RecyclerView.onBindViewHolder只调用一次



经过几个小时的研究,我终于咨询了官方帮助。

我有一个RecyclerView.Adapter和RecyclerView.ViewHolder,它们运行良好。但是由于某些我不明白的原因,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)方法的调用次数与列表的大小一样多,但事实并非如此。该方法只调用一次!

    /*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();
    }
}

My AttendeeHolder(扩展 RecyclerView.ViewHolder)如下所示:

    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'
}

任何帮助或意见将不胜感激。我希望几个小时后我能告别头痛。

问题不在于您的代码。请确保将"layout_height"设置为"回收器视图子项的wrap_content"。

在 RecyclerView 循环中处理 onBindViewHolder 行为。回收器视图.视图持有人位置 0 项目视图

android:layout_height="match_parent"

占用当前显示的屏幕。应触发滚动和 onBindViewHolder,但请确保正确设置了 getItemCount。

溶液:

android:layout_height="wrap_content"

将约束布局作为膨胀项目的解决方案视图:

<?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>

在我遇到的一个案例中,当我的回收器视图只能水平滚动,而不是垂直滚动时。

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

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'包一起添加 - 用这个"重复"包覆盖类或Gradle在构建过程中所做的任何魔术都可能导致你的问题。

对于最近遇到此问题并运行支持库 SDK 28 测试版的用户,请将目标 SDK 更改为 27,并使用 27.1.1 版本的支持库(撰写本文时的最新版本)。

我在 28.0.0-alpha3 库上苦苦挣扎,在我的 app.gradle 中将版本更改为 27.1.1,问题解决了。

implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:support-vector-drawable:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'

还要检查您是否将回收器视图本身的高度设置为 android:layout_height="wrap_content" OR android:layout_height="match_parent" 。在这两种情况下,它都会适应单个项目的高度,并且看起来只是一个,但您实际上可以滚动列表。相反,请手动设置回收器视图的高度。

就我而言,我不得不覆盖getItemId().当我将不同的项目添加到适配器时,它们具有相同的id。滚动时onBindViewHolder停下来打电话。所以,我从

override fun getItemId(position: Int): Long = list[position].id.toLong()

override fun getItemId(position: Int): Long = position.toLong()

适配器还包含以下设置:

override fun getItemCount(): Int = list.size
override fun getItemViewType(position: Int): Int = list[position].viewType
this.setHasStableIds(true)

最好使用具有独特id的集合。

在我的情况下,回收器视图的单个项目布局的根布局(约束布局)高度设置为 match_parent 而不是"wrap_content",将其更改为"wrap_content"并修复了问题

<androidx.constraintlayout.widget.ConstraintLayout 
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="MissingConstraints">
    <TextView
        android:id="@+id/tv_city_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:gravity="center"
        android:text="@{location.name}"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        android:typeface="serif" />
</androidx.cardview.widget.CardView>

检查您在活动/片段中设置适配器的代码,以防出现方向问题。

activityAddBusinessBinding.rvImageList.layoutManager =LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

相关内容

  • 没有找到相关文章

最新更新