【问题标题】:layout_height should be a function of layout_widthlayout_height 应该是 layout_width 的函数
【发布时间】:2012-10-30 05:21:59
【问题描述】:

假设纵向模式,我有一个 ImageView,其图像大小可变(但始终为方形)。我希望 ImageView 的宽度始终等于布局的宽度(fill_parent),并且您可以看到 scaleType 是“centerCrop”,它将进行缩放。

问题是,如果我将 *layout_height* 也设置为“fill_parent”,那么由于 centerCrop 保留了原始纵横比,因此高度优先,图像在左右两侧被裁剪。 (这当然假设屏幕比宽高)。但是,如果我将 layout_height 设置为“wrap_content”,则不再缩放高度,最终得到一个裁剪的矩形。这样做是因为它尊重图像的原始高度。

是否有 layout_height 设置优先于“fill_parent”的 layout_width?

<ImageView
    android:id="@+id/iv_image"
    android:layout_width="fill_parent"
    android:layout_height="?"
    android:layout_below="@id/header"
    android:layout_centerHorizontal="true"
    android:contentDescription="@string/cd_image"
    android:padding="0dp"
    android:scaleType="centerCrop"
    android:src="@drawable/blank_album" />

移除 android:layout_height 属性会导致崩溃: java.lang.RuntimeException:二进制 XML 文件第 16 行:您必须提供 layout_height 属性。

设置 android:layout_height="0dp" 垂直压碎图像。

回答:结合其他用户的回答,我找到了一个适合我的简单解决方案。

首先,图像视图有这样的配置(注意fitStart):

<ImageView
    android:id="@+id/iv_album"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_below="@id/header"
    android:layout_gravity="top"
    android:background="#FF00FF00"
    android:contentDescription="@string/app_name"
    android:padding="0dp"
    android:scaleType="fitStart"
    android:src="@drawable/blank_album" />

然后以编程方式,对图像的高度进行小修改以匹配宽度(在 Activity.onResume() 内)

        ImageView iv = (ImageView)findViewById(R.id.iv_album);
        boolean bPost = iv.post(
                new Runnable()
                {
                    public void run()
                    {
                        ImageView iv = (ImageView)findViewById(R.id.iv_album);
                        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)iv.getLayoutParams();
                        params.width = ASong.this.findViewById(R.id.song_view_layout_top).getWidth();
                        params.height = params.width;                           
                        iv.setLayoutParams(params);
                    }
                });

        if (bPost == false)
        {
            throw new RuntimeException("runnable not posted");
        }

【问题讨论】:

    标签: android layout android-imageview


    【解决方案1】:

    我昨天不得不处理这个问题。这是解决我的问题的 XML:

    <ImageView
                    android:id="@+id/character"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_alignParentBottom="true"
                    android:background="@android:color/transparent"
                    android:scaleType="fitCenter"
                    android:src="@drawable/ma_un1_001" />
    

    在此处查看主题:Center drawable and scale height

    长话短说:

    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="fitCenter"
    

    【讨论】:

    • 谢谢,这很有帮助,但仍然不能解决我的问题。这是因为 ImageView 仍然会填满整个屏幕,即使它关联的图像大小正确。这会导致将任何后续控件推离屏幕。
    • 包装你的图像视图怎么样?你不想创建像拇指画廊这样的东西吗?在这种情况下,创建拇指可能会更好。您可以根据需要缩放它们,而不必做布局魔术。除此之外,这将提高性能,并且还可以避免与内存相关的问题。
    • 在没有以编程方式设置大小的情况下包装 IV 的问题是容器的高度在 layout_height=wrap_content 时太短,而在 layout_height=fill_parent 时占据了剩余的高度。
    【解决方案2】:

    或者,您可以通过编程方式进行:

    用 LinearLayout 包围 ImageView

    <LinearLayout
    android:id="@+id/container"
    android:layout_below="@id/header"
    android:layout_centerHorizontal="true"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
        <ImageView
        android:id="@+id/iv_image"
        android:layout_width="fill_parent"
        android:layout_height="?"
        android:contentDescription="@string/cd_image"
        android:padding="0dp"
        android:scaleType="centerCrop"
        android:src="@drawable/blank_album" />
    </LinearLayout>
    

    然后,在你的 onCreate() 中,插入

    findViewById(R.id.container).post(
        new Runnable() {
        public void run() {
            LinearLayout container = (LinearLayout)findViewById(R.id.container);
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)container.getLayoutParams();
            params.height = params.width;
            container.setLayoutParams(params);
        }}
    );
    

    代码必须放到post()中,因为主进程不能直接修改布局结构。

    【讨论】:

    • 我更喜欢使用 fitCenter。高度是可变的,但在这种情况下始终是正方形,但 params.height = params.width; 会在他想改变图像的形状时出现问题。 fitCenter 适用于任何形状。
    • @vallero。这让我开始了谢谢!供参考。不需要调用 container.setLayoutParams(params),因为对 params 的修改会直接生效。其次,宽度是-1,意思是(填充父),所以我改为使用视图的宽度。在调用 runnable 之前,这些视图尺寸不可用,但是 fyi3,这也是主线程(gui)。
    猜你喜欢
    • 2016-05-19
    • 2012-01-31
    • 1970-01-01
    • 2013-10-07
    • 2011-02-17
    • 2015-04-07
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多