【问题标题】:Dynamically change the row height in a listview based on number of list items根据列表项的数量动态更改列表视图中的行高
【发布时间】:2013-06-14 13:10:35
【问题描述】:

我正在创建一个使用 ListView 的 Android 应用程序。 ListView 由 CheckedTextView 列表项组成。我的活动在顶部包含一个 EditText,在其下方包含一个 TextView,在底部包含一个 Button。 TextView 和按钮之间的空间是ListView 占用的区域。现在,由于我的 ListView 包含的项目很少,因此 ListView 的整个空间都没有被它们占用。此外,剩余空间显然因设备而异。我想知道的是是否有办法改变 ListView 的行高,以便覆盖分配给 ListView 的整个空间。而且,如果需要添加一些项目,行高可能会相应地自行调整。 我在下面提供了一些代码 sn-ps 以便于理解我的 Layout 是什么样的。

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#D0D0D0"
tools:context=".MainActivity" >

<Button
    android:id="@+id/addcourse"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:text="Add Course" />

<EditText
    android:id="@+id/coursenameet"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:ems="10"
    android:layout_marginBottom="2dp"
    android:layout_marginTop="2dp"
    android:hint="Course Name" 
    android:inputType="textCapWords" >

    <requestFocus />
</EditText>

<View
    android:id="@+id/divider"
    android:layout_width="match_parent"
    android:layout_height="3dp"
    android:layout_below="@+id/coursenameet"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:background="@android:color/darker_gray" >
</View>

<TextView
    android:id="@+id/weekdaytv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/divider"
    android:layout_marginBottom="3dp"
    android:layout_marginTop="3dp"
    android:layout_centerHorizontal="true"
    android:text="Select weekdays for this Course" >
</TextView>

<ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/addcourse"
    android:layout_below="@+id/weekdaytv"
    android:divider="#FFFFFF"
    android:dividerHeight="2px">

</ListView>

</RelativeLayout>

这些项目是使用 BaseAdapter 实现的 CheckedTextView。 BaseAdapter 类的 View 方法是

public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    int colorpos = position % colors.length;
    if(v == null){
        LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.listviewitem, null);
    }
    CheckedTextView newrow = (CheckedTextView) v.findViewById(R.id.checkedtextview);
    v.setBackgroundColor(colors[colorpos]);
    newrow.setTextColor(Color.BLACK);
    newrow.setText(items[position]);
    return v;
}

编辑:主要活动的片段

lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    adapter = new ItemsAdapter(MainActivity.this, weekdays, 6, lv.getBottom() - lv.getTop());
    lv.setAdapter(adapter);

    lv.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            CheckedTextView ctv = (CheckedTextView) arg1;
            adapter.toggle(ctv);
        }
    });

【问题讨论】:

  • 有正确的解决方案吗?

标签: android android-layout android-listview listviewitem


【解决方案1】:

嗨,创建一个这样的类

public class Utility {

    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
    }


 }

在你想动态改变列表视图行高的地方调用这个方法。

 Utility.setListViewHeightBasedOnChildren(YourListView);

更多Reference..希望这对你有帮助。

【讨论】:

  • 我已经在 BaseAdapter 类中声明了我的行的外观。请告诉我这到底是要做什么??另外我正在使用:- lv.setAdapter(adapter); 设置我的适配器。我应该在那之后调用这个方法吗?假设我现在有固定数量的行,我现在没有添加任何行。
  • 只需在该方法中声明您的列表视图。它会给你你想要的。
  • 我真的很抱歉,但我无法理解你。我已经编辑了我的问题并提供了主要活动代码的 sn-p 以让您了解我到底在做什么。建议我应该在哪里调用该方法。
  • 在此行之后调用 lv.setAdapter(adapter); Utility.setListViewHeightBasedOnChildren(lv);
  • 我使用了这个代码。它将完美运行..如果您对此有更多疑问。只需单击该引用..
【解决方案2】:

要将ListView 设置为填充分配的整个空间,您可以在XML 中设置listView 属性:

android:fillViewport=”true”

或者在代码中:

myListView.setFillViewport(true);

如果你想改变一个单元格的大小,你可以计算ViewParams来设置。例如,对于单个单元格,您可以使用:

AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, AbsListView.LayoutParams.FILL_PARENT);
v.setLayoutParams(params);

对于 n 个单元格,您可以根据您的 ListView 的大小计算垂直大小:

int n = /* number of cells */ 3;
int height = (myListView.getBottom() - myListView.getTop());
AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, height/n);
v.setLayoutParams(params);

【讨论】:

  • 它给出了一个错误:- 与元素类型“ListView”关联的属性“android:fillViewport”需要打开引用。请帮忙。
  • 请在答案的最后一行告诉我 myCell 是什么。我的代码中没有相应的值。还要告诉我这是要在主要活动还是我拥有的 BaseAdapter 类中完成。
  • AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, height/n);在这一行中, FILL_PARENT 被 Eclipse 删除/弃用。我也不能使用 myListView.getBottom() 因为 listview 声明在另一个类中,而不是 BaseAdapter 类。请帮忙!!
  • @tintin,然后您需要通过其他方式找到所需的高度。至于FILL_PARENT:可以换成MATCH_PARENT
  • 我做到了。我将行数和高度传递给 BaseAdapter 类的构造函数,并将 FILL_PARENT 更改为 MATCH_PARENT。但它的列表视图仍然是它之前的样子。这些行不会填满分配给 ListView 的整个区域
【解决方案3】:

对于那些仍然有错误的人

 listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);

像这样写这几行代码。

if (listItem instanceof ViewGroup)

listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        listItem.measure(0, 0);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多