Android ListView 固定高度项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10387826/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:31:02  来源:igfitidea点击:

Android ListView fixed height item

androidandroid-listviewandroid-relativelayout

提问by Dmitriy

Got a little problem. I'd like to create an android list view activity with all items in the list having a fixed height.

出了点小问题。我想创建一个 android 列表视图活动,列表中的所有项目都具有固定的高度。

So, my item layout (thread_item.xml) looks like this:

因此,我的项目布局 (thread_item.xml) 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="300dip"
        >
    <TextView android:id="@+id/thread_item_title"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="[dummy]"
              android:textSize="20dip"
              android:textStyle="bold"
            />
    <ImageView android:id="@+id/thread_first_image"
               android:layout_below="@id/thread_item_title"
               android:scaleType="centerInside"
               android:maxWidth="100dip"
               android:maxHeight="100dip"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:adjustViewBounds="true" />
    <TextView
            android:id="@+id/thread_item_preview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignTop="@id/thread_first_image"
            android:text="[dummy]"
            android:textSize="15dip">
    </TextView>
</RelativeLayout>

I set layout_height of the root element to 300dip and expect all items to have the same height, but they don't. When I run the application it looks like the height having a wrap_content value.

我将根元素的 layout_height 设置为 300dip 并期望所有项目具有相同的高度,但它们没有。当我运行应用程序时,它看起来像具有 wrap_content 值的高度。

In addition the activity itself looks like this:

此外,活动本身如下所示:

public class ThreadListActivity extends ListActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        /*
         Code to get items from the storage.
        */

        setListAdapter(new ThreadItemAdapter(this, R.layout.thread_item, itemsArray)));


        getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                /*Start new Activity. Unrelated stuff.*/
            }
        });
    }
}

And adapter I'm using looks like this:

我正在使用的适配器如下所示:

public class ThreadItemAdapter extends ArrayAdapter<ThreadItem> {

    Activity context;
    List<ThreadItem> items;

    public ThreadItemAdapter(Activity context, int textViewResourceId, List<ThreadItem> items) {
        super(context, textViewResourceId, items);
        this.context = context;
        this.items = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inf = this.context.getLayoutInflater();
        View result;
        if (convertView == null) {
            result = inf.inflate(R.layout.thread_item, null);
        } else {
            result = convertView;
        }

        TextView tbTitle = (TextView) result.findViewById(R.id.thread_item_title);
        TextView tbPreview = (TextView) result.findViewById(R.id.thread_item_preview);
        ImageView ivFirstImage = (ImageView) result.findViewById(R.id.thread_first_image);

        ThreadItem item = items.get(position);

        tbTitle.setText(item.getThreadTitle());
        ivFirstImage.setImageBitmap(item.getFirstImage());

        SimpleLeadingMarginSpan span = new SimpleLeadingMarginSpan(item.getFirstImage() != null ? 5 : 0, 115); // TODO: const
        SpannableString previewText = new SpannableString(item.getThreadPreview());
        previewText.setSpan(span, 0, previewText.length(), 0);
        tbPreview.setText(previewText);

        return result;
    }
}

I can't see why all list items still wrap their content and don't stay 300dip in height. They might be both smaller or bigger then 300dip. I'm using android 2.3.3, testing on HTC Evo 3D device and an emulator (both show same result).

我不明白为什么所有列表项仍然包裹它们的内容并且不保持 300dip 的高度。它们可能比 300dip 更小或更大。我正在使用 android 2.3.3,在 HTC Evo 3D 设备和模拟器上进行测试(两者都显示相同的结果)。

Thanks a lot in advance.

非常感谢。

UPD:

更新:

Thanks to Miguel and Sam. The solution is to set maxHeight to the textView, that makes my list item grow (that would be +id/thread_item_preview) and setting the RelativeLayout's minHeight to 300dip as well, to prevent it from shrinking.

