【问题标题】:How to get the center item after RecyclerView snapped it to center?RecyclerView 将其捕捉到中心后如何获取中心项目?
【发布时间】:2017-04-09 09:47:08
【问题描述】:

我正在实现一个水平的RecyclerView,它可以在滚动后将项目对齐到中心,例如 Google play App 水平列表。 This 是评论。

我的代码如下:

MainMenuAdapter mainMenuAdapter = new MainMenuAdapter(this, mDataset);

final LinearLayoutManager layoutManagaer = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

RecyclerView mainMenu = (RecyclerView) findViewById(R.id.main_menu);
mainMenu.setLayoutManager(layoutManagaer);
mainMenu.setAdapter(mainMenuAdapter);

final SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(mainMenu);     

RecyclerView 将中心项目(位置)捕捉到中心后,我如何才能获得中心项目(位置)?没有任何监听器实现吗? 此外,当触摸项目视图时,我想将其对齐到中心。我该怎么做?

【问题讨论】:

    标签: android android-recyclerview snapping


    【解决方案1】:

    如果你需要View,你可以调用

     View view =  snapHelper.findSnapView(layoutManagaer);
    

    一旦你有了视图,你应该能够获得该视图在数据集上的位置。例如使用

       mainMenu.getChildAdapterPosition(view)
    

    【讨论】:

    • 一个非常干净的解决方案。谢谢
    【解决方案2】:

    最好使用这种方法:
    https://medium.com/over-engineering/detecting-snap-changes-with-androids-recyclerview-snaphelper-9e9f5e95c424

    原帖:
    即使您不打算使用SnapHelper,您也可以通过RecyclerView.OnScrollListener 获得中心元素位置。

    1. MiddleItemFinder 类复制到您的项目中。
    2. 创建回调对象MiddleItemCallback

      MiddleItemFinder.MiddleItemCallback callback = 
              new MiddleItemFinder.MiddleItemCallback() {
                      @Override
                      public void scrollFinished(int middleElement) {
                          // interaction with middle item
                      }
      };
      
    3. 将新的滚动监听器添加到您的 RecyclerView

      recyclerView.addOnScrollListener(
              new MiddleItemFinder(getContext(), layoutManager, 
                      callback, RecyclerView.SCROLL_STATE_IDLE));
      
    4. 最后一个参数或MiddleItemFinder构造函数是scrollState

      • RecyclerView.SCROLL_STATE_IDLE – RecyclerView 目前没有 滚动。滚动完成。
      • RecyclerView.SCROLL_STATE_DRAGGING – RecyclerView 当前是 被用户触摸输入等外部输入拖动。
      • RecyclerView.SCROLL_STATE_SETTLING – RecyclerView 当前是 在不受外部控制的情况下动画到最终位置。
      • MiddleItemFinder.ALL_STATES – 所有州都在一起。
    5. 例如,如果您选择RecyclerView.SCROLL_STATE_IDLE 作为最后一个构造函数参数,那么在所有滚动结束时回调对象将返回您中间元素的位置。

    MiddleItemFinder 类:

    public class MiddleItemFinder extends RecyclerView.OnScrollListener {
    
        private
        Context context;
    
        private
        LinearLayoutManager layoutManager;
    
        private
        MiddleItemCallback callback;
    
        private
        int controlState;
    
        public
        static final int ALL_STATES = 10;
    
        public MiddleItemFinder(Context context, LinearLayoutManager layoutManager, MiddleItemCallback callback, int controlState) {
        this.context = context;
        this.layoutManager = layoutManager;
        this.callback = callback;
        this.controlState = controlState;
        }
    
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    
            if (controlState == ALL_STATES || newState == controlState) {
    
                int firstVisible = layoutManager.findFirstVisibleItemPosition();
                int lastVisible = layoutManager.findLastVisibleItemPosition();
                int itemsCount = lastVisible - firstVisible + 1;
    
                int screenCenter = context.getResources().getDisplayMetrics().widthPixels / 2;
    
                int minCenterOffset = Integer.MAX_VALUE;
    
                int middleItemIndex = 0;
    
                for (int index = 0; index < itemsCount; index++) {
    
                    View listItem = layoutManager.getChildAt(index);
    
                    if (listItem == null)
                        return;
    
                    int leftOffset = listItem.getLeft();
                    int rightOffset = listItem.getRight();
                    int centerOffset = Math.abs(leftOffset - screenCenter) + Math.abs(rightOffset - screenCenter);
    
                    if (minCenterOffset > centerOffset) {
                        minCenterOffset = centerOffset;
                        middleItemIndex = index + firstVisible;
                    }
                }
    
                callback.scrollFinished(middleItemIndex);
            }
        }
    
        public interface MiddleItemCallback {
    
            void scrollFinished(int middleElement);
        }
    }
    

    【讨论】:

    • 那篇中篇文章非常卫生干净!
    猜你喜欢
    • 2018-07-16
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 2021-05-17
    • 2021-02-26
    • 1970-01-01
    • 2016-01-28
    相关资源
    最近更新 更多