无限/循环Recyclerview,smothScrollToPosition指向错误的索引

时间:2018-08-29 09:42:06

标签: android android-recyclerview

我正在尝试实现无限/循环的recyclerview, 这是Adapter类的实现。

    public class MyAdapter extends
        RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final String TAG = MyAdapter.class.getSimpleName();

    private static final int VIEW_TYPE_NORMAL = 1;

    private static final int VIEW_TYPE_GAP = 2;

    private Context mContext;

    private final List<ChannelInfo> mChannelInfoList;

    private LinearTunerClickListener mClickListener;

    public MyAdapter(
            Context context, List<ChannelInfo> channelInfoList, LinearTunerClickListener mClickListener) {
        mChannelInfoList = channelInfoList;
        mContext = context;
        this.mClickListener = mClickListener;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        //Variable to store inflated view based on VIEW TYPE.
        View inflatedView;

        BaseHolder baseHolder;

        if (viewType == VIEW_TYPE_NORMAL) {
            inflatedView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_some_holder1, parent, false);
            baseHolder = new SomeHolder1(inflatedView);
        } else {
            inflatedView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_some_holder2, parent, false);
            baseHolder = new SomeHolder2(inflatedView);
        }

        return baseHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder myViewHolder, int position) {

        if (mContext != null) {

            if (mChannelInfoList != null) {

                mPos = position % mChannelInfoList.size();

               // do stuff
            }

        }

    }

    @Override
    public int getItemViewType(int position) {
        bPos = position % mChannelInfoList.size();
        int viewType;
        if (bPos != mChannelInfoList.size() - 1) {
            viewType = VIEW_TYPE_NORMAL;
        } else {
            // If current position is last item, then return view type as GAP
            viewType = VIEW_TYPE_GAP;
        }
        return viewType;
    }

    @Override
    public int getItemCount() {
        return Integer.MAX_VALUE;
    }

}

这是保存适配器并获取索引的位置(从包中滚动所需的位置)

 public class MainActivity extends AppCompatActivity implements SomeListener {
        private static final String TAG = "MainActivity" + " : ";
        @BindView(R.id.activity_main2_rv)
        RecyclerView mRecyclerView;

    private MyAdapter mAdapter;
    private List<ChannelInfo> mChannelInfoList = new ArrayList<>();

    private SnapHelper mSnapHelper;
    private CenterLayoutManager mLayoutManager;
    private Integer mIndex;
    private String mChannelNo;

    private int mFocusPos = -1;
    private View mFocusedView;
    private int pos = -1;
    private int BIG = Integer.MAX_VALUE;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.linear);
        ButterKnife.bind(this);
        Log.e(TAG, "onCreate(): ");

        bundleOperation();
        setUpRecycler();
        setUpSnapHelper();
        setAdapter();


        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mLayoutManager != null) {


                    mLayoutManager.scrollToPosition(Integer.MAX_VALUE/2);
                    mRecyclerView.smoothScrollToPosition(Integer.MAX_VALUE/2 + (mIndex-3));


                }
            }
        }, 300);

    }


    private void bundleOperation() {
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            Log.d(TAG, "get Bundle: ");
            mIndex = bundle.getInt("index");
            mChannelNo = bundle.getString("ch_no");
            Log.v(TAG, " we have,  " + " index : " + mIndex + " and " + " ch_no : " + mChannelNo);
            mChannelInfoList = bundle.getParcelableArrayList("list");

        }

    }

    private void setUpRecycler() {
        mLayoutManager = new CenterLayoutManager(
                this,
                CenterLayoutManager.HORIZONTAL,
                false
        );
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    }

    private void setUpSnapHelper() {
        mSnapHelper = new LinearSnapHelper();
        mSnapHelper.attachToRecyclerView(mRecyclerView);
    }

    private void setAdapter() {
        mAdapter = new MyAdapter(this, mChannelInfoList, this);
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.notifyDataSetChanged();
    }

}

仅供参考,我使用了一个自定义布局管理器来实现轮播效果,所以现在让我说,列表大小现在总共有12个项目

  mLayoutManager.scrollToPosition(Integer.MAX_VALUE/2);
                mRecyclerView.smoothScrollToPosition(Integer.MAX_VALUE/2 + (mIndex-3));

逻辑工作正常。------------------------

现在,如果我修改列表,比如说添加更多项或删除它们,那么逻辑就此失败了。

它完全错过了索引。

您能提示我要去哪里调试或类似的东西,迷迷了许多小时。 如果您需要Center Layout Manager类,

    public class CenterLayoutManager extends LinearLayoutManager {

    private static final float BALANCING_FACTOR = 0.78f;

    private static final float fastScrollSpeedFactor = 50f;

    public CenterLayoutManager(Context context) {
        super(context);
    }

    public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public CenterLayoutManager(Context context,
                               AttributeSet attrs,
                               int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                       int position) {


        RecyclerView.SmoothScroller smoothScroller =
                new CenterSmoothScroller(recyclerView.getContext()) {


                    @Override
                    protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                        return fastScrollSpeedFactor / displayMetrics.densityDpi;
                    }

                };

        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);

    }

    @Override
    public PointF computeScrollVectorForPosition(int targetPosition) {
        return super.computeScrollVectorForPosition(targetPosition);
    }

    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
                                    RecyclerView.State state) {
        int scrolled = super.scrollHorizontallyBy(dx, recycler, state);

       // some logic to show center item, ZOOMED in
        return scrolled;
    }


    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);
      //  scrollHorizontallyBy(0, recycler, state);
    }

    private static class CenterSmoothScroller extends LinearSmoothScroller {

        CenterSmoothScroller(Context context) {
            super(context);
        }


        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart,
                                    int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }
    }

}

请问我是否需要更广泛的情况来了解情况 如果没有涵盖上述情况,请尝试避免直接放置链接引用。 谢谢

0 个答案:

没有答案