ListView的使用
在我们学会使用recyclerview之前,我们一定是在ListView的世界中在挣扎,彷徨,忧郁,困惑,然而,当我们真正的封装好了的话也可以趟过这趟混水,迈入新的天地。
下面就给大家带来我项目中曾经遇到过的ListView的坑,当然你可能也会遇到,并且有了不一样的处理方法,此处仅供已懂的人参考,不懂的人借鉴。
首先给大家发一波我遇到的各类滑动冲突的‘撞车事故’:
处理方法:重写ListView的onMeasure()方法即可,代码如下
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class MyListView extends ListView{
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightSpec;
if (getLayoutParams().height==LayoutParams.WRAP_CONTENT){
heightSpec= MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
}else {
heightSpec=heightMeasureSpec;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
处理方法:重写ScrolView的onMeasure()方法即可,代码如下
注:这里可能设计到SimpleOnGestureListener的使用,此为用户触屏时对各类不同手势处理的类,下一篇文章中将做出对它的详细使用说明,当然,如果你是个老司机,也可以直接百度它,也是有一堆合理的解释和使用说明的 -_-)
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebView;
import android.widget.ScrollView;
import android.widget.Scroller;
/**
* 自定义ScrollView,解决:ScrollView嵌套ViewPager,导致ViewPager不能滑动的问题
*/
public class CustomScrollView extends ScrollView {
private GestureDetector mGestureDetector;
private int Scroll_height = 0;
private int view_height = 0;
protected Field scrollView_mScroller;
private static final String TAG = "CustomScrollView";
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new YScrollDetector());
setFadingEdgeLength(0);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
stopAnim();
}
boolean ret = super.onInterceptTouchEvent(ev);
boolean ret2 = mGestureDetector.onTouchEvent(ev);
return ret && ret2;
}
class YScrollDetector extends SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (Math.abs(distanceY) > Math.abs(distanceX)) {
return true;
}
return false;
}
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
boolean stop = false;
if (Scroll_height - view_height == t) {
stop = true;
}
if (t == 0 || stop == true) {
try {
if (scrollView_mScroller == null) {
scrollView_mScroller = getDeclaredField(this, "mScroller");
}
Object ob = scrollView_mScroller.get(this);
if (ob == null || !(ob instanceof Scroller)) {
return;
}
Scroller sc = (Scroller) ob;
sc.abortAnimation();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
super.onScrollChanged(l, t, oldl, oldt);
}
private void stopAnim() {
try {
if (scrollView_mScroller == null) {
scrollView_mScroller = getDeclaredField(this, "mScroller");
}
Object ob = scrollView_mScroller.get(this);
if (ob == null) {
return;
}
Method method = ob.getClass().getMethod("abortAnimation");
method.invoke(ob);
} catch (Exception ex) {
Log.e(TAG, e.getMessage());
}
}
@Override
protected int computeVerticalScrollRange() {
Scroll_height = super.computeVerticalScrollRange();
return Scroll_height;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed == true) {
view_height = b - t;
}
}
@Override
public void requestChildFocus(View child, View focused) {
if (focused != null && focused instanceof WebView) {
return;
}
super.requestChildFocus(child, focused);
}
/**
* 获取一个对象隐藏的属性,并设置属性为public属性允许直接访问
*
* @return {@link Field} 如果无法读取,返回null;返回的Field需要使用者自己缓存,本方法不做缓存
*/
public static Field getDeclaredField(Object object, String field_name) {
Class<?> cla = object.getClass();
Field field = null;
for (; cla != Object.class; cla = cla.getSuperclass()) {
try {
field = cla.getDeclaredField(field_name);
field.setAccessible(true);
return field;
} catch (Exception e) {
}
}
return null;
}
}
import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* 自定义ViewPager,解决ViewPagger嵌套使用时不滑动问题。
*/
public class HorizontalInnerViewPager extends ViewPager {
/** 触摸时按下的点 **/
PointF downP = new PointF();
/** 触摸时当前的点 **/
PointF curP = new PointF();
public HorizontalInnerViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new XScrollDetector());
}
public HorizontalInnerViewPager(Context context) {
super(context);
mGestureDetector = new GestureDetector(context, new XScrollDetector());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
curP.x = ev.getX();
curP.y = ev.getY();
if(ev.getAction() == MotionEvent.ACTION_DOWN){
downP.x = ev.getX();
downP.y = ev.getY();
getParent().requestDisallowInterceptTouchEvent(true);
}
if(ev.getAction() == MotionEvent.ACTION_MOVE){
getParent().requestDisallowInterceptTouchEvent(true);
}
return super.onTouchEvent(ev);
}
}
**处理方法:
import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
/**
* 自定义ViewPager,解决ViewPagger嵌套使用时不滑动问题。
*/
public class HorizontalInnerViewPager extends ViewPager {
/** 触摸时按下的点 **/
PointF downP = new PointF();
/** 触摸时当前的点 **/
PointF curP = new PointF();
/** 自定义手势**/
private GestureDetector mGestureDetector;
public HorizontalInnerViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new XScrollDetector());
}
public HorizontalInnerViewPager(Context context) {
super(context);
mGestureDetector = new GestureDetector(context, new XScrollDetector());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
curP.x = ev.getX();
curP.y = ev.getY();
if(ev.getAction() == MotionEvent.ACTION_DOWN){
downP.x = ev.getX();
downP.y = ev.getY();
getParent().requestDisallowInterceptTouchEvent(true);
}
if(ev.getAction() == MotionEvent.ACTION_MOVE){
float distanceX = curP.x - downP.x;
float distanceY = curP.y - downP.y;
if(Math.abs(distanceX) > Math.abs(distanceY)){
getParent().requestDisallowInterceptTouchEvent(true);
}else{
getParent().requestDisallowInterceptTouchEvent(false);
}
}
return super.onTouchEvent(ev);
}
private class XScrollDetector extends GestureDetector.SimpleOnGestureListener{
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return (Math.abs(distanceX) > Math.abs(distanceY));
}
}
}
未完待续… …