MagicIndicator 在OPPO 手机上的兼容滑动问题

今天出现了一个 OPPO R11 的兼容性问题 ,说实话 R11 已经不是第一次出问题了 。

真想对 R11 说 ,是我们 Android 高攀不上你。

PS:阿弥陀佛,我那刚刚放下屠刀的双手,竟然在微微颤抖。

MagicIndicator 单独使用

前几天刚写的 MagicIndicator 单独使用的文章 ,没想到今天在 OPPO 上出现了坑。

问题 

MagicIndicator 项目的 Issues 中有类似问题 但是无答案 。
 

OPPO 手机滑动BUG

在 onLayout 里面触发 onPageSelected 导致的BUG

OPPO 手机第一次无法正常滑动

等等 。。。

解决方案

使用的 CommonPagerTitleView 来实现选中字体变大的效果 。

项目代码

    private void initMagicIndicator() {
        CommonNavigatorNew commonNavigator = new CommonNavigatorNew(mActivity);
        commonNavigator.setSkimOver(true);

        commonNavigator.setAdapter(new CommonNavigatorAdapter() {
            @Override
            public int getCount() {
                return turnDataBeans.size();
            }

            @Override
            public IPagerTitleView getTitleView(Context context, int index) {
                CommonPagerTitleView commonPagerTitleView = new CommonPagerTitleView(context);
                // load custom layout
                View customLayout = LayoutInflater.from(context).inflate(R.layout.adapter_live_rounds, null);
                final TextView tv_rounds = customLayout.findViewById(R.id.tv_rounds);
                final TextView tv_time = customLayout.findViewById(R.id.tv_time);
                tv_rounds.setText(turnDataBeans.get(index).getName());
                String roundsTime = DateTimeUtil.getRoundsTime(Long.valueOf(turnDataBeans.get(index).getBeginTime()), Long.valueOf(turnDataBeans.get(index).getEndTime()));
                tv_time.setText(roundsTime);
                commonPagerTitleView.setContentView(customLayout);

                commonPagerTitleView.setOnPagerTitleChangeListener(new CommonPagerTitleView.OnPagerTitleChangeListener() {
                    @Override
                    public void onSelected(int index, int totalCount) {// 选中
                        tv_rounds.setTextSize(16);
                        tv_rounds.setTextColor(mContext.getResources().getColor(R.color.color_0DD280));
                        tv_rounds.setTypeface(Typeface.DEFAULT_BOLD);

                        tv_time.setTextSize(13);
                        tv_time.setTextColor(mContext.getResources().getColor(R.color.color_0DD280));
                    }

                    @Override
                    public void onDeselected(int index, int totalCount) {// 未选中
                        tv_rounds.setTextSize(14);
                        tv_rounds.setTextColor(mContext.getResources().getColor(R.color.color_898D89));
                        tv_rounds.setTypeface(Typeface.DEFAULT);

                        tv_time.setTextSize(11);
                        tv_time.setTextColor(mContext.getResources().getColor(R.color.color_898D89));
                    }

                    @Override
                    public void onLeave(int index, int totalCount, float leavePercent, boolean leftToRight) {

                    }

                    @Override
                    public void onEnter(int index, int totalCount, float enterPercent, boolean leftToRight) {

                    }
                });

                commonPagerTitleView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        isFirstTurnSelect = true;
                        magic_indicator.onPageSelected(index);
                        magic_indicator.onPageScrolled(index, 0.0F, 0);
                        if (turnDataBeans.size() > 0) {
                            ApiGetLest(turnDataBeans.get(index).getId());
                            turnId = turnDataBeans.get(index).getId();
                        }
                    }
                });

                return commonPagerTitleView;
            }

            @Override
            public IPagerIndicator getIndicator(Context context) {
                LinePagerIndicator indicator = new LinePagerIndicator(context);
                indicator.setRoundRadius(CommonUtil.dp2px(mActivity, 10));
                indicator.setMode(LinePagerIndicator.MODE_EXACTLY);
                indicator.setTop(CommonUtil.dp2px(mActivity, 8));
                indicator.setLineWidth(CommonUtil.dp2px(context, 30));
                indicator.setColors(Color.parseColor("#0DD280"));
                return indicator;
            }
        });

        magic_indicator.setNavigator(commonNavigator);

    }

 PS :细心的小伙伴会可能会发现 CommonNavigatorNew 这个类 ,哈哈哈 。官方命名为 CommonNavigator (通用的ViewPager指示器,包含PagerTitle和PagerIndicator )。

没错 ,就是这个通用指示器出问题了 。

直接上解决方案 

