我的第一篇博客--ScrollView中嵌套自定义ListView显示不全的解决方案

来源:互联网 发布:球员对比的软件 编辑:程序博客网 时间:2024/06/05 04:07

之前在开发过程中遇到过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

1 0