2017-02-22 9 views
6

NavigationView内でカスタム最初のアイテムを持つRecyclerViewをListViewのaddHeaderView()と同等のものとして作成しました。そのヘッダーレイアウトの下部に、私はEditTextを配置して、以下のリストを除外することができました。sceenの高さを埋めるのに十分なアイテムがないときにRecyclerViewをスクロールさせる方法

私がやりたかったことは、EditTextがフォーカスを得るたびにEditTextが一番上の項目になるまでRecyclerViewをスクロールすることでした。しかし、アイテム数がNavigationViewの高さ全体を埋めることができないほど小さい場合、RecyclerViewは全部スクロールしてEditText以外のヘッダーを少しだけ表示することを拒否します。追加された問題として、リストが十分な大きさであっても、リスト項目のフィルタリングを開始すると、それでもスクロールバックされます。

ヘッダーの残りの部分でピークが表示されないように、ビューの高さを塗りつぶすのに十分なアイテムがない場合でも、RecyclerViewをさらにスクロールさせるにはどうすればよいですか?ここで

は私が達成しようとしているものの可視化です:

私は検索ボックスに焦点を当てたときの挙動を期待
_______________ 
| HEADER LINE 1 | 
| HEADER LINE 2 | 
| HEADER LINE 3 | 
| ------------- | 
| Search box | 
| ------------- | 
| List item 1 | 
| List item 2 | 
| List item 3 | 
--------------- 

_______________ 
| 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 
:実際に何が起こる

_______________ 
| ------------- | 
| 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 
--------------- 

私の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

必要なものは、ヘッダーと同じ高さのフッターです。

ここで考慮すべき2つのシナリオがあります。

  1. があなたのヘッダは固定の高さ
  2. を持っているあなたのヘッダが最初のケースでは、動的高さ

を持って、解決策は非常に簡単です。ただ、<dimen name="header_height">300dp</dimen>のようないくつかの値では、あなたのヘッダーの高さを定義し、次のようなあなたのヘッダーとフッターを定義します。第2のケースで

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

    <!-- Content goes here --> 

</FrameLayout> 

、我々はいくつかのことをする必要があるとしている:

それが
  • 更新フッターの高さを変更するたびに
    • ヘッダーの高さを取得し、ヘッダの高さがありアーカンソー

    でどのような値これを行う方法はたくさんあります。私が前に使用した方法の1つは、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

    関連する問題