我有RecyclerView,它在屏幕上显示一些项目列表。布局如下:
<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>
在上面的布局tv1
&amp; tv2
有一些信息需要显示,它可能是单行或多行,因此不能给它们一个固定高度因此与它们的父项一起 - &gt; top_view
tv1
和tv2
都有高度作为换行内容。
我想要top_view
高度的顶部填充。我正在以编程方式执行以下操作:
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());
但是上面的代码没有任何效果,如果我给了RecyclerView硬编码的top-padding android:paddingTop="100dp"
它可以工作,但是我不能给出硬编码值,因为它依赖于{{1 }}。
将top_view
置于list
之下的另一件事对我来说不起作用,因为我对此填充有一些其他要求。
那么为什么这个以编程方式设置topPadding不起作用?
答案 0 :(得分:1)
您在RecyclerView
(除适配器之外)操纵视图的方式是ItemDecoration
。
由于您要在列表中添加topPadding
,因此只会影响第一项,因此请按照以下步骤创建自定义RecyclerView.ItemDecoration
:
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;
}
}
}
然后将其添加到您的RecylerView
:
// Insert your own top padding value
list.addItemDecoration(new PaddingTopItemDecoration(value));
答案 1 :(得分:0)
top_view.getHeight()将导致0.视图尚未绘制。
你可以试试这段代码。此时将设置高度。
@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());
}
答案 2 :(得分:0)
通常,使用
top_view.getMeasuredHeight()
而不是
top_view.getHeight().
在这种情况下,请使用ViewTreeObserver。它会等待您绘制布局,以便您的高度不会返回0(就像绘制布局之前一样)。
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);
}
});
}
答案 3 :(得分:0)
对于我的项目,我使用了这里存在的类
https://realm.io/docs/swift/latest/#object-notifications
这是一个非常简单的类,可以让你定义:
-top padding
-bottom padding
- 元素之间的填充
可以像这样使用
//if you want padding between elements
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.addItemDecoration(new SpaceItemDecoration(5));
//if you want padding between elements + top and bottom padding
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.addItemDecoration(new SpaceItemDecoration(5,true,true));
请记住,示例中的5是像素,如果您想要DP,则可以使用此方法将其从DP更改为像素(这是我在util类中使用的众多方法之一)
private static float cachedDpToPixelRatio = -1;
public static float dpToPixels(Context context, int valueInDp) {
if (cachedDpToPixelRatio == -1) {
cachedDpToPixelRatio = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, context.getResources().getDisplayMetrics());
}
return cachedDpToPixelRatio * valueInDp;
}