[置頂] Android自定義組件系列【15】――四個(gè)方向滑動(dòng)的菜單實(shí)現(xiàn)
來(lái)源:程序員人生 發(fā)布時(shí)間:2015-02-27 08:38:36 閱讀次數(shù):3159次
今天無(wú)意中實(shí)現(xiàn)了1個(gè)4個(gè)方向滑動(dòng)的菜單,感覺(jué)挺好玩,滑動(dòng)起來(lái)很順手,既然已做出來(lái)了就貼出來(lái)讓大家也玩弄1下。
1、效果演示
(說(shuō)明:目前沒(méi)有安裝Android摹擬器,制作的動(dòng)態(tài)圖片太卡了,就貼1下靜態(tài)圖片吧,實(shí)際效果可以下載源代碼查看)

(向上滑動(dòng))

(向下滑動(dòng))

(向左滑動(dòng))

(向右滑動(dòng))
2、實(shí)現(xiàn)進(jìn)程介紹
1、放置5個(gè)View (分別是上下左右中)
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mTopView.layout(0, -mViewHeight, mViewWidth, 0);
mBottomView.layout(0, mViewHeight, mViewWidth, 2 * mViewHeight);
mCenterView.layout(0, 0, mViewWidth, mViewHeight);
mLeftView.layout(-mViewWidth, 0, 0, mViewHeight);
mRightView.layout(mViewWidth, 0, 2 * mViewWidth, mViewHeight);
}

