如何解决listview与scrollview的滑动冲突
参考文献:
《android 事件处理机制之requestDisallowInterceptTouchEvent》:
https://blog.csdn.net/chaihuasong/article/details/17499799
一、问题:
当布局使用了scrollview时,整个布局时可以上下滑动了,但是其中包裹的listview却会卡顿住不能滑动
二、原因:
当有多个层级的View时,父控件scrollview内的权限会禁止子控件获取焦点滑动。
当手指触摸到屏幕时,系统会调用相应View的onTouchEvent,并传入一系列的action。View的onTouchEvent接收到某个touch action后,会有两种返回方式:return true和return false;
return true会告诉系统当前的View需要处理这次的touch事件,以后的系统发出的ACTION_MOVE,ACTION_UP还是需要继续监听并接收的,而且这次的action已经被处理掉了,父层的View是不可能出发onTouchEvent了。所以每一个action最多只能有一个onTouchEvent接口返回true。
return false,便会通知系统,当前View不关心这一次的touch事件,此时这个action会传向父级,调用父级View的onTouchEvent。
三、解决方案:
理解了上述原理,我们就可以监听listview的触摸事件,当触摸到listview并滑动时,重写scrollview里的权限,让父控件的焦点失效。
四、code
import android.view.View; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ListView; import java.util.ArrayList; import android.widget.ScrollView; import android.view.MotionEvent; public class MainActivity extends Activity { private ListView list_photo; private BaseAdapter mAdapter = null; private ArrayList<Lcon> mData_list; private BaseAdapter mAdapter_list = null; private ScrollView scrollView; //Java中所有的变量在使用前必须声明,包括各种控件 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //-----------------------------------LISTVIEW----------------------------------------- list_photo = (ListView) findViewById(R.id.list_photo); ArrayList<Lcon> mData_list = new ArrayList<Lcon>(); mData_list.add(new Lcon(R.mipmap.lista, "货币基金优等生","1.742%","收益稳健,灵活申赎","七日年化","由银行提供服务")); mData_list.add(new Lcon(R.mipmap.listb, "保险无忧金","10.220%","PR1-低风险","七日年化","由银行提供服务")); MyAdapter<Lcon> mAdapter_list = new MyAdapter<Lcon>(mData_list,R.layout.item_list_icon) { @Override public void bindView(ViewHolder holder, Lcon obj) { holder.setImageResource(R.id.list_img,obj.getiId()); holder.setText(R.id.list_txt1,obj.getiName1()); holder.setText(R.id.list_txt2,obj.getiName2()); holder.setText(R.id.list_txt3,obj.getiName3()); holder.setText(R.id.list_txt4,obj.getiName4()); holder.setText(R.id.list_txt5,obj.getiName5()); } }; list_photo.setAdapter(mAdapter_list); //----------------------解决listview与scrollview的滑动冲突------------------------------- //非常重要!必须在main文件里引用整个scrollview,否则点击listview时会因定位不到具体布局的id闪退 scrollView = (ScrollView)findViewById(R.id.scrollView); list_photo.setOnTouchListener(new View.OnTouchListener() { //监听listview的触摸点击事件 @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { // 当手指触摸listview时,让父控件焦点失效,不能滚动 case MotionEvent.ACTION_DOWN: scrollView.requestDisallowInterceptTouchEvent(true); case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_CANCEL: // 当手指松开时,让父控件重新获取焦点 scrollView.requestDisallowInterceptTouchEvent(false); break; } return false; } });