zoukankan      html  css  js  c++  java
  • ScrollView中嵌套GridView,Listview的办法

    按照android的标准,ScrollView中是不能嵌套具有滑动特性的View的,但是有时如果设计真的有这样做的需要,或者为了更方便简单的实现外观(比如在外在的大布局需要有滑动的特性,并且内部有类似于List的UI结构,那么ListView + Adpater的方式来实现里面的效果就很方便,算是违规抄近道的一种方式吧),有时就会不得不采用这种怪异的组合方式。

    先说下这种方式如果不做特殊处理时会出现的冲突和问题:

    1,在SrollView中嵌套ListView,ListView的显示会有问题,只显示一行或显示效果与预期不同,这是因为android禁止这样使用,放入ScrollView中的ListView的高度是无法计         算的。

    2,嵌套中的子ListView和GridvIew是无法滑动的,因为子控件的滑动事件会被外面的ScrollView吃掉,如果想让子控件可以滑动,只能强行的截取滑动的相关事件了。

    言归正传,嵌套的解决方案:

    1,第一种方案,也是我比较推荐的方案,就是重写ListView与GridView,让其失去滑动特性:

    package com.perfect.xiaoao.all.ui;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.GridView;
    
    /**
    * Created by IntelliJ IDEA.
    * User: zhUser
    * Date: 13-1-24
    * Time: 下午6:53
    */
    public class NoScrollGridView extends GridView{
    
         public NoScrollGridView(Context context, AttributeSet attrs){
              super(context, attrs);
         }
    
         public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
              int mExpandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
              super.onMeasure(widthMeasureSpec, mExpandSpec);
         }
    }
    
    package com.perfect.xiaoao.all.ui;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.ListView;
    
    /**
    * Created by IntelliJ IDEA.
    * User: zhUser
    * Date: 13-1-24
    * Time: 下午6:53
    */
    public class NoScrollListView extends ListView{
    
         public NoScrollListView(Context context, AttributeSet attrs){
              super(context, attrs);
         }
    
         public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
              int mExpandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
              super.onMeasure(widthMeasureSpec, mExpandSpec);
         }
    }

    2,第二种方案,也是网上流行的一种解决办法,人工计算子控件的尺寸,解决办法:

    在listview.setAdapter()之后调用Utility.setListViewHeightBasedOnChilren(listview)就Okay 了。

    public class Utility {
    public static void setListViewHeightBasedOnChildren(ListView listView) {
    //获取ListView对应的Adapter
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
    // pre-condition
    return;
    }
    
    int totalHeight = 0;
    for (int i = 0, len = listAdapter.getCount(); i < len; i++) { //listAdapter.getCount()返回数据项的数目
    View listItem = listAdapter.getView(i, null, listView);
    listItem.measure(0, 0); //计算子项View 的宽高
    totalHeight += listItem.getMeasuredHeight(); //统计所有子项的总高度
    }
    
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    //listView.getDividerHeight()获取子项间分隔符占用的高度
    //params.height最后得到整个ListView完整显示需要的高度
    listView.setLayoutParams(params);
    }
    }

    原理就是:设置完ListView的Adapter后,根据ListView的子项目重新计算ListView的高度,然后把高度再作为LayoutParams设置给ListView,这样它的高度就正确了,通过人工算取控件的应有高度,再设置给ListView

    注意:这个方案中子ListView的每个Item必须是LinearLayout,不能是其他的,因为其他的Layout(如RelativeLayout)没有重写onMeasure(),所以会在onMeasure()时抛出异常。

    最后,建议大家还是少用这样的设计,毕竟这种方式是不标准与不规范的。

  • 相关阅读:
    el-select下拉框选项太多导致卡顿,使用下拉框分页来解决
    vue+elementui前端添加数字千位分割
    Failed to check/redeclare auto-delete queue(s)
    周末啦,做几道面试题放松放松吧!
    idea快捷键
    解决flink运行过程中报错Could not allocate enough slots within timeout of 300000 ms to run the job. Please make sure that the cluster has enough resources.
    用.net平台实现websocket server
    MQTT实战3
    Oracle 查看当前用户下库里所有的表、存储过程、触发器、视图
    idea从svn拉取项目不识别svn
  • 原文地址:https://www.cnblogs.com/ycxyyzw/p/3804947.html
Copyright © 2011-2022 走看看