13

经过许多小时的研究,我终于咨询了官方的帮助。RecyclerView.onBindViewHolder只能调用一次

我有一个完美的RecyclerView.Adapter和RecyclerView.ViewHolders。但由于某些原因,我不明白,RecyclerView.Adapter.onBindViewHolder没有正确调用。

private class AttendeeAdapter extends RecyclerView.Adapter<AttendeeHolder> { 
    /*FIELDS*/ 
    private List<Attendee> mAttendeeList; 

    /*CONSTRUCTORS*/ 
    public AttendeeAdapter(List<Attendee> attendees) { 
     mAttendeeList = attendees; 
     //Log.i(TAG, "AttendeeAdapter size: " + getItemCount()); 
    } 

基于日志信息(如预期的项目数为列表的大小),我承担AttendeeAdapter被正确实例化。

所以我期望onBindViewHolder(VH,int)方法将被调用多次作为列表的大小,但它不是。该方法仅被称为一次! (延伸RecyclerView.ViewHolder)

/*METHODS*/ 
    @Override 
    public AttendeeHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); 
     View itemView = layoutInflater.inflate(R.layout.list_attendee, parent, false); 
     return new AttendeeHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(AttendeeHolder holder, int position) { 
     Attendee attendee = mAttendeeList.get(position); 
     holder.bindAttendee(attendee, position); 

     Log.i(TAG, "Binding ViewHolder #" + position); 
     /* Binding ViewHolder #0 and that's it */ 
    } 

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

我AttendeeHolder去为以下几点:

private class AttendeeHolder extends RecyclerView.ViewHolder { 
    /*FIELDS*/ 
    private EditText mAttendeeNameEditText; 
    private Attendee mAttendee; 

    /*CONSTRUCTOR*/ 
    public AttendeeHolder(View itemView) { 
     super(itemView); 
     mAttendeeNameEditText = (EditText) itemView.findViewById(R.id.edit_text_list_item); 
     mAmountEditTextList = new ArrayList<>(eventMaxCount); 
     } 

    /*METHODS*/ 
    public void bindAttendee(Attendee attendee, final int position) { 
     mAttendee = attendee; 
     String attendeeName = mAttendee.getName(); 

     // Set the name to the EditText if a name has already been set 
     if (attendeeName != null) { 
      mAttendeeNameEditText.setText(attendeeName); 
     } 
    } 
} 

,并在主代码实现

List<Attendee> attendees = AttendeeLab.get().getAttendeeList(); 
    mAttendeeAdapter = new AttendeeAdapter(attendees); 
    mAmountRecyclerView.setAdapter(mAttendeeAdapter); 

我猜的代码将工作(我认为我没有做任何改变),但gradle依赖关系可能没有正确设置。那是我尝试修改recyclerview-v7:23.3.0到recyclerview-v7:23.1.0或其他任何(他们都不工作)的地方。

dependencies { 
compile fileTree(dir: 'libs', include: ['*.jar']) 
testCompile 'junit:junit:4.12' 
compile 'com.android.support:appcompat-v7:23.3.0' 
compile 'com.android.support:design:23.3.0' 
compile 'com.android.support:support-v4:23.3.0' 
compile 'com.android.support:recyclerview-v7:23.1.2' 
} 

任何帮助或评论将不胜感激。我希望自现在起几个小时后,我会说再见。

+0

不知道这意味着什么 - 但你怎么访问你的'AttendeeHolder',因为它有私人accessand它不在你的'AttendeeAdapter'中?另外,在'build.gradle'中使用相同版本的支持包。 – yennsarah

+0

ViewHolder和Adapter是主代码中的内部类,因此可以访问。 – SHAHM

+0

你解决了这个问题!RecyclerView可以使用支持包的相同(旧)版本正常工作,即v7:23.1.2。 对于Gradle的工作原理,我很抱歉,但是它应该以这种方式工作吗?如果我坚持在新的recyclerview-v7:23.3.0库中使用RecyclerView,该怎么办? – SHAHM

回答

1

使用同一版本的所有支持库:

dependencies { 

compile fileTree(dir: 'libs', include: ['*.jar']) 

testCompile 'junit:junit:4.12' 
compile 'com.android.support:appcompat-v7:23.3.0' 
compile 'com.android.support:design:23.3.0' 
compile 'com.android.support:support-v4:23.3.0' 
compile 'com.android.support:recyclerview-v7:23.3.0' //<<< here 
} 

此外,RecyclerView应与'com.android.support:design:23.3.0'包中添加 - 在classor的覆盖任何魔法Gradle在构建过程中做了这个“重复“包可能已经导致你的问题。

+0

不,它不起作用。 onBindViewHolder只被调用一次。实际上,代码的最后一行就像你的建议,但我认为我应该坚持我曾经使用过的库,所以我改变了我发布的内容。清理和重建项目不会改变结果。 – SHAHM

63

该问题不在您的代码中。确保将layout_height设置为RecyclerView子项目的wrap_content

+2

我同意代码正常工作。我检查了子项“layout_height”的属性,发现它们都被设置为'wrap_content'。我很确定问题在于图书馆。 – SHAHM

+0

其实这种类型的问题也出现在我的项目中,它对我很有用。 –

+0

很棒的回答。 +1 – developer1011

2

处理RecyclerView循环中的onBindViewHolder行为。 RecyclerView.ViewHolder position 0 itemView

android:layout_height="match_parent" 

占据当前显示的屏幕。应该触发滚动和onBindViewHolder,但要确保getItemCount已被正确设置。

解决方案:

android:layout_height="wrap_content" 

解决方案与ConstraintLayout为充气ItemView控件:

<?xml version="1.0" encoding="utf-8"?>  
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"><!-- IMPORTANT --> 
    <!-- ... --> 
</android.support.constraint.ConstraintLayout>