在一個滑動控件或者是布局裡面,添加另外一個可以滑動的控件,通常會造成一些莫名其妙的問題。今天主要介紹在工作中遇到的,在ScrollView布局中嵌套Listview顯示不正常,和在Listview中嵌套Listview的滑動沖突的問題。
1.ScrollView布局中嵌套Listview顯示不正常的解決方案
目前來說,解決這個問題有好幾種解決方案,這裡隻介紹其中兩種比較簡單易行的其中兩種。
(1)自定義一個Listview,繼承自Listview,代碼如下:
[java] view plain copy
- 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
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
- MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
- }
- }
在使用的時候,用這個控件代替Listview控件即可。
(2)重新計算Listview的高度
在一個滑動布局中添加一個滑動控件,滑動控件的高度因為不能計算,是以隻能顯示一個Item,若要解決這個問題,我們可以重新計算Listview的高度,調用下面的靜态方法即可。
[java] view plain copy
- 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);
- }
2.在Listview中嵌套Listview的滑動沖突問題
之前在項目中,出現了這種需求,就是在一個listview的footer中添加一個小的Listview,但是由于觸摸沖突問題,小的listview不能滑動,若要解決這個問題,我們可以自定義一個控件繼承自listview,然後重寫onInterceptTouchEvent方法,對觸摸事件進行分發。
onInterceptTouchEvent()是ViewGroup的一個方法,目的是在系統向該ViewGroup及其各個childView觸發onTouchEvent()之前對相關事件進行一次攔截,我們可以在這個方法裡面,對子控件或者是父控件擷取觸摸處理權限進行分發,進而完成各自的滑動任務。
效果圖如下
代碼如下
[java] view plain copy
- public class InnerListview extends ListView {
- public InnerListview(Context context) {
- super(context);
- }
- public InnerListview(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public InnerListview(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- // 當手指觸摸listview時,讓父控件交出ontouch權限,不能滾動
- case MotionEvent.ACTION_DOWN:
- setParentScrollAble(false);
- case MotionEvent.ACTION_MOVE:
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- // 當手指松開時,讓父控件重新擷取onTouch權限
- setParentScrollAble(true);
- break;
- }
- return super.onInterceptTouchEvent(ev);
- }
- // 設定父控件是否可以擷取到觸摸處理權限
- private void setParentScrollAble(boolean flag) {
- getParent().requestDisallowInterceptTouchEvent(!flag);
- }
- }
這樣,外面的listview和裡面的小listview就都可以實作各自的滑動了。
項目位址 https://github.com/ZhaoKaiQiang/InnerListview
轉自:
在一個滑動控件或者是布局裡面,添加另外一個可以滑動的控件,通常會造成一些莫名其妙的問題。今天主要介紹在工作中遇到的,在ScrollView布局中嵌套Listview顯示不正常,和在Listview中嵌套Listview的滑動沖突的問題。
1.ScrollView布局中嵌套Listview顯示不正常的解決方案
目前來說,解決這個問題有好幾種解決方案,這裡隻介紹其中兩種比較簡單易行的其中兩種。
(1)自定義一個Listview,繼承自Listview,代碼如下:
[java] view plain copy
- 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
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
- MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
- }
- }
在使用的時候,用這個控件代替Listview控件即可。
(2)重新計算Listview的高度
在一個滑動布局中添加一個滑動控件,滑動控件的高度因為不能計算,是以隻能顯示一個Item,若要解決這個問題,我們可以重新計算Listview的高度,調用下面的靜态方法即可。
[java] view plain copy
- 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);
- }
2.在Listview中嵌套Listview的滑動沖突問題
之前在項目中,出現了這種需求,就是在一個listview的footer中添加一個小的Listview,但是由于觸摸沖突問題,小的listview不能滑動,若要解決這個問題,我們可以自定義一個控件繼承自listview,然後重寫onInterceptTouchEvent方法,對觸摸事件進行分發。
onInterceptTouchEvent()是ViewGroup的一個方法,目的是在系統向該ViewGroup及其各個childView觸發onTouchEvent()之前對相關事件進行一次攔截,我們可以在這個方法裡面,對子控件或者是父控件擷取觸摸處理權限進行分發,進而完成各自的滑動任務。
效果圖如下
代碼如下
[java] view plain copy
- public class InnerListview extends ListView {
- public InnerListview(Context context) {
- super(context);
- }
- public InnerListview(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public InnerListview(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- // 當手指觸摸listview時,讓父控件交出ontouch權限,不能滾動
- case MotionEvent.ACTION_DOWN:
- setParentScrollAble(false);
- case MotionEvent.ACTION_MOVE:
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- // 當手指松開時,讓父控件重新擷取onTouch權限
- setParentScrollAble(true);
- break;
- }
- return super.onInterceptTouchEvent(ev);
- }
- // 設定父控件是否可以擷取到觸摸處理權限
- private void setParentScrollAble(boolean flag) {
- getParent().requestDisallowInterceptTouchEvent(!flag);
- }
- }
這樣,外面的listview和裡面的小listview就都可以實作各自的滑動了。
項目位址 https://github.com/ZhaoKaiQiang/InnerListview
http://blog.csdn.net/zhaokaiqiang1992/article/details/38585547
在一個滑動控件或者是布局裡面,添加另外一個可以滑動的控件,通常會造成一些莫名其妙的問題。今天主要介紹在工作中遇到的,在ScrollView布局中嵌套Listview顯示不正常,和在Listview中嵌套Listview的滑動沖突的問題。
1.ScrollView布局中嵌套Listview顯示不正常的解決方案
目前來說,解決這個問題有好幾種解決方案,這裡隻介紹其中兩種比較簡單易行的其中兩種。
(1)自定義一個Listview,繼承自Listview,代碼如下:
[java] view plain copy
- 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
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
- MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
- }
- }
在使用的時候,用這個控件代替Listview控件即可。
(2)重新計算Listview的高度
在一個滑動布局中添加一個滑動控件,滑動控件的高度因為不能計算,是以隻能顯示一個Item,若要解決這個問題,我們可以重新計算Listview的高度,調用下面的靜态方法即可。
[java] view plain copy
- 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);
- }
2.在Listview中嵌套Listview的滑動沖突問題
之前在項目中,出現了這種需求,就是在一個listview的footer中添加一個小的Listview,但是由于觸摸沖突問題,小的listview不能滑動,若要解決這個問題,我們可以自定義一個控件繼承自listview,然後重寫onInterceptTouchEvent方法,對觸摸事件進行分發。
onInterceptTouchEvent()是ViewGroup的一個方法,目的是在系統向該ViewGroup及其各個childView觸發onTouchEvent()之前對相關事件進行一次攔截,我們可以在這個方法裡面,對子控件或者是父控件擷取觸摸處理權限進行分發,進而完成各自的滑動任務。
效果圖如下
代碼如下
[java] view plain copy
- public class InnerListview extends ListView {
- public InnerListview(Context context) {
- super(context);
- }
- public InnerListview(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public InnerListview(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- // 當手指觸摸listview時,讓父控件交出ontouch權限,不能滾動
- case MotionEvent.ACTION_DOWN:
- setParentScrollAble(false);
- case MotionEvent.ACTION_MOVE:
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- // 當手指松開時,讓父控件重新擷取onTouch權限
- setParentScrollAble(true);
- break;
- }
- return super.onInterceptTouchEvent(ev);
- }
- // 設定父控件是否可以擷取到觸摸處理權限
- private void setParentScrollAble(boolean flag) {
- getParent().requestDisallowInterceptTouchEvent(!flag);
- }
- }
這樣,外面的listview和裡面的小listview就都可以實作各自的滑動了。
項目位址 https://github.com/ZhaoKaiQiang/InnerListview
http://blog.csdn.net/zhaokaiqiang1992/article/details/38585547
在一個滑動控件或者是布局裡面,添加另外一個可以滑動的控件,通常會造成一些莫名其妙的問題。今天主要介紹在工作中遇到的,在ScrollView布局中嵌套Listview顯示不正常,和在Listview中嵌套Listview的滑動沖突的問題。
1.ScrollView布局中嵌套Listview顯示不正常的解決方案
目前來說,解決這個問題有好幾種解決方案,這裡隻介紹其中兩種比較簡單易行的其中兩種。
(1)自定義一個Listview,繼承自Listview,代碼如下:
[java] view plain copy
- 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
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
- MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
- }
- }
在使用的時候,用這個控件代替Listview控件即可。
(2)重新計算Listview的高度
在一個滑動布局中添加一個滑動控件,滑動控件的高度因為不能計算,是以隻能顯示一個Item,若要解決這個問題,我們可以重新計算Listview的高度,調用下面的靜态方法即可。
[java] view plain copy
- 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);
- }
2.在Listview中嵌套Listview的滑動沖突問題
之前在項目中,出現了這種需求,就是在一個listview的footer中添加一個小的Listview,但是由于觸摸沖突問題,小的listview不能滑動,若要解決這個問題,我們可以自定義一個控件繼承自listview,然後重寫onInterceptTouchEvent方法,對觸摸事件進行分發。
onInterceptTouchEvent()是ViewGroup的一個方法,目的是在系統向該ViewGroup及其各個childView觸發onTouchEvent()之前對相關事件進行一次攔截,我們可以在這個方法裡面,對子控件或者是父控件擷取觸摸處理權限進行分發,進而完成各自的滑動任務。
效果圖如下
代碼如下
[java] view plain copy
- public class InnerListview extends ListView {
- public InnerListview(Context context) {
- super(context);
- }
- public InnerListview(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public InnerListview(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- // 當手指觸摸listview時,讓父控件交出ontouch權限,不能滾動
- case MotionEvent.ACTION_DOWN:
- setParentScrollAble(false);
- case MotionEvent.ACTION_MOVE:
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- // 當手指松開時,讓父控件重新擷取onTouch權限
- setParentScrollAble(true);
- break;
- }
- return super.onInterceptTouchEvent(ev);
- }
- // 設定父控件是否可以擷取到觸摸處理權限
- private void setParentScrollAble(boolean flag) {
- getParent().requestDisallowInterceptTouchEvent(!flag);
- }
- }
這樣,外面的listview和裡面的小listview就都可以實作各自的滑動了。
項目位址 https://github.com/ZhaoKaiQiang/InnerListview