android listview显示所有可用项目,无需滚动静态标题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1778485/
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
android listview display all available items without scroll with static header
提问by d-man
I'm having a little difficulties while trying to get a certain layout to work: I want to have list. List does not have to be scrollable, but should be shown completely. But the page itself should be able to scroll (with the lists in it), if the total content ist higher than the screen.
我在尝试使某个布局起作用时遇到了一些困难:我想要列表。列表不必可滚动,但应完整显示。但是如果总内容高于屏幕,页面本身应该能够滚动(其中包含列表)。
<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>
it only uses a small part of the screen (about 2 lines per list), instead of filling the available height, and the lists themselves can be scrolled. How can I change the layout to always show the whole lists but have the screen be scrollalbe?
它只使用屏幕的一小部分(每个列表大约 2 行),而不是填充可用高度,并且列表本身可以滚动。如何更改布局以始终显示整个列表但让屏幕滚动?
回答by Fedor
The solution I used is to replace ListView with LinearLayout. You can create all your items inside LinearLayout, they will all be displayed. So there's really no need to use ListView.
我使用的解决方案是用 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);
}
回答by HussoM
As @Alex noted in the accepted answer that LinearLayout is hardly a replacement. I had a problem where LinearLayout was not an option, that's when i came across this blog. I will put the code here for reference purposes. Hope it helps someone out there!
正如@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;
}
}
}
Usage:
用法:
//initializing the adapter
listView.setAdapter(adapter);
UIUtils.setListViewHeightBasedOnItems(listView);
//whenever the data changes
adapter.notifyDataSetChanged();
UIUtils.setListViewHeightBasedOnItems(listView);
回答by Kai
I had a ListView
in my layout and wanted to use a library which can't handle a ListView
here because it wraps it into a ScrollView
. The best solution for me is based on Fedor′s answer.
ListView
我的布局中有 a并且想使用一个无法处理 a 的库,ListView
因为它将它包装成ScrollView
. 对我来说最好的解决方案是基于 Fedor 的回答。
Since I already got an ArrayAdapter
for the ListView
I wanted to re-use it:
因为我已经得到了一个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);
}
For me this works fine because I just need to display dynamic data varying from 1 to 5 elements. I just had to add my own divider.
对我来说这很好用,因为我只需要显示从 1 到 5 个元素变化的动态数据。我只需要添加我自己的分隔线。
回答by Francisco
You can make your own customlistview. (It can extends ListView/ExpandableListView/GridView) and override the onMeasure method with this. With this you'll never need to call a function or anything. Just use it in your xml.
您可以制作自己的自定义列表视图。(它可以扩展 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);
}
回答by Rojina
If someone still has the problem then you can make customList and add onMesure()
method just like I implemented it:
如果有人仍然有问题,那么您可以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);
}
}
回答by tinsukE
Check this out:
看一下这个:
ListView ignoring wrap_content
Using android:layout_height and android:layout_weight solved it for me:
使用 android:layout_height 和 android:layout_weight 为我解决了这个问题:
<ListView
android:layout_height="0dp"
android:layout_weight="1"
/>
回答by Ivan
I just did it using setting params of ListView
我只是使用 ListView 的设置参数来完成的
public static void setListViewHeightBasedOnChildren(ListView listView) {
//this comes from value from xml tag of each item
final int HEIGHT_LARGE=75;
final int HEIGHT_LARGE=50;
final int HEIGHT_LARGE=35;
ViewGroup.LayoutParams params = listView.getLayoutParams();
int screenSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
switch(screenSize) {
case Configuration.SCREENLAYOUT_SIZE_LARGE:
params.height =(int) (HEIGHT_LARGE*size);
break;
case Configuration.SCREENLAYOUT_SIZE_NORMAL:
params.height =(int) (HEIGHT_NORMAL*size);
break;
case Configuration.SCREENLAYOUT_SIZE_SMALL:
params.height =(int) (HEIGHT_SMALL*size);
break;
}
listView.setLayoutParams(params);
}
回答by Vahe Gharibyan
If all items has the same height
如果所有项目具有相同的高度
int totalItemsHeight = baseDictionaries.size() * item.getMeasuredHeight();
int totalDividersHeight = listView.getDividerHeight() * (baseDictionaries.size() - 1);
int totalPadding = listView.getPaddingBottom() + listView.getPaddingTop();
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) listTranslationWords.getLayoutParams();
lp.height = totalItemsHeight + totalDividersHeight + totalPadding;
listTranslationWords.setLayoutParams(lp);
回答by Catluc
Iam supprised no one see this.U cant have two scrolls on the same layout. 1st u have a scrollview and then u have a list, i bet u are killing some android good practices there.
我很惊讶没有人看到这个。你不能在同一个布局上有两个卷轴。首先你有一个滚动视图,然后你有一个列表,我敢打赌你在那里扼杀了一些 android 良好实践。
回答by Kvant
If you want a simple solution to this problem without extending ListView class, this is a solution for you.
如果您想在不扩展 ListView 类的情况下对该问题进行简单的解决,这是一个适合您的解决方案。
mListView.post(new Runnable() {
@Override
public void run() {
int height = 0;
for(int i = 0; i < mListView.getChildCount();i++)
height += mListView.getChildAt(i).getHeight();
ViewGroup.LayoutParams lParams = mListView.getLayoutParams();
lParams.height = height;
mListView.setLayoutParams(lParams);
}
});