经常写自定义滚动的Layout ,总是出问题,这次备份一下刚写的可以滑动的Layout,让新手看一下也让自己忘记的时候翻阅一下。这是一个完整的自定义类,可以替换activity中的主视图 使用。
package com.yp.customscrollerview;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.Toast;
public class CustomView extends RelativeLayout {
private Context context;
private FrameLayout leftView;
private FrameLayout midView;
private FrameLayout rightView;
Toast toast;
public CustomView(Context context) {
super(context);
init(context);
}
private void showToast(Context contxt, String text, int len) {
if (toast == null)
toast = new Toast(contxt);
toast.setDuration(len);
toast.setText(text);
toast.show();
}
private void show(String text) {
Log.i("test", text);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
Scroller mScroller;
private void init(Context context) {
mScroller = new Scroller(context, new DecelerateInterpolator());
this.context = context;
leftView = new FrameLayout(context);
leftView.setBackgroundColor(Color.RED);
midView = new FrameLayout(context);
midView.setBackgroundColor(Color.GREEN);
rightView = new FrameLayout(context);
rightView.setBackgroundColor(Color.RED);
leftView.setId(0x123);
addView(leftView);
addView(midView);
addView(rightView);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
midView.measure(widthMeasureSpec, heightMeasureSpec);
int realWidth = MeasureSpec.getSize(widthMeasureSpec);
int tempWidthMeasure = MeasureSpec.makeMeasureSpec(
(int) (realWidth * 0.8f), MeasureSpec.EXACTLY);
leftView.measure(tempWidthMeasure, heightMeasureSpec);
rightView.measure(tempWidthMeasure, heightMeasureSpec);
show("width:" + leftView.getMeasuredWidth() + "rightvieww:"
+ rightView.getMeasuredWidth());
}
//
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
midView.layout(l, t, r, b);
leftView.layout(l - leftView.getMeasuredWidth(), t, l, b);
rightView.layout(l + midView.getMeasuredWidth(), t,
r + rightView.getMeasuredWidth(), b);
show("___width:" + leftView.getMeasuredWidth() + "rightvieww:"
+ rightView.getMeasuredWidth());
}
//
private boolean isTestCompete = false;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (!isTestCompete) {
getEventType(ev);
return true;
}
if (is_event) {
show("++++++++++++++++++++++++++");
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
// int curScrollX = getScrollX();
// show(curScrollX+"");//
// // showToast(context, "__" + curScrollX + "", 0);
// int dis_x = (int) (ev.getX() - point.x);
// int xx = -dis_x + curScrollX;
// int finalX = 0;
// show("dis_x: "+dis_x+"xx: "+xx+"scroll :"+curScrollX);
// if (xx < 0) {
// finalX = Math.max(xx, -leftView.getMeasuredWidth());
// } else {
// finalX = Math.min(xx, rightView.getMeasuredWidth());
//
// }
// show("finalX: "+finalX+"");
// scrollTo(-200, 0);
// point.x = (int) ev.getX();
int curScrollX = getScrollX();
show("scroll" + curScrollX);
int dis_x = (int) (ev.getX() - point.x);
int expectX = -dis_x + curScrollX;
int finalX = 0;
show("dis_x: " + dis_x + "expectX: " + expectX + " "
+ leftView.getMeasuredWidth());
if (expectX < 0) {
finalX = Math.max(expectX, -leftView.getMeasuredWidth());
} else {
finalX = Math.min(expectX, rightView.getMeasuredWidth());
}
show("finalX: " + finalX);
scrollTo(finalX, 0);
point.x = (int) ev.getX();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
curScrollX = getScrollX();
if (Math.abs(curScrollX) > leftView.getMeasuredWidth() >> 1) {
if (curScrollX < 0) {
mScroller.startScroll(curScrollX, 0,
-leftView.getMeasuredWidth() - curScrollX, 0,
200);
} else {
mScroller.startScroll(curScrollX, 0,
leftView.getMeasuredWidth() - curScrollX, 0,
200);
}
} else {
mScroller.startScroll(curScrollX, 0, -curScrollX, 0, 200);
}
invalidate();
is_event = false;
isTestCompete = false;
break;
}
} else {
is_event = false;
isTestCompete = false;
}
return super.dispatchTouchEvent(ev);
}
private Point point = new Point();
final int TEST_DIS = 20;
boolean is_event;
private void getEventType(MotionEvent ev) {
show("+++++++++++getEventType+++++++++++++++");
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
point.x = (int) ev.getX();
point.y = (int) ev.getY();
super.dispatchTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
int dX = (int) Math.abs(ev.getX() - point.x);
int dY = (int) Math.abs(ev.getY() - point.y);
if (dX >= TEST_DIS && dX > dY) {
// 左右滑动
is_event = true;
isTestCompete = true;
point.x = (int) ev.getX();
point.y = (int) ev.getY();
} else if (dY >= TEST_DIS && dY > dX) {
// 上下滑动
is_event = false;
isTestCompete = true;
point.x = (int) ev.getX();
point.y = (int) ev.getY();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
super.dispatchTouchEvent(ev);
is_event = false;
isTestCompete = false;
break;
}
}
@Override
public void computeScroll() {
super.computeScroll();
if (!mScroller.computeScrollOffset()) {
return;
}
int tempX = mScroller.getCurrX();
scrollTo(tempX, 0);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return super.onTouchEvent(event);
}
// class Point{
// public int x;
// public int y;
// }
}