我正在使用基本适配器动态设置列表视图中的数据。我试图动态设置listview高度。如果里面的textview是单行的话,它可以很好地工作。但是,如果textview是多行的,则高度设置不正确。仅考虑单行textview设置高度。如何正确设置包含多行textview的列表视图项的高度。这是代码:
片段代码:
ListView mlistNews=(ListView)rootView.findViewById(R.id.news_listView);
mlistNews.setAdapter(new NewsAdapter(getActivity(),params_news));
Utils.setListViewHeightBasedOnItems(mlistNews);
效用函数:
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(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Get padding
int totalPadding = listView.getPaddingTop() + listView.getPaddingBottom();
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight + totalPadding;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
dashboard_list_news.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:layout_width="0dp"
android:id="@+id/news_item_text"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:layout_marginLeft="5dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/chevron"
android:layout_gravity="center_vertical|right"
android:layout_marginLeft="5dp"
android:layout_marginRight="10dp" />
</LinearLayout>
的ListView:
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_shape_list"
android:id="@+id/news_listView"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:divider="#6DCB99"
android:dividerHeight="1dp" />
答案 0 :(得分:6)
正如Teemu所提到的,你需要约束宽度。示例代码如下。
float px = 300 * (listView.getResources().getDisplayMetrics().density);
item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
答案 1 :(得分:3)
问题可能就是这个电话:
item.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
这里您没有约束宽度,因此TextView扩展到显示单行所有文本所需的任何宽度。因此,您将始终获得等于单行文本的高度? 我认为你应该将宽度与列表视图中的宽度相对应。
答案 2 :(得分:0)
您可以尝试使用此自定义列表视图,以避免列表中出现多行文本视图问题
<namespace.epicurio.NestedListView
android:id="@+id/listComments"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:divider="#000000"
android:dividerHeight="1.0sp">
</namespace.epicurio.NestedListView>
public class NestedListView extends ListView implements OnTouchListener, OnScrollListener {
private int listViewTouchAction;
private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;
public NestedListView(Context context, AttributeSet attrs) {
super(context, attrs);
listViewTouchAction = -1;
setOnScrollListener(this);
setOnTouchListener(this);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, -1);
}
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty()) {
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
}
newHeight += getDividerHeight() * listPosition;
}
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
if (newHeight > heightSize) {
newHeight = heightSize;
}
}
} else {
newHeight = getMeasuredHeight();
}
setMeasuredDimension(getMeasuredWidth(), newHeight);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
scrollBy(0, 1);
}
}
return false;
}
}
答案 3 :(得分:0)
试试这段代码:
listview.post(new Runnable() {
@Override
public void run() {
calculateListHeight(listview.getWidth());
}
});
public void calculateListHeight(int width) {
final ListAdapter adapter = listview.getAdapter();
// Calculate the height of the ListView to display all items
int totalHeight = listview.getPaddingTop() + listview.getPaddingBottom();
for (int i = 0; i < adapter.getCount(); i++) {
View item = adapter.getView(i, null, this);
item.measure(
View.MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
);
totalHeight += item.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listview.getLayoutParams();
params.height = totalHeight + (listview.getDividerHeight() * (adapter.getCount() - 1));
listview.setLayoutParams(params);
listview.requestLayout();
}
答案 4 :(得分:0)
@AlexanderAgeichenko 这是我对@baradas和问题的实现
int totalItemsHeight = 0;
float px = (customListView.getResources().getDisplayMetrics().density);
totalItemsHeight = (int)px;
Log.d(YOUR_TAG, " datta forloop ... px " + px);
Log.d(YOUR_TAG, " datta forloop ... totalItemsHeight = (int)px= " + totalItemsHeight);
for (int itemPos = 0; itemPos < datta.length(); itemPos++) {
View item = CustomListAdptr.getView(itemPos, null, customListView);
//// item.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
//// View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
item.getMeasuredHeightAndState();
Log.d(YOUR_TAG, " datta forloop item.getHeight() " + item.getHeight());
Log.d(YOUR_TAG, " datta forloop item.getMeasuredHeight() " + item.getMeasuredHeight());
Log.d(YOUR_TAG, " datta forloop item.getMeasuredHeightAndState() " + item.getMeasuredHeightAndState());
int itmHeight = item.getHeight();
Log.d(YOUR_TAG, " datta forloop ... itmHeight " + itmHeight);
item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalItemsHeight = item.getMeasuredHeight();
// Log.d(YOUR_TAG, " datta forloop ... item.getMeasuredHeight() " + item.getMeasuredHeight());
Log.d(YOUR_TAG, " datta forloop ... totalItemsHeight=item.getMeasuredHeight() " + totalItemsHeight);
}
Log.d(YOUR_TAG, " datta forloop ... totalItemsHeight == " + totalItemsHeight);
// Get total height of all item dividers.
int totalDividersHeight = customListView.getDividerHeight() *
(numberOfItems - 1);
// Get padding
int totalPadding = customListView.getPaddingTop() + customListView.getPaddingBottom();
// Set list height.
ViewGroup.LayoutParams params = customListView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight + totalPadding;
customListView.setLayoutParams(params);
customListView.requestLayout();
customListView.canScrollList(0);
输出是
D/YOUR_TAG: onViewCompleted() if(success) setting the list data
D/YOUR_TAG: datta counts 3
D/YOUR_TAG: datta forloop ... px 2.0
D/YOUR_TAG: datta forloop ... totalItemsHeight = (int)px= 2
D/YOUR_TAG: datta forloop item.getMeasuredHeightAndState() 0
D/YOUR_TAG: datta forloop item.getMeasuredHeight() 0
D/YOUR_TAG: datta forloop item.getHeight() 0
D/YOUR_TAG: datta forloop ... itmHeight 0
D/YOUR_TAG: datta forloop ... totalItemsHeight=item.getMeasuredHeight() 1709
D/YOUR_TAG: datta forloop item.getMeasuredHeightAndState() 0
D/YOUR_TAG: datta forloop item.getMeasuredHeight() 0
D/YOUR_TAG: datta forloop item.getHeight() 0
D/YOUR_TAG: datta forloop ... itmHeight 0
D/YOUR_TAG: datta forloop ... totalItemsHeight=item.getMeasuredHeight() 1709
D/YOUR_TAG: datta forloop item.getMeasuredHeightAndState() 0
D/YOUR_TAG: datta forloop item.getMeasuredHeight() 0
D/YOUR_TAG: datta forloop item.getHeight() 0
D/YOUR_TAG: datta forloop ... itmHeight 0
D/YOUR_TAG: datta forloop ... totalItemsHeight=item.getMeasuredHeight() 1709
D/YOUR_TAG: datta forloop ... totalItemsHeight == 1709
D/YOUR_TAG: getView() -> unit_option= 0 :: class java.lang.String
WITH 110 float px = 110 *(customListView.getResources()。getDisplayMetrics()。density);
D/YOUR_TAG: onViewCompleted() if(success) setting the list data
D/YOUR_TAG: datta counts 3
D/YOUR_TAG: datta forloop ... px 220.0
D/YOUR_TAG: datta forloop ... totalItemsHeight = (int)px= 220
D/YOUR_TAG: datta forloop item.getMeasuredHeightAndState() 0
D/YOUR_TAG: datta forloop item.getMeasuredHeight() 0
D/YOUR_TAG: datta forloop item.getHeight() 0
D/YOUR_TAG: datta forloop ... itmHeight 0
D/YOUR_TAG: datta forloop ... totalItemsHeight=item.getMeasuredHeight() 159
D/YOUR_TAG: datta forloop item.getMeasuredHeightAndState() 0
D/YOUR_TAG: datta forloop item.getMeasuredHeight() 0
D/YOUR_TAG: datta forloop item.getHeight() 0
D/YOUR_TAG: datta forloop ... itmHeight 0
D/YOUR_TAG: datta forloop ... totalItemsHeight=item.getMeasuredHeight() 159
D/YOUR_TAG: datta forloop item.getMeasuredHeightAndState() 0
D/YOUR_TAG: datta forloop item.getMeasuredHeight() 0
D/YOUR_TAG: datta forloop item.getHeight() 0
D/YOUR_TAG: datta forloop ... itmHeight 0
D/YOUR_TAG: datta forloop ... totalItemsHeight=item.getMeasuredHeight() 159
D/YOUR_TAG: datta forloop ... totalItemsHeight == 159