1. 程式人生 > >我的第一篇部落格--ScrollView中巢狀自定義ListView顯示不全的解決方案

我的第一篇部落格--ScrollView中巢狀自定義ListView顯示不全的解決方案

之前在開發過程中遇到過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; } }
解決後圖片;


參考連結如下: