Animation of nested fragment within ViewPager frag

2019-08-19 05:33发布

问题:

I have a ViewPager fragment

class PagerFragment() : Fragment() {
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)

      val pagerView = view as ViewPager
      val adapter = PagerAdapter(childFragmentManager, items)
      pagerView.adapter = adapter
  }
}

with the following adapter

class PagerAdapter(val fm: FragmentManager, val items: ArrayList<Item>)
    : FragmentStatePagerAdapter(fm) {

    override fun getItem(position: Int): Fragment {
        val item = items[position]
        return NestedFragment.newInstance(item)
    }

    override fun getCount(): Int {
        return  items.size
    }
}

which nests fragments with a few animations triggered onViewCreated the following way:

class NestedFragment() : Fragment() {
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)

      val one = AnimationUtils.loadAnimation(context, R.anim.one)
      val two = AnimationUtils.loadAnimation(context, R.anim.two)
      val three = AnimationUtils.loadAnimation(context, R.anim.three)

      view.findViewById<ImageView>(R.id.pic).startAnimation(one)
      view.findViewById<ConstraintLayout>(R.id.content).startAnimation(two)
      view.findViewById<ImageView>(R.id.img).startAnimation(three)
  }
}

However often by the time the nested fragment is showed on the screen the animation has already started or even ended :(

Is there a way to determine when the fragment is indeed rendered on the screen of the device? Of course any other useful suggestions to overcome the issue are welcome as well.

回答1:

Here's what worked for me.

class NestedFragment() : Fragment() {
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)

      val one = AnimationUtils.loadAnimation(context, R.anim.one)
      val two = AnimationUtils.loadAnimation(context, R.anim.two)
      val three = AnimationUtils.loadAnimation(context, R.anim.three)
      view.post(Runnable {
        /* 
          If the animation doesn't trigger you may try to hide 
          elements visibility and reveal them before animation starts
        */
        view.findViewById<ImageView>(R.id.pic).startAnimation(one)
        view.findViewById<ConstraintLayout>(R.id.content).startAnimation(two)
        view.findViewById<ImageView>(R.id.img).startAnimation(three)
      })
  }
}

If the animation still doesn't trigger you may try to hide views visibility and reveal them right before the animation.