感谢米格尔和山姆。解决方案是将 maxHeight 设置为 textView,这会使我的列表项增长(即+id/thread_item_preview)并将 RelativeLayout 的 minHeight 设置为 300dip,以防止其缩小。

回答by josephus

when inflating for convertView, instead of just

当为 convertView 充气时,而不仅仅是

result = inf.inflate(R.layout.thread_item, null);

do

result = inf.inflate(R.layout.thread_item, parent, false);

The method in question is inflater.inflate(int viewId, ViewGroup parent, boolean attachToRoot)-- because you're not honoring the supplied parent(which in this case is the ListView), whatever dimension you supply to the listview item will by default be set to layout_width=fill_parent, layout_height=wrap_content, ignoring the 300dip height you specified in xml. By supplying the parent view and passing false, the inflater will honor the 300dip height, while not attaching it to the root (parent).

有问题的方法是inflater.inflate(int viewId, ViewGroup parent, boolean attachToRoot)——因为你不尊重所提供的parent(在这种情况下是 ListView),你提供给列表视图项的任何尺寸都将默认设置为 layout_width=fill_parent、layout_height=wrap_content,忽略 300dip您在 xml 中指定的高度。通过提供父视图并传递false,充气器将遵守 300dip 高度,而不会将其附加到根(父)。

回答by Sam

What if you change all the child view heights in the row from wrap_contentto match_parent?

如果您将行中的所有子视图高度从wrap_content更改为match_parent怎么办?



From comments

来自评论

Have you tried the minHeightand maxHeightattributes? For example:

您是否尝试过minHeightmaxHeight属性?例如:

android:minHeight="300dp"

You should also watch Android's Romain Guy discuss efficiency in adapters and getView().

您还应该观看 Android 的 Romain Guy讨论适配器和getView().

回答by Miguel Botón

Try changing this

尝试改变这个

android:layout_height="300dip"

to

android:minHeight="300dip"

This worked for me using an ExpandableListView, so I suppose it will work for this case.

这对我使用 ExpandableListView 有用,所以我想它适用于这种情况。

回答by Vinit Shandilya

You can achieve this by specifying the same dimension for Min and Max. This fixed my problem.

您可以通过为 Min 和 Max 指定相同的维度来实现这一点。这解决了我的问题。

<ImageView
    android:id="@+id/appIconImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="8dp"
    android:adjustViewBounds="true"
    android:maxHeight="50dp"
    android:maxWidth="50dp"
    android:minHeight="50dp"
    android:minWidth="50dp"
    android:src="@drawable/ic_launcher" />

enter image description here

在此处输入图片说明

回答by vrbsm

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:minHeight="60dp"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:gravity="center"
    android:weightSum="1"
    android:background="@color/main_color">

    <ImageView
        android:id="@+id/img_left_menu"
        android:layout_weight="0.4"
        android:focusable="false"
        android:maxHeight="50dp"
        android:maxWidth="50dp"
        android:minHeight="50dp"
        android:minWidth="50dp"
        android:layout_width="0dp"
        android:scaleType="centerInside"
        android:adjustViewBounds="true"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tx_left_menu"
        android:layout_width="0dp"
        android:textSize="18dp"
        android:layout_gravity="center_vertical"
        android:layout_weight="0.6"
        android:singleLine="true"
        android:layout_height="wrap_content"
        android:focusable="false"
        />
</LinearLayout>

回答by DoruChidean

If I'm not mistaken, the listView automatically modifies the LayoutParams of a custom view to wrap_content, wrap_content. However, the answers above are correct, if you set a minHeight or minWidth it will work brilliantly.

如果我没记错的话,listView 会自动将自定义视图的 LayoutParams 修改为 wrap_content、wrap_content。但是,上面的答案是正确的,如果您设置 minHeight 或 minWidth 它将工作得很好。

回答by kabuko

Try setting the content TextView's height to 0dpand then setting its layout_alignParentBottomto true.

尝试将内容 TextView 的高度0dp设置为,然后将其设置layout_alignParentBottomtrue