轉(zhuǎn)載請(qǐng)說(shuō)明出處:http://blog.csdn.net/dawanganban
2、通過(guò)onTouchEvent事件來(lái)判斷移動(dòng)方向
private float mDownY;
private float mDownX;
@Override
public boolean onTouchEvent(MotionEvent event) {
int disY;
int disX;
float eventY = event.getY();
float eventX = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownY = eventY;
mDownX = eventX;
break;
case MotionEvent.ACTION_UP:
disY = (int)(eventY - mDownY);
disX = (int)(eventX - mDownX);
if(Math.abs(disY) > Math.abs(disX)){
if(Math.abs(disY) > MIN_VIEW_HEIGHT / 2){
if(disY > 0){ //向下滑動(dòng)
Log.d(TAG, "TO_BOTTOM");
changeToBottom();
}else{ //向上滑動(dòng)
Log.d(TAG, "TO_TOP");
changeToTop();
}
}
}else{
if(Math.abs(disX) > MIN_VIEW_WIDTH / 2){
if(disX > 0){ //向右滑動(dòng)
Log.d(TAG, "TO_RIGHT");
changeToRight();
}else{ //向左滑動(dòng)
Log.d(TAG, "TO_LEFT");
changeToLeft();
}
}
}
break;
default:
break;
}
return true;
}
3、通過(guò)computerScroll()方法實(shí)現(xiàn)平滑移動(dòng)
@Override
public void computeScroll() {
super.computeScroll();
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
4、判斷臨界條件(否則會(huì)1直向1個(gè)方向滑動(dòng))
int[] location = new int[2];
mCenterView.getLocationOnScreen(location);
if(location[1] >= mViewHeight - MIN_VIEW_HEIGHT * 2) return;
例如上面代碼就是判斷向下滑動(dòng)的臨界條件,location[1]代表中間View的y坐標(biāo)(相對(duì)屏幕)。
3、全部View的源碼
package com.example.testmx4update;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
/**
* 自定義可以拖動(dòng)的View
* @author 陽(yáng)光小強(qiáng) http://blog.csdn.net/dawanganban
*
*/
public class MyCanPullView extends ViewGroup{
private static final int MIN_VIEW_HEIGHT = 200;
private static final int MIN_VIEW_WIDTH = 400;
private static final String TAG = "TEST";
private int mViewHeight;
private int mViewWidth;
private View mTopView;
private View mBottomView;
private View mCenterView;
private View mLeftView;
private View mRightView;
private Scroller mScroller;
public MyCanPullView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
mScroller = new Scroller(context);
}
private void initView(Context context) {
setTopView(context);
setBottomView(context);
setCenterView(context);
setLeftView(context);
setRightView(context);
}
private float mDownY;
private float mDownX;
@Override
public boolean onTouchEvent(MotionEvent event) {
int disY;
int disX;
float eventY = event.getY();
float eventX = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownY = eventY;
mDownX = eventX;
break;
case MotionEvent.ACTION_UP:
disY = (int)(eventY - mDownY);
disX = (int)(eventX - mDownX);
if(Math.abs(disY) > Math.abs(disX)){
if(Math.abs(disY) > MIN_VIEW_HEIGHT / 2){
if(disY > 0){ //向下滑動(dòng)
Log.d(TAG, "TO_BOTTOM");
changeToBottom();
}else{ //向上滑動(dòng)
Log.d(TAG, "TO_TOP");
changeToTop();
}
}
}else{
if(Math.abs(disX) > MIN_VIEW_WIDTH / 2){
if(disX > 0){ //向右滑動(dòng)
Log.d(TAG, "TO_RIGHT");
changeToRight();
}else{ //向左滑動(dòng)
Log.d(TAG, "TO_LEFT");
changeToLeft();
}
}
}
break;
default:
break;
}
return true;
}
private void changeToBottom(){
int[] location = new int[2];
mCenterView.getLocationOnScreen(location);
if(location[1] >= mViewHeight - MIN_VIEW_HEIGHT * 2) return;
int dy = (int)(mViewHeight - MIN_VIEW_HEIGHT);
mScroller.startScroll(0, getScrollY(), 0, -dy, 500);
invalidate();
}
private void changeToTop(){
int[] location = new int[2];
mTopView.getLocationOnScreen(location);
if(location[1] <= -mViewHeight - MIN_VIEW_HEIGHT / 2) return;
int dy = (int)(mViewHeight - MIN_VIEW_HEIGHT);
mScroller.startScroll(0, getScrollY(), 0, dy, 500);
invalidate();
}
private void changeToRight(){
int[] location = new int[2];
mCenterView.getLocationOnScreen(location);
if(location[0] >= mViewWidth - MIN_VIEW_WIDTH * 2) return;
int dx = (int)(mViewWidth - MIN_VIEW_WIDTH);
mScroller.startScroll(getScrollX(), 0, -dx, 0, 500);
invalidate();
}
private void changeToLeft(){
Log.d(TAG, "TO_LEFT");
int[] location = new int[2];
mLeftView.getLocationOnScreen(location);
if(location[0] <= -mViewWidth - MIN_VIEW_WIDTH / 2) return;
int dx = (int)(mViewWidth - MIN_VIEW_WIDTH);
mScroller.startScroll(getScrollX(), 0, dx, 0, 500);
invalidate();
}
@Override
public void computeScroll() {
super.computeScroll();
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mTopView.layout(0, -mViewHeight, mViewWidth, 0);
mBottomView.layout(0, mViewHeight, mViewWidth, 2 * mViewHeight);
mCenterView.layout(0, 0, mViewWidth, mViewHeight);
mLeftView.layout(-mViewWidth, 0, 0, mViewHeight);
mRightView.layout(mViewWidth, 0, 2 * mViewWidth, mViewHeight);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//獲得全部View的寬高
mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
}
private void setTopView(Context context){
View topButton = new View(context);
topButton.setBackgroundColor(Color.RED);
mTopView = topButton;
this.addView(mTopView);
}
private void setBottomView(Context context){
View bottomButton = new View(context);
bottomButton.setBackgroundColor(Color.GREEN);
mBottomView = bottomButton;
this.addView(mBottomView);
}
private void setCenterView(Context context){
View centerButton = new View(context);
centerButton.setBackgroundColor(Color.WHITE);
mCenterView = centerButton;
this.addView(mCenterView);
}
private void setLeftView(Context context){
View leftButton = new View(context);
leftButton.setBackgroundColor(Color.BLUE);
mLeftView = leftButton;
this.addView(mLeftView);
}
private void setRightView(Context context){
View rightButton = new View(context);
rightButton.setBackgroundColor(Color.YELLOW);
mRightView = rightButton;
this.addView(mRightView);
}
}
獲得全部源代碼,請(qǐng)加群在群同享中獲得(142979499)
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)