2017-07-20 1 views
1

Ich habe RecyclerView, die einige Elemente als Liste auf dem Bildschirm zeigt. Das Layout ist wie folgt:Das Einstellen des oberen Padding für einen RecyclerView funktioniert programmatisch nicht?

<RelativeLayout 
     android:id="@+id/parent" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@id/top_layout"> 

     <RelativeLayout 
      android:id="@+id/top_view" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignParentTop="true"> 

      <TextView 
       android:id="@+id/tv1" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:inputType="textMultiLine" 
       android:layout_alignParentTop="true" 
       android:background="@android:color/holo_blue_light" /> 

      <TextView 
       android:id="@+id/tv2" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_below="@id/tv1" 
       android:inputType="textMultiLine" 
       android:background="@android:color/holo_blue_light" /> 
     </RelativeLayout> 


     <android.support.v7.widget.RecyclerView 
      android:id="@+id/list" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_alignParentTop="true" 
      android:clipToPadding="false" 
      android:scrollbars="vertical" /> 

    </RelativeLayout> 

In oben Layout tv1 & tv2 einige Informationen haben zu zeigen, kann es einzelne Zeile oder mehreren Leitungen sein, damit sie eine festgelegte Höhe geben nicht möglich ist, damit zusammen mit ihren Eltern ->top_view sowohl tv1 als auch tv2 haben Höhe als Wrap-Inhalt.

Ich möchte Top-Polsterung von top_view s Höhe. Dass ich programmatisch tue wie folgt:

top_view = (RelativeLayout) findViewById(R.id.top_view); 
list = (RecyclerView) findViewById(R.id.list); 
list.setPadding(list.getPaddingLeft(), 
       top_view.getHeight(), 
       list.getPaddingRight(), 
       list.getPaddingBottom()); 

Aber oben Code hat keine Auswirkung, wenn ich hart codiert Top-Polsterung RecyclerView als android:paddingTop="100dp" geben es funktioniert, aber ich kann nicht hartcodierte Wert, da es geben ist abhängig von top_view.

Eine weitere Sache Platzierung list unter top_view funktioniert nicht für mich, da ich eine andere Anforderung über diese Polsterung habe.

Warum ist das programmgesteuerte TopPadding nicht funktioniert?

+1

Haben Sie gerade versucht, es zu debuggen? All diese Ansichten Höhen sind wahrscheinlich "0", weil sie noch nicht ausgelegt wurden. Der hässliche Hack besteht darin, 'ViewTreeObserver' zu verwenden, um auf das Layout zu warten, oder Sie können ein benutzerdefiniertes Layout erstellen. –

+1

ich stimme David zu, 'top_view.getHeight()' gibt 0 zurück 0 – pskink

+0

können Sie zeigen, wie das Design auf Ihr Ergebnis schaut? –

Antwort

0

top_view.getHeight() ergibt 0. Die Ansicht ist noch nicht gezeichnet.

können Sie diesen Code versuchen. Die Höhe wird an diesem Punkt eingestellt.

@Override 
public void onWindowFocusChanged (boolean hasFocus) { 
     // the height will be set at this point 

     list.setPadding(list.getPaddingLeft(), 
      top_view.getHeight(), 
      list.getPaddingRight(), 
      list.getPaddingBottom()); 
} 
0

Die Art und Weise Sie Ansichten in einer RecyclerView (neben dem Adapter) zu manipulieren ist durch ItemDecoration.

Da Sie eine topPadding zu Ihrer Liste hinzuzufügen nur das erste Element beeinflussen sollte, so erstellen Sie Ihre individuelle RecyclerView.ItemDecoration wie folgt aus:

public class PaddingTopItemDecoration extends RecyclerView.ItemDecoration { 
    private final int size; 

    public PaddingTopItemDecoration(int size) { 
     this.size = size; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     super.getItemOffsets(outRect, view, parent, state); 
     if (parent.getChildAdapterPosition(view) == 0) { 
      outRect.top += size; 
     } 
    } 
} 

Dann fügen Sie es einfach Ihre RecylerView:

// Insert your own top padding value 
list.addItemDecoration(new PaddingTopItemDecoration(value)); 
0

Im Allgemeinen verwenden

top_view.getMeasuredHeight() 

statt

top_view.getHeight(). 

Verwenden Sie in diesem Fall einen ViewTreeObserver. Es wartet darauf, dass das Layout gezeichnet wird, so dass Ihre Höhen nicht 0 zurückgeben (wie vor der Erstellung Ihres Layouts).

parent = (RelativeLayout) findViewById(R.id.parent); 

ViewTreeObserver vto = parent.getViewTreeObserver(); 
     if (vto.isAlive()) { 
      vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
       @Override 
       public void onGlobalLayout() { 
        //Perform your actions here 
        list.setPadding(list.getPaddingLeft(), 
        top_view.getMeasuredHeight(), 
        list.getPaddingRight(), 
        list.getPaddingBottom()); 

        //Remove observer after use 
        parent.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
       } 
      }); 
     } 
Verwandte Themen