提问者:小点点

在布局中强制将视图回收到页面底部


我有一个由< code>ImageView和< code > recycle view 组成的页面。< code > recycle view 包含少量项目(目前为三个),仅占我的测试设备屏幕的四分之一。然而,尽管尝试了许多布局选项,我还是无法让< code > recycle view 有效地包装其内容,并占用刚好足够的空间来包含这三行,并将剩余的空间留给我的< code>ImageView。

为了帮助说明我的意思,我画了两个图表。第一个显示我希望发生的事情,第二个显示正在发生的事情:

到目前为止,我已经尝试了几种不同的组合的RelativeLayout-例如,我将设置Recy0004 View布局:align_ParentBottom和第二个RelativeLayout,其中包含ImageView布局:对齐组件,以便其底部匹配RecyclView顶部(这通常会拖动ImageView布局,以便它填充任何提醒空间,这就是我希望发生的事情。)

尽管它只包含几行,但它一直占据着它能占据的所有空间。我目前的解决方案是将所有内容都放在LinearLayout中,并将较少的重力设置到RecyclView,但它并不理想,因为在不同的模拟器上,它不会与屏幕底部完全对齐,而在其他模拟器中,没有足够的空间,RecyclView变得可滚动。

提前感谢任何人提供的任何帮助和建议。


共3个答案

匿名用户

非常感谢所有做出贡献的人,但我在布局文件之外找到了编程解决方案。如果其他人正在寻找解决此问题的方法,我在这里找到了一个。

似乎< code > recycle view 目前存在问题,无法包装内容。答案是构造一个扩展< code>LinearLayoutManager的自定义类。我在下面贴出了对我有效的解决方案——大部分是从我引用的链接中给出的答案复制粘贴而来的。唯一的小问题是,它没有考虑到装饰所增加的额外空间,这就是为什么我不得不在代码末尾附近对下面一行做了一点小小的调整:

//I added the =2 at the end.    
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin + 2;

以下是完整的代码:

public class HomeLinearLayoutManager extends LinearLayoutManager{

    HomeLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    private int[] mMeasuredDimension = new int[2];

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
                          int widthSpec, int heightSpec) {
        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);
        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);
        int width = 0;
        int height = 0;
        for (int i = 0; i < getItemCount(); i++) {
            measureScrapChild(recycler, i,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);

            if (getOrientation() == HORIZONTAL) {
                width = width + mMeasuredDimension[0];
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                height = height + mMeasuredDimension[1];
                if (i == 0) {
                    width = mMeasuredDimension[0];
                }
            }
        }
        switch (widthMode) {
            case View.MeasureSpec.EXACTLY:
                width = widthSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        switch (heightMode) {
            case View.MeasureSpec.EXACTLY:
                height = heightSize;
            case View.MeasureSpec.AT_MOST:
            case View.MeasureSpec.UNSPECIFIED:
        }

        setMeasuredDimension(width, height);
    }

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                                   int heightSpec, int[] measuredDimension) {
        View view = recycler.getViewForPosition(position);
        if (view != null) {
            RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
            int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                    getPaddingLeft() + getPaddingRight(), p.width);
            int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                    getPaddingTop() + getPaddingBottom(), p.height);
            view.measure(childWidthSpec, childHeightSpec);
            measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
            measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin + 2;
            recycler.recycleView(view);
        }
    }
}

再次感谢。

匿名用户

将两者放在一个RelativeLayout中,并使ImageView填充parent:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
<RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"/>
<ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_above="@id/recyclerView"
    />
</RelativeLayout>

编辑:不小心写了TextView。修好了。

匿名用户

我能想到的唯一解决方案是使用布局权重。为图像指定 70% 的屏幕,为回收器视图指定 30% 的屏幕,因为您说您只有 3 行。使用 adjustViewByBounds 确保保持图像纵横比。

我的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
    <ImageView
        android:src="@drawable/ic_round_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:layout_weight=".9"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".1"/>
</LinearLayout>