Android Moveview滑屏移动视图类完整实例

本文示例所述程序为一个Android Moveview移动视图类。其主要实现主屏左右滑屏拖动功能,并适时显示拖动时候屏幕的显示情况,该代码中还包括完整的逻辑。其完整代码如下:

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);//参数为拖出来后主屏的坐标。 } if (msg.what == 11) { isAimationMoving = false; moveToLeft(false); //满足可以显示的要求开始显示,false只是一个判定条件,以区别按钮起的效果 } 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) {//如果现在已经显示左边 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) {//本函数显示拖动的时候屏幕的显示情况。 int left = main_show_view.getView().getLeft();//left代表主屏左边缘的位置坐标。 if (now_state == MAIN) { if (left > 0) {//如果屏幕的左边被移向右,则left变成正数 if (move_state != MOVE_TO_LEFT) { move_state = MOVE_TO_LEFT; } left_show_view.getView().setVisibility(View.VISIBLE);//设置左边可见 //right_show_view.getView().setVisibility(View.GONE); } //else if (left < 0) {//如果屏幕的左边被移向左,则left变成负数 //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);//参数依次为左、上、右、下。 } else { left = (int) (screen_w * WIDTH_RATE);//left为左边应该留出的控件空间,或者主屏左边应该在的位置 if (now_state == RIGHT) { left = -1 * left;//若状态是在右边空出来,则主屏的左边为负数 } 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);//留下预定的宽度,显示各个view的参数设置。 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));//设置view宽度 super.onMeasure(widthMeasureSpec, heightMeasureSpec);//调用父类的构造函数 } private int start_x; private int start_y; private boolean isMoved; public boolean dispatchTouchEvent(MotionEvent ev) {//分发触摸消息事件 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就被认为移动了 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) {//方向正确的移动才算是移动的状态 isMoved = false; break; } if (move_x < 0 && now_state == RIGHT) {//如果现在在显示右边,那么再向右移就不反应。 isMoved = false; break; } if (move_x < 0 && now_state ==MAIN){//如果现在在主屏,向右移动也是无效的 isMoved = false; break; } if (move_x > 234 && now_state ==MAIN){ isMoved = true;//设置为true那么移动还是发生了,break之后还是会在ACTIONUP中起作用 break;//break之后不会执行下面的move()语句, } if (move_x < -234 && now_state ==LEFT){ isMoved = true; break; } move(move_x);//以移动的距离为参数调用move()实现移动的动态显示 } } 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;//为什么现在又把now_state赋值为left? } // else {//else以及括号中的语句都是为原来的按钮准备的。。。 // mHandler.postDelayed(new Runnable() {//一个新的可运行的函数 // // @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);//又调用自己,基本上非要是小于关系 // } 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; } }

时间: 2024-07-31 08:39:58

Android Moveview滑屏移动视图类完整实例的相关文章

Android Moveview滑屏移动视图类完整实例_Android

本文示例所述程序为一个Android Moveview移动视图类.其主要实现主屏左右滑屏拖动功能,并适时显示拖动时候屏幕的显示情况,该代码中还包括完整的逻辑.其完整代码如下: import android.study.shift.ItemView; import android.study.shift.MainView; import android.study.shift.Moveview; import android.content.Context; import android.os.H

PHP时间类完整实例(非常实用)_php技巧

本文实例讲述了PHP时间类.分享给大家供大家参考,具体如下: <?php header("Content-type:text/html;Charset=utf-8"); class time{ private $year;//年 private $month;//月 private $day;//天 private $hour;//小时 private $minute;//分钟 private $second;//秒 private $microtime;//毫秒 private

php文件上传类完整实例_php技巧

本文实例讲述了php文件上传类.分享给大家供大家参考,具体如下: /** $file=new class_file($file_array,"flash/"); $file->set_allow_type(array("jpg","jpeg","gif")); $file->is_limit_size(); if(!$file->allow_file_size()){ echo $file->error

php自定义分页类完整实例_php技巧

本文实例讲述了php自定义分页类.分享给大家供大家参考,具体如下: <?php header("Content-type:text/html;Charset=utf-8"); class SubPages{ private $each_disNums;//每页显示的条目数 private $nums;//总条目数 private $current_page;//当前被选中的页 private $sub_pages;//每次显示的页数 private $pageNums;//总页数

php封装的smartyBC类完整实例_php实例

本文实例讲述了php封装的smartyBC类.分享给大家供大家参考,具体如下: <?php /** * Project: Smarty: the PHP compiling template engine * File: SmartyBC.class.php * SVN: $Id: $ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Les

一个简洁实用的PHP缓存类完整实例_php技巧

本文完整描述了一个简洁实用的PHP缓存类,可用来检查缓存文件是否在设置更新时间之内.清除缓存文件.根据当前动态文件生成缓存文件名.连续创建目录.缓存文件输出静态等功能.对于采用PHP开发CMS系统来说,离不开对缓存的处理,合理利用好缓存可有效的提高程序执行效率. php缓存类文件完整代码如下: <?php /* * 缓存类 cache */ class cache { //缓存目录 var $cacheRoot = "./cache/"; //缓存更新时间秒数,0为不缓存 var

php封装的单文件(图片)上传类完整实例_php技巧

本文实例讲述了php封装的单文件(图片)上传类.分享给大家供大家参考,具体如下: <?php //封装php中的单文件(图片)上传类 /* //参数1:$file 文件数组 5个属性值 name,type,size,tmp,error //参数2:文件保存的路径$path //参数3:文件上传允许的类型 $allow数组 $allow=array('image/jpeg','image/jpg','image/png','image/gif') //参数4: 允许文件上传的最大大小 $size

php封装的smarty类完整实例_php实例

本文实例讲述了php封装的smarty类.分享给大家供大家参考,具体如下: <?php /** * Project: Smarty: the PHP compiling template engine * File: Smarty.class.php * SVN: $Id: Smarty.class.php 4848 2014-06-08 18:12:09Z Uwe.Tews@googlemail.com $ * This library is free software; you can re

php封装的page分页类完整实例_php技巧

本文实例讲述了php封装的page分页类.分享给大家供大家参考,具体如下: 类文件: <?php //分页工具类 class Page{ /* * 获取分页字符串 * @param1 string $uri,分页要请求的脚本url * @param3 int $counts,总记录数 * @param4 int $length,每页显示的记录数 * @param5 int $page = 1,当前页码 * @return string,带有a标签的,可以点击发起请求的字符串 */ public