Android Moveview滑屏移動視圖類完整實例
更新時間:2014年07月24日 15:02:56 投稿:shichen2014
這篇文章主要介紹了Android Moveview滑屏移動視圖類,很有實用價值,需要的朋友可以參考下
本文示例所述程序為一個Android Moveview移動視圖類。其主要實現(xiàn)主屏左右滑屏拖動功能,并適時顯示拖動時候屏幕的顯示情況,該代碼中還包括完整的邏輯。其完整代碼如下:
import android.study.shift.ItemView; import android.study.shift.MainView; import android.study.shift.Moveview; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.View.MeasureSpec; public class Moveview extends ViewGroup{ private final static int TOUCH_STATE_REST = 0; private final static int TOUCH_STATE_MOVING = 1; private final static int MOVE_TO_LEFT = 1; //private final static int MOVE_TO_RIGHT = 2; private final static int MOVE_TO_REST = 0; public final static int MAIN = 0; public final static int LEFT = 1; public final static int RIGHT = 2; private int touch_state = TOUCH_STATE_REST; private int move_state = MOVE_TO_REST; private int now_state = MAIN; private final float WIDTH_RATE = 0.18f; private MainView main_show_view; private ItemView left_show_view; private int min_distance = 30;//此處只是初始化為30 ,其實不起作用 private int screen_w; private int screen_h; private int move_x_v; private boolean isAimationMoving = false; private Handler mHandler = new Handler() { public void handleMessage(Message msg) {//處理消息 synchronized (Moveview.this) {//同步 isAimationMoving = true; int move_change = (int) (screen_w * WIDTH_RATE / 5); int left = main_show_view.getView().getLeft(); if (msg.what == 1) {//主屏在向右拖曳。。。 move(move_change + left);//參數(shù)為拖出來后主屏的坐標(biāo)。 } if (msg.what == 11) { isAimationMoving = false; moveToLeft(false); //滿足可以顯示的要求開始顯示,false只是一個判定條件,以區(qū)別按鈕起的效果 } if (msg.what == 2) {//代表主屏向左在拖曳。。。 move(-1 * move_change + left); } if (msg.what == 12) { isAimationMoving = false; //moveToRight(false); } if (msg.what == 0) { if (now_state == LEFT) {//如果現(xiàn)在已經(jīng)顯示左邊 move(-1 * move_x_v);//那么還原成主屏 } else { move(move_x_v); } } if (msg.what == 10) { isAimationMoving = false; moveToMain(false); } } } }; public Moveview(Context context) { super(context); } public Moveview(Context context, AttributeSet attrs) { super(context, attrs); } public Moveview(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void initView() { if (main_show_view == null) { main_show_view = new MainView(this.getContext(), this); left_show_view = new ItemView(this.getContext()); //right_show_view = new ItemView(this.getContext(), "aaa"); } this.addView(left_show_view.getView()); //this.addView(right_show_view.getView()); this.addView(main_show_view.getView()); } public void initContent() { } public void move(int start) {//本函數(shù)顯示拖動的時候屏幕的顯示情況。 int left = main_show_view.getView().getLeft();//left代表主屏左邊緣的位置坐標(biāo)。 if (now_state == MAIN) { if (left > 0) {//如果屏幕的左邊被移向右,則left變成正數(shù) if (move_state != MOVE_TO_LEFT) { move_state = MOVE_TO_LEFT; } left_show_view.getView().setVisibility(View.VISIBLE);//設(shè)置左邊可見 //right_show_view.getView().setVisibility(View.GONE); } //else if (left < 0) {//如果屏幕的左邊被移向左,則left變成負(fù)數(shù) //if (move_state != MOVE_TO_RIGHT) { // move_state = MOVE_TO_RIGHT; //} //right_show_view.getView().setVisibility(View.VISIBLE); //left_show_view.getView().setVisibility(View.GONE); //} else { move_state = MOVE_TO_REST; } main_show_view.getView().layout(start, 0, start + screen_w, screen_h);//參數(shù)依次為左、上、右、下。 } else { left = (int) (screen_w * WIDTH_RATE);//left為左邊應(yīng)該留出的控件空間,或者主屏左邊應(yīng)該在的位置 if (now_state == RIGHT) { left = -1 * left;//若狀態(tài)是在右邊空出來,則主屏的左邊為負(fù)數(shù) } left = left + start; main_show_view.getView().layout(left, 0, left + screen_w, screen_h); } } @Override protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { if (move_state == MOVE_TO_REST) { if (now_state == MAIN) { int w = (int) (screen_w * WIDTH_RATE);//留下預(yù)定的寬度,顯示各個view的參數(shù)設(shè)置。 main_show_view.getView().layout(0, 0, screen_w, screen_h); left_show_view.getView().layout(0, 0, w, screen_h); } else if (now_state == LEFT) { moveToLeft(false); } else { } } } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { main_show_view.getView().measure(widthMeasureSpec, heightMeasureSpec); left_show_view.getView().measure(MeasureSpec.UNSPECIFIED,//unspecified為未指定的 heightMeasureSpec); left_show_view.setWidth((int) (screen_w * WIDTH_RATE));//設(shè)置view寬度 super.onMeasure(widthMeasureSpec, heightMeasureSpec);//調(diào)用父類的構(gòu)造函數(shù) } private int start_x; private int start_y; private boolean isMoved; public boolean dispatchTouchEvent(MotionEvent ev) {//分發(fā)觸摸消息事件 if (isAimationMoving) { return super.dispatchTouchEvent(ev); } else { int action = ev.getAction(); float x = ev.getX(); float y = ev.getY(); switch (action) { case MotionEvent.ACTION_DOWN: super.dispatchTouchEvent(ev); start_y = (int) y; move_x_v = 0; if (this.touch_state == TOUCH_STATE_REST) { this.touch_state = TOUCH_STATE_MOVING; start_x = (int) x; isMoved = false; move_state = MOVE_TO_REST; } break; case MotionEvent.ACTION_MOVE: int last_y = (int) y; int last_x = (int) x; super.dispatchTouchEvent(ev); if (!isMoved) { if (Math.abs(last_y - start_y) > Math.abs(last_x - start_x)) {//如果Y上面移動的距離大于X上面移動的距離。 super.onTouchEvent(ev); return true; } else {//X移動距離大于Y if (Math.abs(last_x - start_x) > 5) {//X移動距離大于5就被認(rèn)為移動了 isMoved = true; } } } if (isMoved) { if (this.touch_state == TOUCH_STATE_MOVING) { if (Math.abs(last_x - start_x) > 10) {//如果移動的X距離大于10 int left = main_show_view.getView().getLeft(); Log.d("msg", "left:" + left); Log.d("msg", "x:" + last_x); isMoved = true; int move_x = last_x - start_x; if (move_x > 0 && now_state == LEFT) {//方向正確的移動才算是移動的狀態(tài) isMoved = false; break; } if (move_x < 0 && now_state == RIGHT) {//如果現(xiàn)在在顯示右邊,那么再向右移就不反應(yīng)。 isMoved = false; break; } if (move_x < 0 && now_state ==MAIN){//如果現(xiàn)在在主屏,向右移動也是無效的 isMoved = false; break; } if (move_x > 234 && now_state ==MAIN){ isMoved = true;//設(shè)置為true那么移動還是發(fā)生了,break之后還是會在ACTIONUP中起作用 break;//break之后不會執(zhí)行下面的move()語句, } if (move_x < -234 && now_state ==LEFT){ isMoved = true; break; } move(move_x);//以移動的距離為參數(shù)調(diào)用move()實現(xiàn)移動的動態(tài)顯示 } } return false; } break; case MotionEvent.ACTION_UP:// if (this.touch_state == TOUCH_STATE_MOVING) { if (isMoved) { last_x = (int) x; if (Math.abs(last_x - start_x) > min_distance) {// if (now_state == MAIN) { if (move_state == MOVE_TO_LEFT) { this.moveToLeft(false); } } else { this.moveToMain(false); } } else { // if (now_state == MAIN) { this.moveToMain(false); } if (now_state == LEFT) { this.moveToLeft(false); } if (now_state == RIGHT) { //this.moveToRight(false); } } move_state = MOVE_TO_REST; } else { super.dispatchTouchEvent(ev); this.touch_state = TOUCH_STATE_REST; return false;// } } super.onTouchEvent(ev); this.touch_state = TOUCH_STATE_REST; break; } return true; } } public boolean getIsMoved() { return isMoved; } public void moveToLeft(boolean b) { if (!b) { int move_x = (int) (screen_w * WIDTH_RATE); left_show_view.getView().layout(0, 0, screen_w, screen_h); //right_show_view.getView().layout(move_x, 0, move_x * 2, screen_h); main_show_view.getView().layout(move_x, 0, move_x + screen_w, screen_h); now_state = LEFT;//為什么現(xiàn)在又把now_state賦值為left? } // else {//else以及括號中的語句都是為原來的按鈕準(zhǔn)備的。。。 // mHandler.postDelayed(new Runnable() {//一個新的可運行的函數(shù) // // @Override // public void run() { // int move_change = (int) (screen_w * WIDTH_RATE / 5);//五分之一要顯示的寬度 // int left = (int) (screen_w * WIDTH_RATE - main_show_view // .getView().getLeft());//getleft()返回的是主屏左邊緣離左邊的距離 // Message msg = new Message(); // if (left > move_change) {//括號里面不懂,起什么作用? // msg.what = 1; // mHandler.sendMessage(msg); // mHandler.postDelayed(this, 10);//又調(diào)用自己,基本上非要是小于關(guān)系 // } else { // msg.what = 11; // mHandler.sendMessage(msg); // mHandler.removeCallbacks(this); // } // } // }, 0); // } } public void moveToMain(boolean b) { if (!b) { //right_show_view.getView().setVisibility(View.VISIBLE); left_show_view.getView().setVisibility(View.VISIBLE); int w = (int) (screen_w * WIDTH_RATE); main_show_view.getView().layout(0, 0, screen_w, screen_h); left_show_view.getView().layout(0, 0, w, screen_h); now_state = MAIN; } } public void initScreenSize(int w, int h) { this.screen_w = w; this.screen_h = h; Log.d("screen", "screen_w:" + w); this.setKeepScreenOn(true); min_distance = (int) (screen_w / 12.0);//min_distance在這里又被初始化為屏幕的一個比例大小 initView(); initContent(); moveToMain(false); } public int getNowState() { return this.now_state; } }
您可能感興趣的文章:
- Android使用ViewFlipper和GestrueDetector共同實現(xiàn)滑屏效果實例
- Android組件banner實現(xiàn)左右滑屏效果
- Android利用ViewPager實現(xiàn)滑動廣告板實例源碼
- Android 開發(fā)之BottomBar+ViewPager+Fragment實現(xiàn)炫酷的底部導(dǎo)航效果
- Android ViewPager相冊橫向移動的實現(xiàn)方法
- Android 使用viewpager實現(xiàn)無限循環(huán)(定時+手動)
- Android App中使用ViewPager+Fragment實現(xiàn)滑動切換效果
- Android App中ViewPager與Fragment結(jié)合的一些問題解決
- Android App中ViewPager所帶來的滑動沖突問題解決方法
- Android ViewPager無限循環(huán)實現(xiàn)底部小圓點動態(tài)滑動
- Android基礎(chǔ)之使用Fragment控制切換多個頁面
- Android基礎(chǔ)之Fragment與Activity交互詳解
- Android基于ViewPager+Fragment實現(xiàn)左右滑屏效果的方法
相關(guān)文章
Activity透明/半透明效果的設(shè)置transparent(兩種實現(xiàn)方法)
兩種方法實現(xiàn)Activity透明/半透明效果的設(shè)置,代碼思路很有調(diào)理,感興趣的朋友可以參考下,希望本文可以幫助到你2013-02-02Android中分析Jetpack?Compose動畫內(nèi)部的實現(xiàn)原理
這篇文章主要介紹了Android中分析Jetpack?Compose動畫內(nèi)部的實現(xiàn)原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-09-09Android MediaPlayer音頻播放器封裝示例淺析
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內(nèi)置的媒體播放器的服務(wù),如播放音頻,視頻等為了使用MediaPlayer,我們要調(diào)用這個類的靜態(tài)create()方法2023-04-04