之前在开发过程中遇到过ScrollView嵌套ListView的开发需求,如果listview的item高度固定的话,可以通过继承listview进行重写onMeasure()方法可以完美解决滑动冲突等问题,代码如下:
public class ChildListView extends ListView { public ChildListView(Context context) { super(context); } public ChildListView(Context context, AttributeSet attrs) { super(context, attrs); } public ChildListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
但当listview的item高度不固定时,比如从后台返回的是文字,文字多少不固定有多有少,这时候如果再用上面的方法就会有一个bug,就是ListView的最后一个Item偶尔会被遮挡,显示不全,我在开发中遇到的问题截图如下:
最后一行字完全被遮挡了,这时候就不能用上述方案解决了,下面是我的解决方案如下:
public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.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; } }解决后图片;
参考链接如下:
http://stackoverflow.com/questions/18367522/android-list-view-inside-a-scroll-view
http://stackoverflow.com/questions/6210895/listview-inside-scrollview-is-not-scrolling-on-android