zoukankan      html  css  js  c++  java
  • Android 解决ScrollView嵌入ListView | GridView | ScrollView显示问题

    一、ScrollView中嵌套ListView

    ScrollView和ListView都是滚动结构,很明显如果在ScrollView中加入ListView,可以预见性的知道,肯定会有显示/滚动的问题,接下来就分享我在网上找到的方法(有2种方法);

    M1、手动设置(计算)ListView的高度

    /**
     * 动态设置ListView的高度
     * @param listView
     */
    public static void setListViewHeightBasedOnChildren(ListView listView) { 
        if(listView == null) return;
    
        ListAdapter listAdapter = listView.getAdapter(); 
        if (listAdapter == null) { 
            return; 
        } 
    
        int totalHeight = 0; 
        for (int i = 0; i < listAdapter.getCount(); i++) { 
            View listItem = listAdapter.getView(i, null, listView); 
            listItem.measure(0, 0); 
            totalHeight += listItem.getMeasuredHeight(); 
        } 
    
        ViewGroup.LayoutParams params = listView.getLayoutParams(); 
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 
        listView.setLayoutParams(params); 
    }

    上面这个方法很显然,就是设定ListView的高度了,在为ListView设置了Adapter之后使用,就可以解决问题了。
    但是使用这个方法有个细节需要注意:Adapter中getView方法返回的View的必须由LinearLayout组成,因为只有LinearLayout才有measure()方法,如果使用其他的布局如RelativeLayout,在调用listItem.measure(0, 0);时就会抛异常,因为除LinearLayout外的其他布局的这个方法就是直接抛异常的。

    M2、自定义ListView,适应嵌入ScrollView中

    public class ListViewForScrollView extends ListView {
        public ListViewForScrollView(Context context) {
            super(context);
        }
    
        public ListViewForScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ListViewForScrollView(Context context, AttributeSet attrs,
            int defStyle) {
            super(context, attrs, defStyle);
        }
            
        @Override
        /**
         * 重写该方法,达到使ListView适应ScrollView的效果
         */
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
        }
    }

    其实,这个方法也就是重写onMeasure方法,重新计算ListView的高度,不过比第一个方法更加简单简洁;
    同样,使用这个方法时,需要注意一点,默认scrollview会滚动到ListView的第一项,此时只需要让scrollview滚动到最顶端即可:

    scrollview.smoothScrollTo(0, 0);

    二、ScrollView中嵌套GridView
    参考ScrollView中嵌套ListView的第二个实现方法,不过有一占小的区别;参见如下代码:

    public class GridViewForScrollView extends GridView {   
    private boolean haveScrollbar = true;
    public GridViewForScrollView(Context context) { super(context); } public GridViewForScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public GridViewForScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 设置是否有ScrollBar,当要在ScollView中显示时,应当设置为false。 默认为 true * * @param haveScrollbars */ public void setHaveScrollbar(boolean haveScrollbar) { this.haveScrollbar = haveScrollbar; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (haveScrollbars == false) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } }

    三、ScrollView嵌套ScrollView

            parent.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    parent.requestDisallowInterceptTouchEvent(false);
                    return false;
                }
            });
            child.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // 禁止parent view响应child view的触摸事件
                    child.requestDisallowInterceptTouchEvent(true);
                    return false;
                }
            });

    这个方法的核心在于:当触摸事件发生在child身上时,禁止parent view响应child view的触摸事件;

  • 相关阅读:
    .OBJ est1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
    线程详细剖析(四)
    线程详细剖析(三)
    线程详细剖析(二)
    线程详细剖析(一)
    CAN总线相关的几个gitlab代码
    进程详细剖析(三)
    C++实现多级排序
    C/C++读写二进制文件
    C++11新特性
  • 原文地址:https://www.cnblogs.com/a284628487/p/3696403.html
Copyright © 2011-2022 走看看