Android 自定义控件之页面控件操作

     看到网络上有个关于自定的页面控件,但没有实现和用户的交互。根据交互方式的不同,添加方法也多种多样。下面对横向的触碰做个简要说明,这个操作可以在 View里面完成,也可以在View外面完成。为了不修改原来的View代码,本例仅仅从View外部实现该操作,效果如图:

    以下是View的自定义代码,来自 ,详情如下:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class PointPageView extends View {
	
	private int mPageSize;
	private int mPageIndex;
	private int mPointSize;
	private int mPointSpan;
	private int mSelectPointSize;
	private int mStep;
	private int mDisplaySize;
	private int mDisplayIndex;
	private Paint paint;
	
	private void init() {
		mPointSize = 3;
		mSelectPointSize = mPointSize;
		mPointSpan = 3 * mPointSize;
		mStep = 1;
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(Color.WHITE);
	}
	
	public PointPageView(Context context) {
		super(context, null);
		init();
	}
	/**
	 * Used to inflate the Workspace from XML.
	 */
	public PointPageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	public void setPageSize(int pageSize) {
		mPageSize = Math.max(pageSize, 0);
		mDisplaySize = (int)Math.ceil((double)mPageSize / mStep);
		invalidate();
	}
	
	public int getPageSize() {
		return mPageSize;
	}
	
	public void setPageIndex(int pageIndex) {
		mPageIndex = Math.min(Math.max(pageIndex, 0), mPageSize - 1);
		mDisplayIndex = (int)Math.floor((double)mPageIndex / mStep);
		invalidate();
	}
	
	public int getPageIndex() {
		return mPageIndex;
	}
	
	public void setColor(int color) {
		paint.setColor(color);
	}
	
	public void setPointSize(int size) {
		mPointSize = size;
	}
	
	public void setSelectPointSize(int size) {
		mSelectPointSize = size;
	}
	
	public void setPointSpan(int span) {
		mPointSpan = span;
	}
	
	public void setStep(int step) {
		mStep = step;
	}
	
	public int getStep() {
		return mStep;
	}
	
	@Override
	public void draw(Canvas canvas) {
		super.draw(canvas);
		drawAllPoint(canvas);
	}
	
	private void drawAllPoint(Canvas canvas) {
		canvas.save();
		
		final int paddingLeft = mPointSpan;
		final int width = getMeasuredWidth();
		final int height = getMeasuredHeight();
		
		int radius = mPointSize;
		int contentWidth = (radius + paddingLeft) * mPageSize;
		int beginX = (width - contentWidth) / 2;
		int beginY = height / 2;

		for (int i = 0; i < mDisplaySize; i++) {
			if (i == mDisplayIndex) {
				paint.setAlpha(255);
				radius = mSelectPointSize;
			} else {
				paint.setAlpha(128);
				radius = mPointSize;
			}
			canvas.drawCircle(beginX, beginY, radius, paint);
			beginX = beginX + radius + radius + paddingLeft;
		}
		
		canvas.restore();
	}
}

     判断事件的代码比较简单,比较ACTION_DOWN和ACTION_UP之间X方向的值的变化的大小和方向判断是横向向左还是横向向右操作,进而更新自定义View的状态即可,详见代码:

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class CustomizedViewActivity extends Activity implements OnTouchListener {

	private PointPageView pageView;
	
	/** 上次X坐标值 */
	private float lastX;
	
	/** X方向变化的最小有效值 */
	private static float MINIMUM_EFFECTIVE_DISTANCE = 10.0f;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		pageView = new PointPageView(this);
		pageView.setPageSize(5);
		pageView.setColor(Color.GREEN);
		pageView.setSelectPointSize(3);
		pageView.setPointSpan(20);
		pageView.setPageIndex(2);
		
		// 设置触摸监听器
		pageView.setOnTouchListener(this);
		
		setContentView(pageView);

	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 在一次Touch循环中,初始化lastX值
			lastX = event.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			
			break;
		case MotionEvent.ACTION_UP:
			float currentX = event.getX();
			if (currentX - lastX > MINIMUM_EFFECTIVE_DISTANCE) {
				// 向右
				pageView.setPageIndex(getNextPageIndex());
			} else if (currentX - lastX < -MINIMUM_EFFECTIVE_DISTANCE) {
				// 向左
				pageView.setPageIndex(getPrePageIndex());
			}
			break;
		case MotionEvent.ACTION_CANCEL:

			break;
		case MotionEvent.ACTION_OUTSIDE:

			break;
		default:
			break;
		}
		return true;
	}
	
	private int getPrePageIndex() {
		if (pageView != null) {
			int currentPageIndex = pageView.getPageIndex();
			if (currentPageIndex == 0) {
				return currentPageIndex;
			} else {
				return currentPageIndex - 1;
			}
		}
		return 0;
	}
	
	private int getNextPageIndex() {
		if (pageView != null) {
			int count = pageView.getPageSize();
			int currentPageIndex = pageView.getPageIndex();
			if (currentPageIndex == count - 1) {
				return currentPageIndex;
			} else {
				return currentPageIndex + 1;
			}
		}
		return 0;
	}
	
}

    当然,利用MotionEvent中的其它信息可以构建更加复杂的屏幕触摸事件,比如:横向触摸滑动时的速度,加速度,平均速度等!:)

猜你喜欢

转载自wangleyiang.iteye.com/blog/1722879