2017-02-22 86 views
6

我在NavigationView中使用自定義第一項作爲與ListView的addHeaderView()等效的RecyclerView。在該頁眉佈局的底部,我放置了一個EditText,以便我可以過濾掉下面的列表。如何強制RecyclerView滾動時沒有足夠的項目來填充sceen的高度

我想要做的就是一直向上滾動RecyclerView,直到EditText獲得焦點時EditText成爲最頂端的項目。但是,如果我的項目數量足夠小,無法填充NavigationView的整個高度,則RecyclerView將拒絕一直向上滾動,因此會顯示比EditText更多的標題。作爲一個附加問題,即使列表足夠大,一旦我開始過濾列表項目,它仍然會向下滾動。

如何強制我的RecyclerView繼續向上滾動,即使我沒有足夠的項目來填充視圖的高度,以便我的標題的其餘部分不會偷看?

這裏是我想要實現可視化:

_______________ 
| HEADER LINE 1 | 
| HEADER LINE 2 | 
| HEADER LINE 3 | 
| ------------- | 
| Search box | 
| ------------- | 
| List item 1 | 
| List item 2 | 
| List item 3 | 
--------------- 

當我專注於搜索框預期的行爲:

_______________ 
| ------------- | 
| Search box | <- becomes the topmost item. I can already achieve this 
| ------------- | with RecyclerView.smoothScrollBy(dx, dy) 
| List item 1 | except when the list is small enough (see below) 
| List item 2 | 
| List item 3 | 
| List item 4 | 
|    | <- empty space is okay and is desired if dataset 
|    | is small enough 
--------------- 

實際發生的:

_______________ 
| HEADER LINE 2 | <- the header is 'bleeding' on top 
| HEADER LINE 3 | 
| ------------- | 
| Search box | <- search box cannot take the topmost spot 
| ------------- |  as the recycler tries to position itself to fill in 
| List item 1 |  the bottom part with items 
| List item 2 | 
| List item 3 | 
| List item 4 | <- items are pushed down to the bottom to fill 
---------------  in the space 

這裏是我的NavigationView xml的一個片段(只是你的典型設置):

<android.support.design.widget.NavigationView 
    android:id="@+id/navigation_view" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    android:fitsSystemWindows="true"> 
    <android.support.v7.widget.RecyclerView 
     android:id="@+id/drawer_content" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 
</android.support.design.widget.NavigationView> 

與自定義標題這裏(RecyclerView適配器)ViewHolder:

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    if(viewType == HEADER) { 
     return new HeaderHolder(mHeaderView); 
    } else { 
     View v = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.list_item, parent, false); 

     return new ItemViewHolder(v); 
    } 
} 

抽屜頭只是一個XML佈局我的主要活動充氣(我分配的聽衆和動畫有),並傳遞給我的RecyclerView適配器通過setHeaderView(查看標題)我做的。

+0

試過嗎?這是不同的效果相同的結果。 https://stackoverflow.com/questions/26568087/parallax-header-effect-with-recyclerview –

+0

看到了。我的頭部有控件(包括可擴展的佈局),所以視差效果會毀掉它。更不用說爲它使用一個庫會是矯枉過正,因爲我已經成功地在RecyclerView中實現了自定義標頭。只有滾動位置是問題 – dmonloz

+0

嘗試將回收站視圖的高度更改爲'wrap_content'。 –

回答

1

你需要的是一個頁腳,它與你的頁眉高度相同。

有兩種情況考慮這裏:

  1. 你的頭有一個固定的高度
  2. 你的頭有一個動態的高度

在第一種情況下,解決的方法很簡單。只需定義標題的高度像<dimen name="header_height">300dp</dimen>一些值,然後定義頁眉和頁腳類似如下:

<FrameLayout 
    android:layout_height="@dimen/header_height"> 

    <!-- Content goes here --> 

</FrameLayout> 

在第二種情況下,我們將不得不做兩件事情:

  • 檢索頭的高度時,它改變
  • 更新頁腳的高度,以任何值標頭的高度是

有AR有很多方法可以做到這一點。我之前使用過的一種方法是,您可以在RecyclerView上使用ViewTreeObserver.OnPreDrawListener來檢測標題何時具有高度(以及是否已更改),然後將該高度傳遞給您的RecyclerView.Adapter,該高度將使用它來設置請求當頁腳膨脹時頁腳的高度,然後您只需在頁腳的索引處調用適配器上的notifyItemChanged(int),告訴它重新給頁腳充氣。這裏的大部分東西我只是在代碼中描述:

final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.drawer_content); 
recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
    @Override 
    public boolean onPreDraw() { 
     if(recyclerView.getChildCount() < 1 || recyclerView.getChildAt(0) == null || recyclerView.getChildAt(0).getHeight() == 0) { 
      return true; 
     } 

     int headerHeight = recyclerView.getChildAt(0).getHeight(); 
     adapter.setFooterHeight(headerHeight); 

     return true; 
    } 
}); 

而在你的適配器:

int footerHeight = 0; 

public void setFooterHeight(int footerHeight){ 
    if(this.footerHeight == footerHeight){ 
     return; 
    } 

    this.footerHeight = footerHeight; 
    notifyItemChanged(getItemCount() - 1); 
} 

然後你需要做的唯一的另一件事是喜歡你是你的頭擡高你的頁腳已經將其高度設置爲footerHeight

希望這會有所幫助。

+0

這幾乎是現貨。我有一個動態調整大小的標題。設置頁腳高度,然後notifyItemChanged將向下移動列表的動畫。我做了一些調整。對於我稱之爲墊片的頁腳有一個空洞的看法。我將其大小設置爲 'recyclerVIew.getHeight() - (mItemHeight *(getItemCount() - 2))' 因此,如果列表項不足以填滿屏幕,它將始終填滿屏幕標題高度無關緊要)。每次更新列表時,我都會設置隔離墊高度。 謝謝你指點我在正確的方向。 :) – dmonloz

相關問題