安卓学习之解决ScrollView嵌套自定义上拉加载的Listview事件冲突
来源:互联网 发布:沈阳专业seo公司 编辑:程序博客网 时间:2024/04/28 17:27
问题
ScrollView和ListView都具有滑动的功能,如果在ScrollView中嵌套ListView,就会出现滑动时间冲突,那如果非要在ScrollVIew中嵌套ListView,又该怎么做呢?下文将提出一种解决方案,在ScrollView中嵌套上拉加载的ListView。
解决思路
既然我们知道在ScrollView中嵌套ListView会出现滑动事件冲突,所以解决的办法就是对事件的分发拦截等进行处理。
首先我们先自定义一个上拉加载的DropLoadListView,代码如下:
import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.widget.AbsListView;import android.widget.ListView;import com.example.mahui.stop.R;/** * Created by mahui on 16/12/31. * 创建上拉加载的listview */public class DropLoadListView extends ListView implements AbsListView.OnScrollListener { private Context context; private View footer; private int totalItemCount;//总数量 private int lastItemCount;//最后一个 private boolean isLoading;//正在加载 private ILoadListener iLoadListener; public DropLoadListView(Context context) { super(context); this.context = context; initVew(); initEvent(); } /** * 事件监听 */ private void initEvent() { this.setOnScrollListener(this); } public DropLoadListView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; initVew(); initEvent(); } public DropLoadListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.context = context; initVew(); initEvent(); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_MOVE: if(!isLoading){ //上拉 this.requestDisallowInterceptTouchEvent(false); this.getParent().getParent().requestDisallowInterceptTouchEvent(true); }else{ //下滑 this.requestDisallowInterceptTouchEvent(true); this.getParent().getParent().requestDisallowInterceptTouchEvent(false); } break; } return super.onTouchEvent(ev); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if(this.getAdapter().getCount()>1){ if (totalItemCount == lastItemCount && scrollState == SCROLL_STATE_IDLE) { if (!isLoading) { isLoading = true; footer.findViewById(R.id.id_load_progressbar).setVisibility(View.VISIBLE); footer.findViewById(R.id.id_load_text).setVisibility(View.VISIBLE); iLoadListener.onLoad(); //加载更多数据 } } } } /** * @param view * @param firstVisibleItem 当前屏幕上显示的第一个item的位置,初始为0 * @param visibleItemCount 当前屏幕上显示的item数 * @param totalItemCount 总共的item数 */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { this.lastItemCount = firstVisibleItem + visibleItemCount; this.totalItemCount = totalItemCount; } /** * 初始化 */ private void initVew() { LayoutInflater layoutInflater = LayoutInflater.from(context); footer = layoutInflater.inflate(R.layout.load, null); //一开始隐藏 footer.findViewById(R.id.id_load_progressbar).setVisibility(View.GONE); this.addFooterView(footer); } public void setInterface(ILoadListener iLoadListener){ this.iLoadListener=iLoadListener; } /** * 加载更多数据的回调接口 */ public interface ILoadListener{ public void onLoad(); } // 加载完成通知隐藏 public void loadComplete() { isLoading = false; footer.findViewById(R.id.id_load_progressbar).setVisibility(View.GONE); footer.findViewById(R.id.id_load_text).setVisibility(View.GONE); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }}
首先我们得先会自定义上拉加载的ListView,在这里我们不做过多的讲解,我们主要看如下方法:
public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_MOVE: if(!isLoading){ //上拉 this.requestDisallowInterceptTouchEvent(false); this.getParent().getParent().requestDisallowInterceptTouchEvent(true); }else{ //下滑 this.requestDisallowInterceptTouchEvent(true); this.getParent().getParent().requestDisallowInterceptTouchEvent(false); } break; } return super.onTouchEvent(ev); }
该方法是处理触摸事件的,我们通过判断此刻是否是上拉加载,然后进行事件分发处理。在此ListView中,我通过判断totalItemCount == lastItemCount && scrollState == SCROLL_STATE_IDLE是否满足条件,满足则代表我是上拉加载,此时设置isLoading=true,表示要加载,然后在触摸事件中判断是否要加载,如果是,则让当前view对该事件进行拦截,并让ScrollView不要拦截,让当前view消费此事件;如果不是上拉加载,即表示我要滑动整个ScrollView,让当前ListView不拦截,让ScrollView进行拦截,已达到此目的,在该模块处理时,最重要的方法就是requestDisallowInterceptTouchEvent(true),不允许拦截;requestDisallowInterceptTouchEvent(flase),允许拦截;;
效果
- 安卓学习之解决ScrollView嵌套自定义上拉加载的Listview事件冲突
- 安卓解决ScrollView嵌套ListView显示不全、与ViewPager滑动冲突的3个类
- Android之解决scrollview嵌套listview的冲突
- Android中自定义ListView,解决scrollview嵌套listview 滑动事件冲突
- scrollview嵌套listview滑动,上拉刷新,冲突等问题
- 解决ScrollView嵌套ListView的冲突
- 解决scrollView嵌套listview的冲突问题
- ScrollView嵌套ListView冲突的解决
- 解决ScrollView 里面嵌套Listview 的冲突
- Scrollview嵌套listVIew冲突问题的解决
- 解决scrollView嵌套listview 冲突
- scrollview嵌套listView冲突解决
- Android scrollview中嵌套listview实现listview的下拉刷新上拉加载更多
- android解决listview与scrollview的冲突、自定义listview的高度以及上下拉刷新
- ListView,GridView和ScrollVIew嵌套实现上拉加载更多
- ScrollView+TabLayout+ViewPager+ListView复杂滑动嵌套、上拉加载
- ScrollView+TabLayout+ViewPager+ListView复杂滑动嵌套、上拉加载
- 利用事件分发机制解决ScrollView嵌套ListView滑动冲突
- hdu 5971
- cookie 和 session对浏览器
- Strawberry Perl 所有版本链接
- C++虚基类与虚继承
- M
- 安卓学习之解决ScrollView嵌套自定义上拉加载的Listview事件冲突
- springboot+redis作缓存
- Lehmer快速求1e11以内质数个数
- php_network_getaddresses: getaddrinfo failed:Temporary failure in name resolution
- OS常用的调度算法
- hdu 5895
- JDBC-ODBC桥接
- java泛型
- android获取状态栏高度