ListView,ScrollView嵌套滑動衝突問題,子view包含EditText等

之前寫過ListView和ScrollView嵌套滑動衝突問題,最近剛好遇到ListView的子View包含可以獲取焦點的情況,這種情況下只是單純的給ListView設置onTouchListener會經常失效,也就是滑動衝突重新出現了。

經過同事提點,我自己也測試了一下,解決滑動衝突的成功率果然提高了很多,話不多說,趕緊分享一下。
最開始解決衝突的方式:

listView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //關鍵是這一句
                scrollView.requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });

這是最簡單的,要做ListView和ScrollView滑動能力自動切換可以看一下我之前的一篇分享。下面直接說這次的重點,ListView的ItemView裏包含了Button,CheckBox,EditText(尤其是這個)等會獲取焦點的控件,解決衝突的方式其實和之前的差不多,我們在自定義的adapter裏增加onTouchListener的對象,在構造函數或者另外提供一個set方法,將用於解決衝突的onTouchListener傳進ItemView裏。

下面是代碼
 

TestAdapter testAdapter = new TestAdapter(this, Arrays.asList(testArray), new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //判斷是否爲滑動,是滑動則讓scrollView不可滑動
                //這裏只判斷了滑動,可根據需要判斷主要滑動方向(要用到ACTION_DOWN 和ACTION_UP),
                //我這對解決衝突的精度沒有特別高要求,就單純判斷滑動就完事了
                if(event.getAction() == MotionEvent.ACTION_MOVE){
                    scrollView.requestDisallowInterceptTouchEvent(true);
                }
                return false;
            }
        });

然後在會獲取焦點的控件裏,給它設置傳進去的onTouchListener

@Override
    public View getView(int position, View convertView, ViewGroup parentView){
        ViewHolder holder;
        if(convertView == null){
            convertView = View.inflate(mContext, R.layout.test_item, null);
            holder = new ViewHolder();
            holder.tvLabel = (TextView) convertView.findViewById(R.id.tvLabel);
            holder.etValue = (EditText) convertView.findViewById(R.id.etValue);
            //這個控件會獲得焦點,直接給它設置onTouchListener
            holder.etValue.setOnTouchListener(onTouchListener);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tvLabel.setText(dataList.get(position));
        holder.etValue.setText(dataList.get(position));
        return convertView;
    }

衝突問題到這就基本解決了。
其實最開始我還嘗試使用過

android:descendantFocusability="blocksDescendants"

但是基本上沒效果。最後才用這麼麻煩的方法。注意這個方法裏沒有對ListView包含EditText會導致的數據紊亂,光標異常這些問題進行處理,所以說如果用到TextWatcher這些還是需要自己再處理一下的,記錄好位置就好了,有空也分享一下這個,但這個網上也有很多,找一下就好了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章