3

我有一個水平recyclerview(與一個LinearLayoutManager),它的子項目有一個imageview包裹在一個相關佈局中。 recyclerview有三個包含子項的水平行。當滾動回滾視圖時,我使用來自http調用的響應更新數據集,並在http響應回調中調用notifydatasetChanged。如果recyclerview子項的高度和寬度是固定值(例如150dp,84dp),recyclerview的行爲就像預期的那樣,即加載新項目並停留在同一個滾動位置,但如果我將recyclerview的子項的高度和寬度設置爲match_parent,並且wrap_content,recyclerview完全刷新並滾動到第一個位置。這是爲什麼發生? 注意:我已經檢查過其他類似的問題,但都沒有提供可行的解決方案。Recyclerview在調用notifydatasetchanged後滾動到頂部

main_layout

<android.support.v7.widget.RecyclerView 
    android:id="@+id/grid_recycler_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_marginBottom="110dp" 
    android:layout_marginLeft="15dp" 
    android:layout_marginTop="80dp" 
    android:background="@color/transparent" 
    android:outlineProvider="bounds" 
    android:elevation="8dp" 
    android:padding="0dp" 
    android:scrollbars="none" /> 
.... 

recycler_view_child_item

<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" 
android:padding="0dp"> 
<ImageView 
    android:id="@+id/thumbnail" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:adjustViewBounds="true" 
    android:maxWidth="126dp" 
    android:maxHeight="225dp" 
    android:padding="0dp"/> 
</RelativeLayout> 

回答

0

的刷新可能是因爲你沒有指定的子視圖大小。我要做的第一件事就是刪除RelativeLayout,它減少了視圖深度,因爲它似乎沒有任何目的。此外,如果recyclerView的子視圖始終具有相同大小,則將其設置在childViews本身而不是parentView(也稱爲recyclerView)上。您是否也在recyclerView上將HasFixedSize設置爲true?

+0

刪除相對佈局。由於我將recyclerview的尺寸設置爲與父母的尺寸相匹配,因此回收站視圖的尺寸可能因設備而異。所以我無法爲子視圖設置固定大小。回收站視圖有三行,因此我設置了childview的高度以匹配父級和寬度以包裝內容,以避免回收站視圖中子視圖之間出現空間。 – Neanderthal

+0

此外,我已將setHasFixedSize設置爲true。 – Neanderthal

-1

您可以滾動RecyclerView到特定位置,當你叫notifyDataSetChanged

recyclerView.scrollToPosition(array.size() - 1); 
5

我有同樣的問題,但沒有找到一個解決方案,因此無論是。該問題是由於RecyclerView未設置LayoutManager而導致的。我知道你說你有一個LinearLayoutManager。但請確保您按照以下方式進行設置。 (在我的情況下,我使用HorizontalGridView,但同樣的原則適用於RecyclerView)。

horizontalGridView = (HorizontalGridView) findViewById(R.id.gridView); 
GridElementAdapter adapter = newGridElementAdapter(VenueProfileActivity.this, mDeals); 
horizontalGridView.setAdapter(adapter); 

HorizontalGridView.LayoutManager layoutManager = new LinearLayoutManager(VenueProfileActivity.this, LinearLayoutManager.HORIZONTAL, false); 
horizontalGridView.setLayoutManager(layoutManager); 
horizontalGridView.setHasFixedSize(true); 
0

我有同樣的問題,發現從mossy321有用的答案有用,但沒有解決我的一切。在我的應用程序中,我有一個對象列表,每個對象都有一段時間,需要每隔30秒左右遞增一次。我在宿主片段中運行了一個計時器,但更新數據導致跳躍問題。

我回收的代碼如下:

orderRecycler = (RecyclerView) rootView.findViewById(R.id.order_recycler_view); 
    // use this setting to improve performance if you know that changes 
    // in content do not change the layout size of the RecyclerView 
    orderRecycler.setHasFixedSize(true); 

    //Stops items doing a default flashing animation on individual refresh 
    RecyclerView.ItemAnimator animator = orderRecycler.getItemAnimator(); 
    if (animator instanceof SimpleItemAnimator) { 
     ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); 
    } 

    orderLayoutManager = new LinearLayoutManager(getActivity()); 
    orderRecycler.setLayoutManager(orderLayoutManager); 
    orderAdapter = new OrderAdapter(orderArrayList, historyArrayList, getActivity()); 

    orderRecycler.setAdapter(orderAdapter); 

這裏注意到的是,setHasFixedSize是至關重要的。我猜想在數據更改時,系統必須重新繪製視圖,以強制跳轉到最高的問題,但如果它知道它們將具有相同的大小,則可以在此情況下更新已更改的文本。

另一個問題是我不能使用notifyDatasetChanged或它仍然會導致同樣的問題。我必須分別通知每件物品。這是動畫師在回收商聲明中使用的內容。沒有這些,項目會在更新時閃爍。

for(int i = 0; i < orderArrayList.size(); i++){ 
       orderAdapter.notifyItemChanged(i); 
      } 
相關問題