ScrollView和ListView滑动冲突问题

1.在ScrollView里面嵌套ListView时,ListView的滑动事件无法响应。

   先看下事件分发的过程:

   由父View层的  onInterceptTouchEvent    到中间层的onInterceptTouchEvent   再到我们View层的  onTouchEvent  

   在回到中间层的  onTouchEvent  最后回到父View的onTouchEvent。

 我们在view中设置的OnTouchEvent没有响应事件,那么很清楚,在父View的OnInterceptTouchEvent 被拦截了。

 这样我们可以很明确的去重新父View的OnInterceptTouchEvent方法。

2.看下实现的效果图

 

3.实现

  布局效果:

  

    <myapplication.com.myasynctask.entity.MyScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:fillViewport="true"
        android:layout_height="wrap_content">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <ImageView
                android:layout_height="300dp"
                android:layout_width="match_parent"
                android:src="@mipmap/background"
                android:scaleType="centerCrop"/>

            <ListView
                android:layout_height="200dp"
                android:layout_width="match_parent"
                android:id="@+id/listView"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:orientation="horizontal">
                <ImageView
                    android:layout_height="400dp"
                    android:layout_width="match_parent"
                    android:src="@drawable/zuo"/>
            </LinearLayout>

        </LinearLayout>
    </myapplication.com.myasynctask.entity.MyScrollView>
View Code

  重写ScrollView

public class MyScrollView extends ScrollView {
    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false;
    }
}
View Code

  代码:

/**
 * ScrollView listView嵌套,保证listView能够滑动,
 * 这里需要确保,上层View不会拦截onTouch,则重写ScrollView的onInterceptTouchEvent事件,设置 return false;
 */
public class Main2Activity extends AppCompatActivity {

    ListView listView;
    MyScrollView scrollView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();
    }


    public void initView(){
        scrollView= (MyScrollView) findViewById(R.id.scrollView);

        listView= (ListView) findViewById(R.id.listView);
        String [] a=new String[50];
        for(int i=0;i<50;i++){
            a[i]="模仿填充数据"+i;
        }

        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,a);
        listView.setAdapter(adapter);
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

            }
        });


        listView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                return false;
            }
        });



    }
}
View Code

4.实现(2)

  除去重新scrollView我们还可以在listView的onTouch事件中拦截父View的事件分发。

scrollView.requestDisallowInterceptTouchEvent(true);

  布局:一样 需要设置scrollView的属性

android:fillViewport="true"

  看代码:

/**
 * ScrollView  里面嵌套listView,listView 能够滑动展示数据,滑动其他地方,scrollView能够上下滑动
 *
 *   1: 设置scrollView属性fillViewport="true"
 *   2: listView.setOnTouchListener事件中加入:
 *       scrollView.requestDisallowInterceptTouchEvent(true);
         return false;
 */
public class ListActivity extends AppCompatActivity {

    ListView listView;
    ScrollView scrollView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);
        initView();
    }

    public void initView(){
        scrollView= (ScrollView) findViewById(R.id.scrollView);

        listView= (ListView) findViewById(R.id.listView);
        String [] a=new String[50];
        for(int i=0;i<50;i++){
            a[i]="模仿填充数据"+i;
        }

        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,a);
        listView.setAdapter(adapter);
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
           @Override
           public void onScrollStateChanged(AbsListView view, int scrollState) {

           }

           @Override
           public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

           }
       });


     listView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            scrollView.requestDisallowInterceptTouchEvent(true);
            return false;
        }
    });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               String s= (String) parent.getItemAtPosition(position);
                Toast.makeText(ListActivity.this,s,Toast.LENGTH_SHORT).show();
            }
        });


    }
}

  

今天多一点积累,明天少一分烦恼
原文地址:https://www.cnblogs.com/galibujianbusana/p/6656757.html