当前位置: 首页 > 编程笔记 >

Android 中ScrollView嵌套GridView,ListView的实例

丁德义
2023-03-14
本文向大家介绍Android 中ScrollView嵌套GridView,ListView的实例,包括了Android 中ScrollView嵌套GridView,ListView的实例的使用技巧和注意事项,需要的朋友参考一下

Android 中ScrollView嵌套GridView,ListView的实例

在Android开发中,经常有一些UI需要进行固定style的动态布局,然而由于现在的UI都喜欢把一个界面拉的很长,所以我们很多情况下需要使用ScrollView来嵌套列表控件来实现UI。这样就导致了很多不顺心的问题。

问题一:列表控件显示不完全

原因是嵌套情况下,ScrollView不能正确的计算列表控件的高度。

有两种解决方案

方案一

适配器赋值完成后代码动态计算列表的高度。这里贴出ListView的计算代码,GridView的计算方式类似,不过需要考虑列数,下面代码没有加上列表控件padding的计算,如果你设置了这个属性,需要加上计算代码

public void setListViewHeightBasedOnChildren(ListView listView) {  
    // 获取ListView对应的Adapter  
    ListAdapter listAdapter = listView.getAdapter();  
    if (listAdapter == null) {  
      return;  
    }  

    int totalHeight = 0;  
    for (int i = 0, len = listAdapter.getCount(); i < len; i++) {  
      // listAdapter.getCount()返回数据项的数目  
      View listItem = listAdapter.getView(i, null, listView);  
      // 计算子项View 的宽高  
      listItem.measure(0, 0);  
      // 统计所有子项的总高度  
      totalHeight += listItem.getMeasuredHeight();  
    }  

    ViewGroup.LayoutParams params = listView.getLayoutParams();  
    params.height = totalHeight+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));  
    // listView.getDividerHeight()获取子项间分隔符占用的高度  
    // params.height最后得到整个ListView完整显示需要的高度  
    listView.setLayoutParams(params);  
  }  

方案二

重写列表控件的onMeasure方法,这种方案不会出现列表控件本身的滚动条,并且viewholder复用机制会失效

@Override
  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int expandSpec = MeasureSpec.makeMeasureSpec(1 << 16, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
  }

方案一代码多,需要多次写,建议写成工具类方便调用;方案二在数据量大到不能一屏显示完的情况下会有性能问题,而且快速滑动的时候ScrollView会不停的去计算列表控件的高度。贼影响绘制性能。
两种方案有利有弊,大家自己取舍

问题二:列表控件自动获取焦点,导致ScrollView自动滚动到列表控件所在的位置

这个问题其实有很多种解决方案,归结起来是两种。

方案一

等待列表控件数据全部加载完成后(包括图片加载)调用ScrollView.fullScroll(ScrollView.FOCUS_UP);

方法让ScrollView滚动到顶部。这个加载完成的时间不好控制,搞得不好会有滚动动画出现,很尴尬的事情。

方案二

重写列表控件的如下两个方法,使之固定返回false

@Override
  public boolean isFocused() {
    return false;
  }

  @Override
  public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
    return false;
  }

两种方案的优缺点很明显,喔,第二种方案的缺点我目前没发现。如果你这么使用发现了什么坑,请留言告知

问题三 滑动冲突

这问题就更操蛋了,根据UI的不同,操蛋程度也不同,涉及到view的事件传递知识,很难给出所有情况的解决代码
解决起来也离不开几个要点,不过首先你得熟悉view的事件传递

你需要根据情况决定重写列表控件与ScrollView的如下几个方法,根据情况给方法返回不同的bool值来告诉控件是否拦截或者传递事件,需要哪个控件相应哪个方向的滚动事件就拦截哪个方向的事件传递,作为一个有追求的开发者,切记不要一通乱拦截

 @Override
  public boolean onTouchEvent(MotionEvent ev) {
    return super.onTouchEvent(ev);
  }

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    return super.onInterceptTouchEvent(ev);
  }

  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    return super.dispatchTouchEvent(ev);
  }

给个小彩蛋

getParent().requestDisallowInterceptTouchEvent(boolean b);

这一句代码可以在子控件里决定是否让父容器获取事件

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

 类似资料:
  • 本文向大家介绍Android中ScrollView嵌套GridView的解决办法,包括了Android中ScrollView嵌套GridView的解决办法的使用技巧和注意事项,需要的朋友参考一下 前些日子在开发中用到了需要ScrollView嵌套GridView的情况,由于这两款控件都自带滚动条,当他们碰到一起的时候便会出问题,即GridView会显示不全。 找到大家的通用解决办法。记录一下。 解

  • 我需要创建一个像谷歌报摊这样的界面,它是一种折叠标题(垂直滚动)上的ViewPenger(水平滚动)。我的要求之一是使用在Google IO 2015上展示的新设计支持库。(http://android-developers.blogspot.ca/2015/05/android-design-support-library.html) 基于克里斯·贝恩斯(https://github.com/c

  • 在< code>NestedScrollView的末尾有一个< code > endlesscrecyclerview 。< code>EndlessRecyclerView表示:当用户滚动到RecyclerView的底部时,它会加载更多数据。这已经在其他地方实现并运行了,但是当我将recyclerView放入< code>NestedScrollView时,< code>OnScrollList

  • 本文向大家介绍Android 解决ScrollView嵌套CridView显示问题,包括了Android 解决ScrollView嵌套CridView显示问题的使用技巧和注意事项,需要的朋友参考一下 Android 解决ScrollView嵌套CridView显示问题 由于GridView是可滑动的控件,嵌套在ScrollView下时需要重写onMeasure方法。 然后在布局XML文件中引入My

  • 本文向大家介绍Android 中ListView和GridView赋值错位,包括了Android 中ListView和GridView赋值错位的使用技巧和注意事项,需要的朋友参考一下 ListView和GridView多次调用getView的bug,导致赋值错位 最近总遇到写GridView适配器赋值时,最后一两个需定义其他图片时,赋图错误,原因就是适配器的getView多次调用,导致数据赋值错误

  • 本文向大家介绍Android中listview嵌套scrollveiw冲突的解决方法,包括了Android中listview嵌套scrollveiw冲突的解决方法的使用技巧和注意事项,需要的朋友参考一下 一.使用网上用的动态改变listview高度的方法 该方法只适用于item布局是LinearLayout布局的情况,不能是其他的,因为其他的Layout(如RelativeLayout)没有重写o