空间(视图)在ListItem布局中不起作用

时间:2014-06-05 09:26:50

标签: android android-layout view android-listview space

我已经使用自定义适配器获得了L​​istActivity。此适配器使用以下list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:id="@+id/ll1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center">

        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/default_margin"
            android:contentDescription="@string/checkbox_content_description"
            android:src="@drawable/checkbox_unchecked"
            android:background="@layout/transparent_background"
            android:focusableInTouchMode="false"
            android:adjustViewBounds="true"
            android:clickable="false"
            android:focusable="false" />

        <TextView
            android:id="@+id/tv_amount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/default_margin"
            android:layout_marginTop="@dimen/default_margin"
            android:focusableInTouchMode="false"
            android:clickable="false"
            android:focusable="false"
            android:textIsSelectable="false" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:layout_marginRight="@dimen/default_margin"
            android:layout_marginTop="@dimen/default_margin">

            <TextView
                android:id="@+id/tv_product_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:ellipsize="end"
                android:focusableInTouchMode="false"
                android:clickable="false"
                android:focusable="false"
                android:textIsSelectable="false" />

        </LinearLayout>

        <TextView
            android:id="@+id/tv_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/default_margin"
            android:layout_marginTop="@dimen/default_margin"
            android:focusableInTouchMode="false"
            android:clickable="false"
            android:focusable="false"
            android:textIsSelectable="false" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll2"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_below="@id/ll1">

        <Space
            android:id="@+id/filler_space"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/default_margin"
            android:layout_marginRight="@dimen/default_margin"
            android:layout_marginBottom="@dimen/default_margin"
            android:focusableInTouchMode="false"
            android:clickable="false"
            android:focusable="false" />

        <EditText
            android:id="@+id/et_amount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/default_margin"
            android:layout_marginBottom="@dimen/default_margin"
            android:inputType="number" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:layout_marginRight="@dimen/default_margin"
            android:layout_marginBottom="@dimen/default_margin"
            android:padding="0dp">

            <AutoCompleteTextView
                android:id="@+id/actv_search_product"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:singleLine="true"
                android:ellipsize="end"
                android:inputType="text" />

        </LinearLayout>

        <EditText
            android:id="@+id/et_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/default_margin"
            android:layout_marginBottom="@dimen/default_margin"
            android:inputType="numberDecimal"
            android:digits="0123456789.,-" />

    </LinearLayout>

</RelativeLayout>

在适配器的getView方法中,我添加了以下代码:

// Change the width of the Filler-Space to match the Image
// and leave the height as is
Space space = (Space) view.findViewById(R.id.filler_space);
space.setLayoutParams(new LinearLayout.LayoutParams(
    imageView.getMeasuredWidth(), space.getMeasuredHeight()));

首先给出以下结果:

enter image description here

当我将第二个LinearLayout(ll2)的可见性更改为VISIBLE时,它会得到以下结果:

enter image description here

我想要的是:

enter image description here

因为看起来Space-View宽度根本没有改变。虽然我知道getView方法是成功调用的,这要归功于Log-messages和我在getView方法中做的其他事情。

有谁知道我做错了什么?

PS:当我使用View而不是Space时,我得到了相同的结果。从来没有使用太空,所以我认为它可能需要做些什么。


感谢Demand的选项4:

// Since we can't access Measured widths and heights before the View is completely loaded,
// we set up an Observer that will be called once the ListItem's layout is ready
ViewTreeObserver observer = view.getViewTreeObserver();
if(observer.isAlive()){
    // In order to access the view in the onGlobalLayout, it needs to be final, so we create a final copy here
    final View v = view;
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        // This will be called once the layout is finished, prior to displaying it
        @Override
        public void onGlobalLayout() {
            ImageView imageView = (ImageView) v.findViewById(R.id.image);
            Space space = (Space) v.findViewById(R.id.filler_space);
            // Change the width of the Filler-Space to match the Image and leave the height as is
            space.setLayoutParams(new LinearLayout.LayoutParams(imageView.getMeasuredWidth(), space.getMeasuredHeight()));
        }
    });
}

1 个答案:

答案 0 :(得分:1)

如果您的空间为wrap_content,则设置宽度和高度。这意味着空间将作为他们的孩子有宽度,但没有孩子,你有宽度= 0.这不是关于空间,它是关于android中的布局测量。 当你打电话给你的代码时:

Space space = (Space) view.findViewById(R.id.filler_space);
space.setLayoutParams(new LinearLayout.LayoutParams(
    imageView.getMeasuredWidth(), space.getMeasuredHeight()));

您的imageView尚未测量并且返回宽度= 0.它将在绘制之前进行测量。在适配器中的getView()中,您只创建视图,但测量,布局和绘图将会更晚。

你有几种方法可以解决它:

  1. 以dp为单位设置空间宽度,而不是wrap_content。
  2. 使用相对布局而不是三个线性布局。
  3. 使用TableLayout。
  4. 在适当的时候添加GlobalTreeObserver和getMeasuredWidth()。
  5. 将您的runnable发布到view的处理程序以在绘制后获得宽度。
  6. 我认为最好的方法是2和3,因为4和5会导致多次测量。