How to realize rotation on Android side of live broadcasting system

Posted by davejj on Sun, 26 Dec 2021 17:11:09 +0100

Achieve goals

We can find that in the live broadcast system, the rotation chart is a very important part of the system page. Today, let's take a look at how the rotation effect of the live broadcast system is realized.

  • You can manually scroll left and right
  • Can rotate automatically
  • Strong customization

Realization idea

The first thought is to use ViewPager. ViewPager itself is very good at handling page left and right scrolling. On the basis of ViewPager, a Handler is added so that it can scroll automatically.

Problems encountered
The pictures of the live broadcast system cannot be scrolled in a circular way. You cannot scroll back to the last one of the viewpagers, nor can you scroll forward to the first one.
Solution ideas
Display the item of count-1 on the 0 position, and the item of 0 on the count, that is, add 2 to the Adapter getCount() method of ViewPager, and the implementation process will become viewPager.setCurrentItem(count-1) immediately after sliding to 0. Similarly, sliding to count will make ViewPager Setcurrentitem (0) is seamlessly connected to the rotation.

Manual sliding jam on nexus 6p
The above ideas have a good experience on most mobile phones, but there will be catons on some mobile phones. The reason for catons is in ViewPager Setcurrentitem(), so can we avoid it? Obviously, using ViewPager can't avoid this situation. Now let's think about it. We only added two additional items, but now I add 100. The probability of users sliding to the critical point is greatly reduced. We use this method.

Partial implementation code:

1. First, take a look at autoloopswitchbaseview The ViewPager is laid out in Java. In this View, we define a Handler to send circular messages.

Three message types are defined in LoopHandler

 //Requests that the displayed View be updated.
    private static final int MSG_UPDATE = 1;
    //Request to pause the rotation.
    public static final int MSG_STOP = 2;
    //Request to resume rotation.
    public static final int MSG_REGAIN = 3;

Handle these three messages in public void handleMessage(Message msg)

@Override
 public void handleMessage(Message msg) {
    super.handleMessage(msg);
  if (mView == null || mView.mHandler == null || mView.mPagerAdapter == null || mView.mIsDragging) {
    return;
  }

  Log.e("ryze", "stop: " + mIsStop);

  switch (msg.what) {
    case MSG_UPDATE:
      if (mIsStop || hasMessages(MSG_UPDATE)) {
        return;
      }
      if (mView.mPagerAdapter.getCount() > 1) {
        mView.mCurrentItem++;
        mView.mCurrentItem %= mView.mPagerAdapter.getCount();
        mView.mViewPager.setCurrentItem(mView.mCurrentItem, true);
        sendEmptyMessageDelayed(MSG_UPDATE, mView.getDurtion());
      }
      break;
    case MSG_STOP:
      if (hasMessages(MSG_UPDATE)) {
        removeMessages(MSG_UPDATE);
      }
      mIsStop = true;
      Log.e("ryze", "stop: MSG_STOP " + mIsStop);
      break;
    case MSG_REGAIN:
      if (hasMessages(MSG_UPDATE)) {
        removeMessages(MSG_UPDATE);
      }
      sendEmptyMessageDelayed(MSG_UPDATE, mView.getDurtion());
      mIsStop = false;
      Log.e("ryze", "stop: MSG_REGAIN " + mIsStop);
      break;
  } 

2. Let's take a look at the implementation of the Adapter. As mentioned earlier, the general implementation method will add one before and after, and then increase the number of multiples of the current 100. Then the number of getCount() will be the actual number * 100 + 2

"`
public static final int VIEWPAGER_RADIX = 100;

@Override

public final int getCount() {
if (getDataCount() > 1) {
//If the number of rotations is greater than 1, you need to rotate, increase the base, and add one at the beginning and end,
return getDataCount() * VIEWPAGER_RADIX + 2;
} else {
return getDataCount();
}
}
"`

3. There are data and automatic scrolling messages, and the added data before and after has also increased. So how to realize the connection of circular playback in the live broadcast system?

Listen to the OnPageChangeListener of ViewPager in public void onPageScrollStateChanged(int i)

 @Override
 public void onPageScrollStateChanged(int i) {

if (i == ViewPager.SCROLL_STATE_DRAGGING) {
  mIsDragging = true;
} else if (i == ViewPager.SCROLL_STATE_IDLE) {
  if (mViewPager.getCurrentItem() == 0) {
    isLoopSwitch = true;
    mViewPager.setCurrentItem(mPagerAdapter.getCount() - 2, false);
  } else if (mViewPager.getCurrentItem() == mPagerAdapter.getCount() - 1) {
    isLoopSwitch = true;
    mViewPager.setCurrentItem(1, false);
  }
  mCurrentItem = mViewPager.getCurrentItem();

  if (mIsDragging && mHandler != null) {
    //If from the dragging state to not mIsDragging
    mHandler.sendEmptyMessageDelayed(LoopHandler.MSG_UPDATE, getDurtion());
  }

  mIsDragging = false;

  Log.e("ryze", "onPageScrollStateChanged  " + i);
 }
}

The above is the whole content of how to realize the rotation effect of the live broadcasting system. Interested friends can try it.

Topics: Android