【问题标题】:How to call scrollToPosition(position) inside recyclerView's adapter?如何在 recyclerView 的适配器中调用 scrollToPosition(position)?
【发布时间】:2018-01-22 07:25:51
【问题描述】:

我的onBindViewHolder 中有一个setOnClick 监听器

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
       ((ViewHolder) holder).txtType.setText(object.text);
       ((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) { 
                        Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();                           
                      //???.scrolltoPosition(position+1);
                    }
                });

点击时,我会将视口滚动到下一个回收站视图项。我已经通过recyclerView.scrollToPosition(position); 在我的 MainActivity java 中完成了这项工作。但是在 onBindViewHolder 上的适配器类中,我不知道如何在主 Java 类上调用我的 recyclerView。

我应该怎么做?

编辑: 为简化起见,我修改了之前的代码,因为我为我的回收器使用了多视图适配器。这是多视图适配器:

public class MultiViewTypeAdapter extends RecyclerView.Adapter {

private ArrayList<InstructionModel>dataSet;
Context mContext;
int total_types;
private LinearLayoutManager manager;

public MultiViewTypeAdapter(LinearLayoutManager manager)
{
    this.manager=manager;
}


public static class SimpleTextViewHolder extends RecyclerView.ViewHolder {

    TextView txtType;
    CardView cardView;
    CheckBox checkBox;

    public SimpleTextViewHolder(View itemView) {
        super(itemView);

        this.txtType = (TextView) itemView.findViewById(R.id.type);
        this.cardView = (CardView) itemView.findViewById(R.id.card_view);
        this.checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);

    }
}
public static class TimeTextViewHolder extends RecyclerView.ViewHolder {

    TextView txtType;
    CardView cardView;
    CheckBox checkBox;

    public TimeTextViewHolder(View itemView) {
        super(itemView);

        this.txtType = (TextView) itemView.findViewById(R.id.type);
        this.cardView = (CardView) itemView.findViewById(R.id.card_view);
        this.checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);
    }
}




public MultiViewTypeAdapter(ArrayList<InstructionModel> data, Context context) {
    this.dataSet = data;
    this.mContext = context;
    total_types = dataSet.size();
}

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

    View view;
    switch (viewType) {
        case InstructionModel.SIMPLE_TYPE:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.simple, parent, false);
            return new SimpleTextViewHolder(view);
        case InstructionModel.TIME_TYPE:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.time, parent, false);
            return new TimeTextViewHolder(view);
    }
    return null;
}

@Override
public int getItemViewType(int position) {

    switch (dataSet.get(position).type) {
        case 0:
            return InstructionModel.SIMPLE_TYPE;
        case 1:
            return InstructionModel.TIME_TYPE;
        default:    return -1;
    }
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int listPosition) {

    InstructionModel object = dataSet.get(listPosition);
    if (object != null) {
        switch (object.type) {

            case InstructionModel.SIMPLE_TYPE:

                ((SimpleTextViewHolder) holder).txtType.setText(object.text);
                break;
            case InstructionModel.TIME_TYPE:
                ((TimeTextViewHolder) holder).txtType.setText(object.text);

                break;
        }
    }



}

@Override
public int getItemCount() {
    return dataSet.size();
}

附: 如果你看到一些随机无用的东西,我正在尝试一些东西。

【问题讨论】:

  • 在适配器中传递 layoutmanager 实例并使用它来做同样的事情
  • @ApoorvSingh 对不起,我是新手,你能告诉我该怎么做吗?
  • @NicoDioso 你找到解决办法了吗?
  • @NicoDioso 请看我的回答
  • 我很久以前就已经解决了这个问题,但是感谢这个,可能会帮助其他一些开发者。

标签: java android android-recyclerview


【解决方案1】:

用构造函数传递LayoutManger

 class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
            private LinearLayoutManager manager;

            public Adapter(LinearLayoutManager manager)
            {
                this.manager=manager;
            }


        @Override
        public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
           ((ViewHolder) holder).txtType.setText(object.text);
           ((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) { 
                            Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();                           
                          manager.scrollToPosition(position+1);
                        }
                    });
    }

【讨论】:

  • 我的适配器类是这样构建的:public class Adapter extends RecyclerView.Adapter { public static class SimpleTextViewHolder extends RecyclerView.ViewHolder {...}},我应该在哪里声明私有 LinearLayoutManager 管理器;公共适配器(LinearLayoutManager 管理器){ this.manager=manager; }?
  • 我实际上修改了这里的代码,因为我使用了多视图适配器,我将添加包含我们讨论过的代码的第一部分。
  • 当我尝试了你的代码时,我收到了这个错误 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.LinearLayoutManager.scrollToPosition(int)' on在 manager.scrollToPosition(position+1); 中指向 manager 的空对象引用;
  • 您是否在适配器中传递了LayoutManger,如果是请更新代码
【解决方案2】:

我觉得你应该定义一个接口来通知你的父RecyclerView做滚动操作,把RecyclerView放到ViewHodler里面操作,造成耦合

【讨论】:

    【解决方案3】:

    您可以在Fragment OR Activity实现的构造函数中传递一个监听器对象。

    /**
     * item click interface of adapter
     */
    public interface MultiViewTypeAdapterListener {
        void onScroll(int position)
    }  
    

    该接口由Fragment OR Activity实现

    /**
         * On Scroll Implement Method from adapter listener.
         *
         * @param position
         */
        @Override
        public void onScroll(int position) {
            // Here you can call that method 
            recyclerview.scrolltoPosition(position)
        }
    

    然后你在适配器的构造函数中传递这个监听器。

    private void buildRecyclerView() {
      multiViewTypeAdapter = new MultiViewTypeAdapter(this);
      recyclerView.setAdapter(multiViewTypeAdapter);
    }
    

    在构造函数中,可以这样赋值

     private MultiViewTypeAdapterListener mMultiViewTypeAdapterListener;
     public OfferAdapter(MultiViewTypeAdapterListener mMultiViewTypeAdapterListener) {
            this.mMultiViewTypeAdapterListener = mMultiViewTypeAdapterListener
            }
        }
    

    现在你可以像这样在 anyViwe 上设置点击监听器来使用这个监听器

    ((ViewHolder) holder).checkBox.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) { 
                            Toast.makeText(mContext, ""+position, Toast.LENGTH_SHORT).show();                           
                          //???.scrolltoPosition(position+1);
                            mMultiViewTypeAdapterListener.onScroll(position+1);
                        }
                    });
    

    返回调用实现该方法的onItemClick方法

    【讨论】:

      【解决方案4】:
        private int getScrollRange() {
              int scrollRange = 0;
              if (parent.getChildCount() > 0) {
                  View child = parent.getChildAt(0);
                  scrollRange = Math.max(0,
                          child.getHeight() - (parent.getHeight()));
              }
              return scrollRange;
          }
      
      ScrollView parent=findViewById(R.id.scroll_Recipe_Detail);
      parent.scrollTo(0,getScrollRange());
      

      【讨论】:

        【解决方案5】:

        如果您想滚动添加新项目,您必须覆盖“onItemsAdded”。 这是我的做法:

        recyclerView.apply {
                setHasFixedSize(true)
                layoutManager = MyLinearLayoutManager(this@MainActivity)
                ...
        }
        
        private class MyLinearLayoutManager(private val context: Context) :
            LinearLayoutManager(context) {
        
            // Force new items appear at the top
            override fun onItemsAdded(recyclerView: RecyclerView, positionStart: Int, itemCount: Int) {
                super.onItemsAdded(recyclerView, positionStart, itemCount)
        
                scrollToPosition(findLastVisibleItemPosition())
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多