2015-09-21 12 views
10

Obecnie rozwijam aplikację, która korzysta z RecyclerView.onCreateViewHolder z RecyclerView.Adapter jest wywoływany dwa razy lub więcej, wiele razy

Podczas przeglądania LogCat zauważyłem, że onCreateViewHolder został wywołany dwa razy po jego utworzeniu.

09-22 05:22:55.209 V/Adapter﹕ Construct 
09-22 05:22:55.213 V/Adapter﹕ onCreateViewHolder 
09-22 05:22:55.224 V/Adapter﹕ onBindViewHolder 
09-22 05:22:55.240 V/Adapter﹕ onCreateViewHolder 
09-22 05:22:55.247 V/Adapter﹕ onBindViewHolder 

także onBindViewHolder nazwano dwukrotnie choć wiem, że to się nazywa, gdy elementy są poddawane recyklingowi.

Ale myślę, że onCreateViewHolder wystarczy, aby zostać wywołanym tylko raz.

Czy to nienormalne zachowanie? Jeśli tak, jak można to naprawić?

Odpowiedz

14

To nie jest nienormalne, ale całkiem normalne zachowanie. Nie musisz się martwić.

To prawda, że ​​obiekt ViewHolder zostanie poddany recyklingowi i nie zostanie ponownie utworzony.

Do wyświetlenia wielu elementów na ekranie aplikacji potrzebne są jednak wielokrotne przeglądarki . Tak więc zostanie utworzona pewna liczba ViewHolders i dla tego onCreateViewHolder jest nazywany określonym czasem.

Funkcja onBindViewHolder będzie wywoływana w nieskończoność, gdy dane zostaną zresetowane do jednego z ViewHolders.

I zbadano ten fakt przy zastosowaniu testu jak poniżej:

główną działalność:

public class MainActivity extends AppCompatActivity { 
    private static final String[] DATASET = new String[]{ 
      "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 
      "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 
    }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     recyclerView.setHasFixedSize(true); 

     LinearLayoutManager layoutManager = new LinearLayoutManager(this); 
     recyclerView.setLayoutManager(layoutManager); 

     MyAdapter myAdapter = new MyAdapter(DATASET); 
     recyclerView.setAdapter(myAdapter); 
    } 
} 

MyAdapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { 
    private static final String LOG_TAG = "RecyclerViewAdapter"; 
    private String[] dataset; 

    private int counterOnCreateViewHolder = 0; 
    private int counterOnBindViewHolder = 0; 

    public MyAdapter(String[] dataset) { 
     Log.d(LOG_TAG, "Construct"); 
     this.dataset = dataset; 
    } 

    public static class ViewHolder extends RecyclerView.ViewHolder { 
     public TextView textView; 
     public ViewHolder(TextView textView) { 
      super(textView); 
      this.textView = textView; 
     } 
    } 

    @Override 
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     Log.d(LOG_TAG, "onCreateViewHolder (" + ++counterOnCreateViewHolder + ")"); 
     View view = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.adapter_textview, parent, false); 

     ViewHolder viewHolder = new ViewHolder((TextView) view); 
     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     Log.d(LOG_TAG, "onBindViewHolder (" + ++counterOnBindViewHolder + ")"); 
     holder.textView.setText(dataset[position]); 
    } 

    @Override 
    public int getItemCount() { 
     // Log.d(LOG_TAG, "getItemCount"); 
     return dataset.length; 
    } 
} 

Układ/activity_main.xml:

<android.support.v7.widget.RecyclerView 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:scrollbars="vertical" 
    android:id="@+id/recycler_view" /> 

l ayout/adapter_textview.xml:

<TextView 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/adapter_textview" 
    android:textSize="30sp" /> 

Wynik:

