欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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;
 }
}