android布局调整父级而不调整子级的大小

You*_*sef 8 android width android-animation android-layout

TLDR版本:

当我调整父级的大小时:

在此输入图像描述

说明:

在Android应用程序中,我有一个父布局,里面有多个相对布局.

<LinearLayout
    android:id="@+id/parent"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <RelativeLayout
        android:id="@+id/child1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/transparent">

     </RelativeLayout>

    <RelativeLayout
        android:id="@+id/child2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/transparent">

     </RelativeLayout>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

这种布局的孩子们有一些文字和图片.我正在做的是以下内容:

当用户点击按钮时,我想折叠父线性布局(动画宽度直到它为0).我已经实现了这个功能:

public static void collapseHorizontally(final View v) {
    final int initialWidth = v.getMeasuredWidth();

    Animation a = new Animation()
    {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if(interpolatedTime == 1){
                v.setVisibility(View.GONE);
            }else{
                v.getLayoutParams().width = initialWidth - (int)(initialWidth * interpolatedTime);
                v.requestLayout();
            }
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    // 1dp/ms
    long speed = (int)(initialWidth / v.getContext().getResources().getDisplayMetrics().density);
    a.setDuration(speed);
    v.startAnimation(a);
}
Run Code Online (Sandbox Code Playgroud)

我在父视图上调用上面的函数.这工作正常,父视图的宽度调整为0,然后我将其可见性设置为已消失.

我的问题

当父视图重新调整大小(折叠)时,子视图也会随之调整大小.我的意思是,当父元素的宽度到达其中一个子元素时,子元素也将使用它重新调整大小,这将导致其中的文本视图也重新调整大小.

以下是一些示例的屏幕截图:

在此输入图像描述

在这里,您可以看到初始布局,绿色的父布局和子布局(包含日期和文本和图标).

然后,当我开始减小父布局的大小时,子布局大小也会受到影响,它将减小其中textview的大小,导致单词换行,如下面的两个图像所示:

在此输入图像描述 在此输入图像描述

当您注意到子项中的文本被包装时,父项的宽度会减少.

有没有一种方法可以让子元素不用父视图调整大小,但保持原样,即使父视图大小正在减少?我需要chil元素的大小在整个大小调整动画期间保持固定,并且不会被父级调整.

非常感谢您的帮助

Gui*_*ian 9

你的问题来自几个问题.

  • 第一个:singleLine="false" 你的参数TextViews >使用这个参数,你不能要求它包装它的内容,因为文本可以使用多行,因此没有适当的宽度.如果有多行,它将填充其父级.
  • 第二:"wrap_content"的行为是为了适应内容大小,除非它大于父级.在这种情况下,它将再次匹配父级大小.(我们可以看到,从填充或边距移动,边界遵循父级大小.)

第二个问题可以通过使用固定大小来解决,但不是第一点的情况:

你可以设置singleLine="true",android:width="wrap_content"看它在单行上工作.(设置android:ellipsize="none"是为了隐藏'...'移动)但单行文字不是你需要的吗?

我已经进行了一些测试,TextView以避免这些视图调整大小,即使有多行:

public class NoResizeTextView extends TextView {

    int firstWidth = -1;
    int firstHeight = -1;

    public NoResizeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        Layout layout = getLayout();
        if (layout != null) {

            if (firstWidth == -1)
                firstWidth = getMeasuredWidth();
            if (firstHeight == -1)
                firstHeight = getMeasuredHeight();

            setMeasuredDimension(firstWidth, firstHeight);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后在布局中使用此TextView扩展:

       <com.guian.collapsetest.NoResizeTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="none"
                android:singleLine="false"
                android:text="Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit" >
        </com.guian.collapsetest.NoResizeTextView>
Run Code Online (Sandbox Code Playgroud)

那不是很漂亮,我不建议过多地使用它,因为它可能会破坏android的布局机制.但在你的特殊情况下,我猜它确实起了作用.

逻辑:

当您扩展视图以创建自定义视图时,您负责实施onMeasure.这就是它的大小给你的看法.这就是它的工作原理:你计算一次大小(或者让默认函数为你做的而不是x getMeasuredW/H)并保存它,然后在每个大小请求上,你只需返回相同的值,这样你的视图大小就不会改变.

限制:

正确您的视图大小不会改变,它可能会在更改屏幕方向/父级大小时有不良行为,或者当文本内部更改时(如Vikram所说).这就是我所谓的"破解android布局机制".如果需要动态更改文本,则必须扩展setText方法以允许它在此时调整大小...

  • 当文本动态更改时,这会如何? (2认同)