13

Sau nhiều giờ nghiên cứu, tôi cuối cùng đã tư vấn trợ giúp chính thức.RecyclerView.onBindViewHolder được gọi chỉ một lần

Tôi có RecyclerView.Adapter và RecyclerView.ViewHolders hoạt động hoàn hảo. Nhưng vì một số lý do tôi không hiểu, RecyclerView.Adapter.onBindViewHolder không được gọi đúng cách.

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

Dựa trên thông điệp tường trình (mục được tính là kích thước của danh sách như mong đợi), tôi cho rằng AttendeeAdapter đã được tạo đúng cách.

Vì vậy, tôi mong đợi phương thức onBindViewHolder (VH, int) sẽ được gọi nhiều lần như kích thước của Danh sách nhưng nó không phải là. Phương thức này chỉ được gọi là ONCE!

/*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 của tôi (mở rộng RecyclerView.ViewHolder) diễn ra như sau:

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

và triển khai trong mã chính như

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

Tôi đoán mã sẽ làm việc (tôi nghĩ Tôi đã không thực hiện bất kỳ thay đổi nào) nhưng phụ thuộc gradle có thể không được đặt đúng. Đó là nơi tôi đã cố gắng sửa đổi recyclerview-v7: 23.3.0 để recyclerview-v7: 23.1.0 hoặc bất cứ điều gì (Không ai trong số họ làm việc).

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

Mọi trợ giúp hoặc nhận xét sẽ được đánh giá cao. Tôi ước tôi sẽ nói lời tạm biệt với cơn đau đầu sau vài giờ kể từ bây giờ.

+0

Không chắc chắn nếu nó có nghĩa là bất cứ điều gì - nhưng làm thế nào để bạn truy cập vào 'của bạn AttendeeHolder', vì nó có tin accessand nó không nằm trong 'AttendeeAdapter' .. của bạn? Ngoài ra, sử dụng cùng một phiên bản cho các gói hỗ trợ trong 'build.gradle' của bạn. – yennsarah

+0

ViewHolder và Adapter là các lớp bên trong trong mã chính do đó có thể truy cập được. – SHAHM

+0

Bạn đã giải quyết được sự cố!RecyclerViews đang hoạt động đúng cách sử dụng cùng một phiên bản (cũ) cho các gói hỗ trợ, tức là v7: 23.1.2. Tôi xin lỗi vì tôi có hiểu biết kém về cách Gradle hoạt động, nhưng liệu nó có hoạt động theo cách đó không? Điều gì xảy ra nếu tôi khăng khăng sử dụng RecyclerViews với thư viện recyclerview-v7: 23.3.0 mới? – SHAHM

Trả lời

1

Sử dụng các phiên bản tương tự cho tất cả các thư viện hỗ trợ của bạn:

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 
} 

Ngoài ra, RecyclerView nên được bổ sung với 'com.android.support:design:23.3.0' gói - ghi đè lên các classor bất cứ điều gì kỳ diệu Gradle đã thực hiện trong quá trình xây dựng với điều này " trùng lặp "gói có thể đã gây ra sự cố của bạn.

+0

Không, nó không hoạt động. onBindViewHolder chỉ được gọi một lần. Trên thực tế, dòng cuối cùng của mã đã giống như những gì bạn đề xuất nhưng tôi nghĩ rằng tôi nên dính vào thư viện mà tôi sử dụng để sử dụng vì vậy tôi đã thay đổi khi tôi đăng. Làm sạch và xây dựng lại dự án không thay đổi kết quả. – SHAHM

63

Sự cố không có trong mã của bạn. Đảm bảo bạn đặt layout_height thành wrap_content mục con RecyclerView.

+2

Tôi đồng ý rằng mã hoạt động đúng. Tôi đã kiểm tra các thuộc tính 'layout_height' của các mục con và thấy rằng chúng được đặt thành' wrap_content'. Tôi khá chắc chắn vấn đề là về các thư viện. – SHAHM

+0

Trên thực tế loại vấn đề này cũng đã xảy ra trong dự án của tôi và nó hoạt động cho tôi. –

+0

Câu trả lời hay. +1 – developer1011

2

Chăm sóc hành vi onBindViewHolder trong chu kỳ RecyclerView. RecyclerView.ViewHolder vị trí 0 mụcView

android:layout_height="match_parent" 

chiếm màn hình hiện tại. Cuộn và onBindViewHolder sẽ được kích hoạt nhưng đảm bảo rằng getItemCount được đặt phù hợp.

Giải pháp:

android:layout_height="wrap_content" 

Giải pháp với ConstraintLayout như itemView thổi phồng:

<?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> 
Các vấn đề liên quan