Sceen

2017-02-22 9 views
6

yüksekliğini doldurmak için yeterli öğe olmadığında kaydırma yapmak için RecyclerView nasıl zorlanır Bir NavigationView içinde özel bir ilk öğeyi ListView'ın addHeaderView(). Bu başlık düzeninin alt kısmında, aşağıdaki listeyi filtrelemek için bir EditText yerleştirdim.Sceen

Yapmak istediğim, EditText odağı her kazanıldığında EditText en üstteki öğe olana kadar RecyclerView öğesinin sonuna kadar kaydırmaktı. Bununla birlikte, öğe sayımın NavigationView'ın tüm yüksekliğini dolduramayacak kadar küçük olması durumunda, RecyclerView, tüm yolu yukarı kaydırmayı ve böylece EditText dışındaki başlıkların biraz daha fazlasını göstermeyi reddeder. Ek bir sorun olarak, liste yeterince büyük olsa bile, liste öğelerini filtrelemeye başladığımda yine de arka arkaya kayar.

Görüşümün yüksekliğini doldurmak için yeterli öğeye sahip olmasam bile, Başlığımın geri kalanı bir göz atmayacak şekilde bile olsa, RecyclerView'ımı tamamen yukarı kaydırmaya nasıl zorlayabilirim? İşte

elde etmek çalışıyorum şeyin bir görselleştirme bulunuyor:

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

Arama kutusuna odaklanmak Beklenen davranış:

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

aslında ne olur:

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

Benim NavigationView xml'imin bir pasajı (sadece tipik kurulumunuz):

01 Burada özel bir başlıkta (RecyclerView Adaptör) ile
<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> 

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

çekmece başlığı (Ben orada dinleyicileri ve animasyonlar atanan) ve aktarılmasını ana aktivitede şişirilmiş sadece xml düzenini benim setHeaderView (View header) üzerinden RecyclerView adaptörü yaptım.

+0

bunu denedi? Bu farklı etki aynı sonuçtur. https://stackoverflow.com/questions/26568087/parallax-header-effect-with-recyclerview –

+0

Bunu zaten gördüm. Başlığımın içinde kontrolleri var (genişletilebilir bir düzen dahil), böylece paralaks etkisi onu mahveder. Bunun için bir kütüphane kullanmaktan söz etmemekle birlikte, RecyclerView'imde başarıyla bir özel başlık daha gerçekleştirdiğim için fazladan olacaktır. Sorun sadece kaydırma pozisyonuydu. – dmonloz

+0

Geri dönüşümcü görünümünün yüksekliğini "wrap_content" olarak değiştirmeyi deneyin. –

cevap

1

İhtiyacınız olan şey, üstbilginizle aynı yükseklikte bir altbilgidir.

burada dikkat edilmesi gereken iki senaryo vardır:

  1. Kişisel başlık
  2. Kişisel başlık dinamik İç yükseklik İlk durumda

sahip sabit bir yüksekliğe sahiptir, çözüm çok basit .Sadece <dimen name="header_height">300dp</dimen> gibi bazı değer Başlığınızın yüksekliğini tanımlamak ve sonra başlığını tanımlamak ve aşağıdaki gibi altbilgim: İkinci durumda

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

    <!-- Content goes here --> 

</FrameLayout> 

, biz bir kaç şey yapmak zorunda gidiyoruz:

o kadar
  • Güncelleme altbilginin yüksekliğini değiştirdiğinde
    • Başlığın yüksekliğini Al başlığının yükseklik yok ar

    ne olursa olsun değer Bunu yapmanın birçok yolu var. Daha önce kullanmış olduğum bir yol, üstbilginin bir yüksekliğe sahip olduğunu (ve sonra değiştiyse) algılamak ve daha sonra bu yüksekliği RecyclerView.Adapter'a iletmek için GericlerGörüntüsünde ViewTreeObserver.OnPreDrawListener kullanabilmenizdir. altbilgisi şişirdiğinde, altbilginizi yeniden şişirmek için altbilgisayarınızın diziniyle birlikte notifyItemChanged(int) aramasını yapmanız yeterlidir.

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

    Ve adaptörü: o zaman yapmak gerekir tek şey size başlık vardır gibi altbilginizi şişirmek olduğunu

    int footerHeight = 0; 
    
    public void setFooterHeight(int footerHeight){ 
        if(this.footerHeight == footerHeight){ 
         return; 
        } 
    
        this.footerHeight = footerHeight; 
        notifyItemChanged(getItemCount() - 1); 
    } 
    

    Ve İşte ben sadece kod açıklanan şeylerin çoğu var zaten ve yüksekliğini footerHeight'a ayarlayın.

    Bu yardımcı olur umarım.

  • +0

    Bu neredeyse noktadaydı. Dinamik olarak yeniden boyutlandırma başlığım var. Altbilgi yüksekliğini ayarlama ve ardından notifyItemChanged, aşağı kaydırıldığında listenin animasyonunu bozar. Bazı ince ayarlar yaptım. Arayıcı olarak aradığım altbilgi için boş bir görünüm vardı. Boyutunu 'recyclerVIew.getHeight() - (mItemHeight * (getItemCount() - 2)) olarak ayarlayın. Liste öğelerinin ekranı doldurmak için yetersiz kalması durumunda ekranı her zaman dolduracaktır (başlık yüksekliği alakasızdı). Liste güncellendiğinde aralık yüksekliğini ayarladım. Bana doğru yönde işaret ettiğiniz için teşekkür ederiz. :) – dmonloz