android listview显示所有可用的项目,不带有静态标题的滚动

d-m*_*man 34 android listview

我试图让某个布局工作时遇到一些困难:我想要列表.List不必是可滚动的,但应该完全显示.但是如果总内容高于屏幕,页面本身应该能够滚动(带有列表).

<ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     >

     <LinearLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/linear_layout"
         android:orientation="vertical"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:background="#ff181818"
         >
           <Textview android:id="@+id/my_text" text="header contents goes here" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
           <Textview android:id="@+id/headertext" text="header contents goes here" android:layout_width="fill_parent" android:layout_height="wrap_content"/>

          <ListView
               android:id="@+id/my_list1"
               android:layout_height="wrap_content"
               android:layout_width="fill_parent"
          /> 
     </LinearLayout> 

</ScrollView>
Run Code Online (Sandbox Code Playgroud)

它只使用屏幕的一小部分(每个列表约2行),而不是填充可用的高度,列表本身可以滚动.如何更改布局以始终显示整个列表,但屏幕是否为scrollalbe?

Fed*_*dor 64

我使用的解决方案是用LinearLayout替换ListView.您可以在LinearLayout中创建所有项目,它们都将显示.所以真的没有必要使用ListView.

LinearLayout list = (LinearLayout)findViewById(R.id.list_recycled_parts);
for (int i=0; i<products.size(); i++) {
  Product product = products.get(i);
  View vi = inflater.inflate(R.layout.product_item, null);
  list.addView(vi);
}
Run Code Online (Sandbox Code Playgroud)

  • 线性布局几乎不是替代品.列表视图具有内置适配器(用于填充项目视图),项目之间的分隔符,项目状态,项目单击事件. (47认同)
  • 此示例未显示如何使用产品数据填充视图 (7认同)
  • 更不用说,listview在重用行视图方面具有性能优势.如果你有大量的行,那么线性布局将不起作用,滚动将非常不连贯. (5认同)

Hus*_*soM 40

正如@Alex在接受的答案中指出,LinearLayout几乎不是替代品.我有一个问题,其中LinearLayout不是一个选项,那是我遇到这个博客时.我将把代码放在这里以供参考.希望它可以帮助那里的人!

public class UIUtils {

    /**
     * Sets ListView height dynamically based on the height of the items.
     *
     * @param listView to be resized
     * @return true if the listView is successfully resized, false otherwise
     */
    public static boolean setListViewHeightBasedOnItems(ListView listView) {

        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter != null) {

            int numberOfItems = listAdapter.getCount();

            // Get total height of all items.
            int totalItemsHeight = 0;
            for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
                View item = listAdapter.getView(itemPos, null, listView);
                item.measure(0, 0);
                totalItemsHeight += item.getMeasuredHeight();
            }

            // Get total height of all item dividers.
            int totalDividersHeight = listView.getDividerHeight() *
                    (numberOfItems - 1);

            // Set list height.
            ViewGroup.LayoutParams params = listView.getLayoutParams();
            params.height = totalItemsHeight + totalDividersHeight;
            listView.setLayoutParams(params);
            listView.requestLayout();

            return true;

        } else {
            return false;
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

//initializing the adapter
listView.setAdapter(adapter);
UIUtils.setListViewHeightBasedOnItems(listView);

//whenever the data changes
adapter.notifyDataSetChanged();
UIUtils.setListViewHeightBasedOnItems(listView);
Run Code Online (Sandbox Code Playgroud)

  • 像魅力一样工作,但不应该是UIUtils.setListViewHeightBasedOnItems(适配器); 是UIUtils.setListViewHeightBasedOnItems(listView); ? (2认同)

Kai*_*Kai 11

我有一个ListView在我的布局中,并希望使用一个无法处理ListView这里的库,因为它将它包装成一个ScrollView.对我来说最好的解决方案是基于Fedor的答案.

因为我已经得到了一个ArrayAdapter,ListView我想重新使用它:

LinearLayout listViewReplacement = (LinearLayout) findViewById(R.id.listViewReplacement);
NamesRowItemAdapter adapter = new NamesRowItemAdapter(this, namesInList);
for (int i = 0; i < adapter.getCount(); i++) {
    View view = adapter.getView(i, null, listViewReplacement);
    listViewReplacement.addView(view);
}
Run Code Online (Sandbox Code Playgroud)

对我来说这很好用,因为我只需要显示1到5个元素的动态数据.我只需要添加自己的分隔符.


小智 11

您可以制作自己的自定义列表视图.(它可以扩展ListView/ExpandableListView/GridView)并使用它覆盖onMeasure方法.有了它,你永远不需要调用函数或任何东西.只需在你的xml中使用它.

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
            MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
}
Run Code Online (Sandbox Code Playgroud)


Roj*_*ina 5

如果有人仍然有问题,那么您可以onMesure()像我实现的那样制作 customList 和 add方法:

public class ScrolleDisabledListView extends ListView {

private int mPosition;

public ScrolleDisabledListView(Context context) {
    super(context);
}

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

public ScrolleDisabledListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;

    if (actionMasked == MotionEvent.ACTION_DOWN) {
        // Record the position the list the touch landed on
        mPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
        return super.dispatchTouchEvent(ev);
    }

    if (actionMasked == MotionEvent.ACTION_MOVE) {
        // Ignore move events
        return true;
    }

    if (actionMasked == MotionEvent.ACTION_UP) {
        // Check if we are still within the same view
        if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) {
            super.dispatchTouchEvent(ev);
        } else {
            // Clear pressed state, cancel the action
            setPressed(false);
            invalidate();
            return true;
        }
    }

    return super.dispatchTouchEvent(ev);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
            MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
}
}
Run Code Online (Sandbox Code Playgroud)