工作中遇到ListView和ScrollView的冲突

众所周知ListView与ScrollView都具有滚动能力,对于这样的View控件,当ScrollView与ListView相互嵌套会成为一种问题:

 问题一:ScrollView与ListView嵌套导致ListView显示不全面

 问题二:ScrollView不能正常滑动


解决方式一:

ScrollView+LinearLayout+ListView可以换成ScrollView+LinearLayout+LinearLayout,对于开发中,ScrollView所能滚动的样式形式各异,另外的话,ScrollView所显示的内容肯定不会太多,因此这种方案是合理而且可选的


解决方式二:

同样是替换:ListView具有HeaderView与FooterView2部分,因此,在非下拉刷新,上拉加载的需求中,完全可以使用ListView来代替ScrollView,因此是合理可选的方案


解决方式三:

主动计算和设置ListView的高度,这样的结果最终得出类似解决方案一效果,具体来说缺点是大材小用,但也是合理的解决办法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     public  class  Utility {
         public  static  void  setListViewHeightBasedOnChildren(ListView listView) {
             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);
         }
     }

解决方式四:

复写ScrollView,从事件方向进行处理,缺点是灵活性不够好

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
public  class  ListScrollView  extends  ScrollView {
  private  List list =  new  ArrayList();
  private  int  scrollPaddingTop;  // scrollview的顶部内边距
  private  int  scrollPaddingLeft; // scrollview的左侧内边距
  private  int [] scrollLoaction =  new  int [ 2 ];  // scrollview在窗口中的位置
  private  final  static  int  UPGLIDE =  0 ;
  private  final  static  int  DOWNGLIDE =  1 ;
  private  int  glideState;
  public  ListScrollView(Context context, AttributeSet attrs) {
   super (context, attrs);
  }
  private  int  downY =  0 ;
  private  int  moveY =  0 ;
  
  @Override
  public  boolean  dispatchTouchEvent(MotionEvent ev) {
   switch  (ev.getAction()) {
   case  MotionEvent.ACTION_DOWN:
    downY = ( int ) ev.getY();
    //System.out.println("actiondown" + ev.getY());
    break ;
   case  MotionEvent.ACTION_MOVE:
    moveY= ( int ) ev.getY();
    //System.out.println("move" + moveY + "down" + downY);
    if ((moveY - downY) >=  0 ) {
     //System.out.println("'''''''''DOWNGLIDE'''''''''''");
     glideState = DOWNGLIDE;
    else  {
     //System.out.println("'''''''''UPGLIDE'''''''''''");
     glideState = UPGLIDE;
    }
    break ;
   case  MotionEvent.ACTION_UP:
   default :
    break ;
   }
   return  super .dispatchTouchEvent(ev);
  }
  @Override
  public  boolean  onInterceptTouchEvent(MotionEvent ev) {
   // 该事件的xy是以scrollview的左上角为00点而不是以窗口为00点
   int  x = ( int ) ev.getX() + scrollLoaction[ 0 ];
   int  y = ( int ) ev.getY() + scrollLoaction[ 1 ];
   for  ( int  i =  0 ; i < list.size(); i++) {
    ListView listView = list.get(i);
    int [] location =  new  int [ 2 ];
    listView.getLocationInWindow(location);
    int  width = listView.getWidth();
    int  height = listView.getHeight();
    // 在listview的位置之内则可以滑动
    if  (x >= location[ 0 ] + scrollPaddingLeft
      && x <= location[ 0 ] + scrollPaddingLeft + width
      && y >= location[ 1 ] + scrollPaddingTop
      && y <= location[ 1 ] + scrollPaddingTop + height) {
     //System.out.println(glideState);
     if (( (listView.getLastVisiblePosition() == (listView.getCount()- 1 )) && (glideState == UPGLIDE) ) ) {
      //System.out.println("up");
      break ;
     }
     if (( (listView.getFirstVisiblePosition() ==  0 ) && (glideState == DOWNGLIDE))) {
      //System.out.println("down");
      break ;
     }
     return  false //让子控件直接处理
    }
   }
   return  super .onInterceptTouchEvent(ev);
  }
  @Override
  public  boolean  onTouchEvent(MotionEvent ev) {
   return  super .onTouchEvent(ev);
  }
  
  
  private  void  findAllListView(View view) {
   if  (view  instanceof  ViewGroup) {
    int  count = ((ViewGroup) view).getChildCount();
    for  ( int  i =  0 ; i < count; i++) {
     if  (!(view  instanceof  ListView)) {
      findAllListView(((ViewGroup) view).getChildAt(i));
     }
    }
    if  (view  instanceof  ListView) {
     list.add((ListView) view);
    }
   }
  }
  @Override
  protected  void  onDraw(Canvas canvas) {
   super .onDraw(canvas);
   scrollPaddingTop = getTop();
   scrollPaddingLeft = getLeft();
   getLocationInWindow(scrollLoaction);
  }
  @Override
  protected  void  onLayout( boolean  changed,  int  l,  int  t,  int  r,  int  b) {
   super .onLayout(changed, l, t, r, b);
   if  ( this .getChildCount() !=  1 ) {
    try  {
     throw  new  ScrollException();
    catch  (ScrollException e) {
     e.printStackTrace();
    }
   }
   list.clear();
   findAllListView( this .getChildAt( 0 ));
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值