Android Moveview滑屏移动视图类完整实例
程序员文章站
2023-02-02 11:46:14
本文示例所述程序为一个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; } }
上一篇: android双缓冲技术实例详解