public class CommonNavigatorNew extends FrameLayout implements IPagerNavigator, NavigatorHelper.OnNavigatorScrollListener {
    private HorizontalScrollView mScrollView;
    private LinearLayout mTitleContainer;
    private LinearLayout mIndicatorContainer;
    private IPagerIndicator mIndicator;

    private CommonNavigatorAdapter mAdapter;
    private NavigatorHelper mNavigatorHelper;

    /**
     * 提供给外部的参数配置
     */
    /****************************************************/
    private boolean mAdjustMode;   // 自适应模式,适用于数目固定的、少量的title
    private boolean mEnablePivotScroll; // 启动中心点滚动
    private float mScrollPivotX = 0.5f; // 滚动中心点 0.0f - 1.0f
    private boolean mSmoothScroll = true;   // 是否平滑滚动,适用于 !mAdjustMode && !mFollowTouch
    private boolean mFollowTouch = true;    // 是否手指跟随滚动
    private int mRightPadding;
    private int mLeftPadding;
    private boolean mIndicatorOnTop;    // 指示器是否在title上层,默认为下层
    private boolean mSkimOver;  // 跨多页切换时,中间页是否显示 "掠过" 效果
    private boolean mReselectWhenLayout = true; // PositionData准备好时,是否重新选中当前页,为true可保证在极端情况下指示器状态正确
    /****************************************************/

    // 保存每个title的位置信息,为扩展indicator提供保障
    private List<PositionData> mPositionDataList = new ArrayList<PositionData>();


  //省略代码 。。。

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (mAdapter != null) {
            preparePositionData();
            if (mIndicator != null) {
                mIndicator.onPositionDataProvide(mPositionDataList);
            }
            if (mReselectWhenLayout && mNavigatorHelper.getScrollState() == ScrollState.SCROLL_STATE_IDLE) {
                onPageSelected(mNavigatorHelper.getCurrentIndex());
                onPageScrolled(mNavigatorHelper.getCurrentIndex(), 0.0f, 0);
            }
        }
        super.onLayout(changed, left, top, right, bottom);

    }

    /**
     * 获取title的位置信息,为打造不同的指示器、各种效果提供可能
     */
    private void preparePositionData() {
        mPositionDataList.clear();
        for (int i = 0, j = mNavigatorHelper.getTotalCount(); i < j; i++) {
            PositionData data = new PositionData();
            View v = mTitleContainer.getChildAt(i);
            if (v != null) {
                data.mLeft = v.getLeft();
                data.mTop = v.getTop();
                data.mRight = v.getRight();
                data.mBottom = v.getBottom();
                if (v instanceof IMeasurablePagerTitleView) {
                    IMeasurablePagerTitleView view = (IMeasurablePagerTitleView) v;
                    data.mContentLeft = view.getContentLeft();
                    data.mContentTop = view.getContentTop();
                    data.mContentRight = view.getContentRight();
                    data.mContentBottom = view.getContentBottom();
                } else {
                    data.mContentLeft = data.mLeft;
                    data.mContentTop = data.mTop;
                    data.mContentRight = data.mRight;
                    data.mContentBottom = data.mBottom;
                }
            }
            mPositionDataList.add(data);
        }
    }

   
//省略代码 。。。
}

PS :篇幅原因 ,省略大部分代码 。

建议替换官方库的 CommonNavigator onLayout  类 ,新建 CommonNavigatorNew 类里面对 onLayout 方法做修改 。

修改一行代码 " super.onLayout(changed, left, top, right, bottom) " 位置挪到最后。解决 。。。。

过程很坎坷

本来上午是出现了 Realm 数据库升级的问题 ,下午又出现了 OPPO 使用 MagicIndicator 滑动问题 。 讲真的 这一天过的特充实 。

在解决这个问题的时候 ,我是在 onSelected 和 onDeselected 里面写了 Log 打印 。结果就是 Logcat 里面一直打印就挺不下来 。

PS :手机的上看到的效果就是你滑动到其他 Tab 之后又会回到选中的 Tab 。代码上的逻辑就是一直在走刷新的代码 。

PS1:我 Clone 了一下大佬的代码运行 ,按照自己的逻辑结果运行结果没问题 。(很玄幻)

PS2:在网上查找的时候有遇到的 ,但是没有解决方案 。有些给我的情况几乎是一模一样 。

PS3:接下来就开始想着去看看源码 。(这一步不到最后关头 我很少会去做这个操作 )

。。。

我在查为啥 super.onLayout() ,的位置会影响 View 的刷新 。

PS :有一个小瑕疵 ,第一次进入的时候 下方选中没有横条 。

发布了57 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37492806/article/details/103736312