09-22 06:03:04.166 D/RecyclerViewAdapter﹕ Construct 
09-22 06:03:05.179 D/RecyclerViewAdapter﹕ onCreateViewHolder (1) 
09-22 06:03:05.183 D/RecyclerViewAdapter﹕ onBindViewHolder (1) 
09-22 06:03:05.190 D/RecyclerViewAdapter﹕ onCreateViewHolder (2) 
09-22 06:03:05.192 D/RecyclerViewAdapter﹕ onBindViewHolder (2) 
09-22 06:03:05.192 D/RecyclerViewAdapter﹕ onCreateViewHolder (3) 
09-22 06:03:05.194 D/RecyclerViewAdapter﹕ onBindViewHolder (3) 
09-22 06:03:05.195 D/RecyclerViewAdapter﹕ onCreateViewHolder (4) 
09-22 06:03:05.197 D/RecyclerViewAdapter﹕ onBindViewHolder (4) 
09-22 06:03:05.198 D/RecyclerViewAdapter﹕ onCreateViewHolder (5) 
09-22 06:03:05.199 D/RecyclerViewAdapter﹕ onBindViewHolder (5) 
09-22 06:03:05.200 D/RecyclerViewAdapter﹕ onCreateViewHolder (6) 
09-22 06:03:05.202 D/RecyclerViewAdapter﹕ onBindViewHolder (6) 
09-22 06:03:05.203 D/RecyclerViewAdapter﹕ onCreateViewHolder (7) 
09-22 06:03:05.204 D/RecyclerViewAdapter﹕ onBindViewHolder (7) 
09-22 06:03:05.206 D/RecyclerViewAdapter﹕ onCreateViewHolder (8) 
09-22 06:03:05.207 D/RecyclerViewAdapter﹕ onBindViewHolder (8) 
09-22 06:03:05.209 D/RecyclerViewAdapter﹕ onCreateViewHolder (9) 
09-22 06:03:05.211 D/RecyclerViewAdapter﹕ onBindViewHolder (9) 
09-22 06:03:05.212 D/RecyclerViewAdapter﹕ onCreateViewHolder (10) 
09-22 06:03:05.213 D/RecyclerViewAdapter﹕ onBindViewHolder (10) 
09-22 06:03:05.215 D/RecyclerViewAdapter﹕ onCreateViewHolder (11) 
09-22 06:03:05.217 D/RecyclerViewAdapter﹕ onBindViewHolder (11) 
09-22 06:03:05.218 D/RecyclerViewAdapter﹕ onCreateViewHolder (12) 
09-22 06:03:05.220 D/RecyclerViewAdapter﹕ onBindViewHolder (12) 
09-22 06:03:55.048 D/RecyclerViewAdapter﹕ onCreateViewHolder (13) 
09-22 06:03:55.050 D/RecyclerViewAdapter﹕ onBindViewHolder (13) 
09-22 06:03:55.228 D/RecyclerViewAdapter﹕ onCreateViewHolder (14) 
09-22 06:03:55.229 D/RecyclerViewAdapter﹕ onBindViewHolder (14) 
09-22 06:03:55.230 D/RecyclerViewAdapter﹕ onCreateViewHolder (15) 
09-22 06:03:55.231 D/RecyclerViewAdapter﹕ onBindViewHolder (15) 
09-22 06:03:55.232 D/RecyclerViewAdapter﹕ onBindViewHolder (16) 
09-22 06:03:55.232 D/RecyclerViewAdapter﹕ onBindViewHolder (17) 
09-22 06:03:55.260 D/RecyclerViewAdapter﹕ onBindViewHolder (18) 
09-22 06:03:55.276 D/RecyclerViewAdapter﹕ onBindViewHolder (19) 
09-22 06:03:55.296 D/RecyclerViewAdapter﹕ onBindViewHolder (20) 
09-22 06:03:55.310 D/RecyclerViewAdapter﹕ onBindViewHolder (21) 

Jak widać, tylko onBindViewHolder nazwano po onCreateViewHolder (15).

+1

jest jakiś sposób, aby obsługiwać wiele połączeń z metodą onBindViewHolder bo mam problem z wydajnością w przewijania.. dzięki –

0

Możesz zwiększyć liczbę RecycledViewPool o ten kod. Domyślnie ma on wartość 5.

można zwiększyć zgodnie z potrzebami.

recyclerView.getRecycledViewPool() setMaxRecycledViews (0,50); // 0 - twój typ widoku

Powiązane problemy