web-dev-qa-db-ja.com

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

Logメッセージ(期待どおりのリストのサイズとしてのアイテム数)に基づいて、AttendeeAdapterが適切にインスタンス化されたと思います。

したがって、onBindViewHolder(VH、int)メソッドがListのサイズと同じ回数呼び出されることを期待していますが、そうではありません。メソッドは1回だけ呼び出されます!

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

任意のヘルプまたはコメントをいただければ幸いです。私は今から数時間後に頭痛に別れを告げることを望みます。

26
SHAHM

問題はコードにありません。必ず、RecyclerView子アイテムのlayout_heightwrap_contentに設定してください。

88
Ashish Rawat

RecyclerViewサイクルの onBindViewHolder 動作に注意してください。 RecyclerView.ViewHolder 位置0 itemView

Android:layout_height="match_parent"

現在表示されている画面を占有します。 ScrollとonBindViewHolderをトリガーする必要がありますが、 getItemCount が適切に設定されていることを確認してください。

解決:

Android:layout_height="wrap_content"

膨張したitemViewとしてConstraintLayoutを使用したソリューション:

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

すべてのサポートライブラリに同じバージョンを使用します。

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が何であれ、問題。

1
yennsarah

この問題が最近発生し、サポートライブラリの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'
1

私が出くわしたケースでは、私のリサイクラービューが垂直ではなく水平方向にのみスクロール可能でした。

0

また、RecyclerView自体の高さをAndroid:layout_height="wrap_content" OR Android:layout_height="match_parent"。]に設定しているかどうかも確認してください。どちらの場合も、1つのアイテムの高さを調整し、 1つだけですが、実際にリストをスクロールできますが、代わりに、RecyclerViewの高さを手動で設定します。

0
Lukas Mohs