关于ScrollView中嵌套listview焦点滑动问题 分发事件以及处罚事件

activity_main.xml:

<com.example.ScallView.MyScallView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" 
    
    >

      <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
          <com.example.listview.MyListVeiw
              android:id="@+id/list_view"
                    android:layout_width="match_parent"
        android:layout_height="wrap_content"
              ></com.example.listview.MyListVeiw>
           <Button 
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="改变listview的高"
            />
                    <Button 
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="改变listview的高"
            />
                             <Button 
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="改变listview的高"
            />
                                      <Button 
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="改变listview的高"
            />
                                               <Button 
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="改变listview的高"
            />
                                                        <Button 
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="改变listview的高"
            />
                                                                 <Button 
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="改变listview的高"
            />
      </LinearLayout>
      

</com.example.ScallView.MyScallView>
com.example.ScallView.MyScallView这个类里面主要是自定义ScallView:
package com.example.ScallView;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;

public class MyScallView extends ScrollView{

    public MyScallView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            //判断是否是滑动状态
            boolean b = super.onTouchEvent(ev);
            //触发取消
            int i = MotionEvent.ACTION_CANCEL;
            return b;
        }
//        负责分发事
        public boolean dispatchTouchEvent(MotionEvent ev) {
            // TODO Auto-generated method stub
            //判断是否调用分发事件
            boolean b=super.dispatchTouchEvent(ev);
            return b;
        }
//        onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            // TODO Auto-generated method stub
            boolean b=super.onInterceptTouchEvent(ev);
            return b;
        }
}
com.example.listview.MyListVeiw,自定义listview这个类,
package com.example.listview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;

public class MyListVeiw extends ListView{

    public MyListVeiw(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        boolean b=super.onTouchEvent(ev);
        
        return b;
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        boolean b=super.onInterceptTouchEvent(ev);
        return b;
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        //这行代码的作用是设置listview的滑动,入股没有这行代码,那么listview就不会动
         getParent().requestDisallowInterceptTouchEvent(true);  
        boolean b=super.dispatchTouchEvent(ev);
        return b;
    }
}

MainActivity.class

package com.example.day7_scall_view;

import com.example.listview.MyListVeiw;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.Button;

public class MainActivity extends Activity {

    private MyListVeiw list_view;
    private Button change;
    String [] books=new String[]{"1.0","2.0","3.0","4.0","5.0","1.1","2.2","3.3","4.3","5.5","2.0","3.0","4.0","5.0","1.1","2.2","3.3","4.3","5.5"};
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        init();
        setListViewHeightBasedOnChildren(list_view);
    }
    //根据listview的数据来计算他的应得的高度,设置高度
    private void setListViewHeightBasedOnChildren(MyListVeiw list_view2) {
        ArrayAdapter listviewadapter=(ArrayAdapter) list_view2.getAdapter();
        if(listviewadapter==null){
            return;
        }
        int totalHeight = 0;
        //遍历适配器里面的item项
        for(int i=0;i<listviewadapter.getCount();i++){
            //获得里面view
        View listitem=listviewadapter.getView(i, null, list_view2);
        if(listitem!=null){
            listitem.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
            //该方法指定该控件在屏幕上的大小
            //MeasureSpec.UNSPECIFIED 未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。



            listitem.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED);
            totalHeight+=listitem.getMeasuredHeight();
            
        }
        ViewGroup.LayoutParams parmars=list_view2.getLayoutParams();
        //list_view2.getDividerHeight()设置的是每个Item之间的间隔dividerHeight。
        parmars.height=totalHeight+(list_view2.getDividerHeight()*(listviewadapter.getCount()-1))
        +list_view2.getPaddingTop()+list_view2.getPaddingBottom();
        //获取屏幕的精确高度
        int h=getWindowManager().getDefaultDisplay().getHeight();
        if(parmars.height>h/2){
            parmars.height=h/2;
        }
        list_view2.setLayoutParams(parmars);
        
        }
        
        
        
        
        
        
    }
    private void init() {
        // TODO Auto-generated method stub
        //获取ID
        list_view=(MyListVeiw) findViewById(R.id.list_view);
        change=(Button) findViewById(R.id.change);
        //配置数据
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,books);
        list_view.setAdapter(adapter);
        
        
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

效果图:

原文地址:https://www.cnblogs.com/123p/p/5391458.html