在这个例子中,notifyItemRangeChanged(0, this.data.size())是什么?它是如何工作的?

6

我了解ViewHolderonBindViewHolder如何工作,但是我不清楚在这个例子中notifyItemRangeChanged(0, this.data.size());是如何工作的,它确切地做了什么。

提供给此适配器的数据以Json格式提供。

适配器如下所示:

 public class AdapterQuestion extends RecyclerView.Adapter<AdapterQuestion.ViewQuestion>{

     private LayoutInflater mLayoutInflater;

     //this is an arrayList of questionData objects
     private ArrayList<QuestionData> data =new ArrayList<>();

     //Created the layoutInflator
     public AdapterQuestion(Context context){
          //get from context
          mLayoutInflater=LayoutInflater.from(context);
     }

     public void setBloglist(ArrayList<QuestionData> data){
         this.data =data;
         notifyItemRangeChanged(0, this.data.size());
     }

     @Override
     public ViewQuestion onCreateViewHolder(ViewGroup parent, int viewType) {
         //inflates the customQuestion view or converts it to java code
         View view= mLayoutInflater.inflate(R.layout.customquestion, null);

        //We now want to convert the View into a ViewQuestion, view Question takes
        //a view so we pass the view into view question and then return it.

        ViewQuestion holder=new ViewQuestion(view);
        return holder;
    }

    //ViewGroup parent and ViewType are not being assigned.
    @Override
    public void onBindViewHolder(ViewQuestion holder, int position) {
         //here we need to bind the data to our view, there is currently no Data!
         //We need to get the data from our JSON
         //Parameters is a ViewHolder and a Position
         //This gives us the current information object from the whole arraylist
         //data.get(position) data is the arraylist and we are getting the current position or index;
         //That current obj is of Type QuestionData

         QuestionData currentObj= data.get(position);

         //we are accessing the Inflated view, or saved view with holder
         //holder.answerText is the textView in holder. We are then taking that current object
         //We are getting the text of the current object and setting it to the AnswerText view
         holder.answerText.setText(currentObj.getMtext());
         holder.answerId.setText(currentObj.getId());
         holder.mVotes.setText(currentObj.getVotes());
         holder.mLikeButton.setTag(currentObj);
     }

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

    public class ViewQuestion extends RecyclerView.ViewHolder{
        //once we create it once the reclycer view will automatically recycle it
        private TextView answerText;
        private TextView answerId;
        private TextView mVotes;
        private LikeButton mLikeButton;

        public ViewQuestion (View itemView){
            super(itemView);
            //here we are finding the views by their ID
            answerText=(TextView)itemView.findViewById(R.id.answerText);
            answerId=(TextView)itemView.findViewById(R.id.answerId);
            mVotes=(TextView)itemView.findViewById(R.id.VoteTextView);
            mLikeButton=    (LikeButton)itemView.findViewById(R.id.heart_buttons);

            mLikeButton.setOnLikeListener(new OnLikeListener() {

                @Override
                public void liked(LikeButton likeButton) {
                    Voting vote = new Voting();
                    vote.onUpVote(convertToString(), 
                            getAdapterPosition(),ViewQuestion.this);
                    System.out.print("Adapter Position"+getAdapterPosition());
                }

                @Override
                public void unLiked(LikeButton likeButton) {
                     Voting onDown=new Voting();
                     onDown.onDownVote(convertToString(), 
                             getAdapterPosition(), ViewQuestion.this);

                }
            });
        }

        public String getVoteView(){
            String voteView=mVotes.getText().toString();
            return voteView;
        }

        public String convertToString(){
            String converted=answerId.getText().toString();
            return converted;
        }

        public int convertToInt(){
            String converted=answerId.getText().toString();
            int ConvertedInt=Integer.parseInt(converted);
            return ConvertedInt;
        }
    }
}

notifyItemRangeChanged 是您的适配器中的自定义方法,您需要在设置适配器的 Mainclass 中调用它。 - Kathi
你查看过文档了吗?:http://developer.android.com/intl/zh-cn/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemRangeChanged(int, int) - Yazan
格式化的代码和描述,希望能够更好地阅读(保留所有代码不变,但是OP可能需要考虑将其减少到仅包含所需部分,而不是整个代码转储)。 - Ori Lentz
如果这个回答对您有帮助,请接受并确认,这样其他人也会更容易找到答案。 - erluxman
3个回答

9

当要设置在RecyclerView中的数据发生变化时,Adapter需要收到数据更改通知,以便它可以更改RecyclerView中的数据。

方法

notifyItemRangedChanged(fromIndex,toIndex);

此方法用于通知适配器某些数据在整个数据集中发生了更改,并告诉适配器应刷新数据并重新加载它们到recyclerView,从传递给该方法的fromIndex到toIndex开始。

如果您有多个数据更改但不是全部,那么使用此方法,这些更改的数据也位于聚类中,因此您可以说从第5到第10个索引数据已更改。

如果所有数据都发生了更改,请调用:

notifyDataSetChanged();

如果只有一个数据项被更改,则调用:

notifyItemChanged(dataPosition);

1
这里似乎有些不对劲。 notifyItemRangedChanged 的第二个参数是 itemCount,而不是 toIndex。函数 notifyItemRangeChanged(int positionStart, int itemCount) 会通知任何已注册的观察者,从位置 positionStart 开始的 itemCount 个项目已更改。 - user2818066
请点击此处查看工作示例:https://dev59.com/mVwX5IYBdhLWcg3w-DbJ#38796098 - DragonFire
notifyDataSetChangednotifyItemRangeChanged(0, this.data.size()) 是完全相同的吗? - android developer

1
使用notifyItemRangeChanged(0, this.data.size())是不好的做法。最好的方法是使用notifyItemChanged或带有payload的notifyItemRangeChanged。
Payload - 可选参数(键)。这给了你检查需要哪种更新的机会。
public void onBindViewHolder(/*...*/, List payloads) {
    if (payloads.isEmpty()) {
        setText(holder, position);
        downloadBitmap(holder, position);
    } else if (payloads.contains(SET_ONLY_TEXT)){
        setText(holder, position);
    }
}

在这个例子中,负载用于检查适配器何时应仅更新文本。

0

在你的情况下,你没有正确地执行(notifyItemRangeChanged),因为你可以直接调用notifyDataSetChanged();,因为你告诉适配器整个列表已经改变而不是特定位置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接