Android 开发笔记 折叠动画效果

实现左右两个页面,左边页面作为右边的附属页,并且可以拖动缩放左边的页面,左边的页面有纸张折叠的动画效果。

 

由于android系统的动画只有默认的4种,即:移动、缩放、旋转、拉伸(倾斜),无法满足折叠的要求。

这些动画都是一个时间段执行完的,动画开始后,无需再操作,直到动画完成,这里的折叠需要有点击屏幕拖动的折叠效果。

根据上述4种动画的原理(其中拉伸比较相仿),都是需要View对象重新执行onDraw方法重新画图。

我们可以获取右边页面的图片效果,再把这张图重新按需要重新画出来。但是对一张图的拉伸无法达到折叠效果,由于折叠效果图是对称的两个梯形组成的,我们可以分别画两个梯形来实现。

实际步骤:

1.获取左边页面的图形,把图形按左右两个分为两个图形。

2.在左边页面上面再添加一个View,设为V1,即覆盖一个View,用于画梯形。

3.在最顶层添加一个View,用于监听onTouch事件

4.当onTouch事件移动时,缩放左边的页面宽度,这时会自动触发V1的onDraw事件。

获取左边图形的方法,

private Bitmap getBitmap() {
  int width = this.getWidth();
  int height = this.getHeight();
  Bitmap returnedBitmap = null;
  if (width > 0 && height > 0)
    returnedBitmap = getBitmapFromView(r1, width, height);
  return returnedBitmap;
}

private Bitmap getBitmapFromView(View view, int width, int height) {
  int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
  int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
  view.measure(widthSpec, heightSpec);
  view.layout(0, 0, width, height);
  Bitmap bitmap = new WeakReference<Bitmap>(Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)).get();
  Canvas canvas = new Canvas(bitmap);
  view.draw(canvas);
  return bitmap;
}

创建左右两个图形的方法

private Bitmap getBitmapLeftOrRight(Bitmap bitmap, boolean isLeft) {
  Bitmap returnedBitmap = null;
  if (bitmap == null)
    return returnedBitmap;
  int width = bitmap.getWidth();
  int height = bitmap.getHeight();
  returnedBitmap = Bitmap.createBitmap(bitmap, isLeft ? 0 : width / 2, 0, width / 2, height);
  return returnedBitmap;
}

添加View,V1

view = new View(context) {
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    drawBitmap(canvas);
  }
};

view.setBackgroundColor(Color.BLACK);

r1.addView(view);

顶层添加View,监听onTouch事件

l2 = new View(context);
l2.setOnTouchListener(new OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      isAutoMove = false;
      isOpen = r1.getWidth() > 0;
      lastX = event.getX();
      resultMove = (isOpen && lastX > riwidth - 50) || (!isOpen && lastX < 100);
      isMove = false;
      break;
    case MotionEvent.ACTION_MOVE:
      isMove = true;
      xvalue = event.getX() - lastX;
      move();
      break;
    case MotionEvent.ACTION_UP:
      autoMove();
      break;
  }
  lastX = event.getX();
  return resultMove;
}
});
addView(l2);

 

private void move() {
  int width = r1.getWidth();
  if (width <= riwidth && width >= 0) {
    initeBitmap();
    setView(true);
    setR1Width();
  }
}

 

private void drawBitmap(Canvas canvas) {
  if (this.isMove) {
    int width = r1.getWidth();
    drawBitmap(canvas, true, width);
    drawBitmap(canvas, false, width);
  }
}

private void setR1Width() {
  if (r1 == null || !isMove)
    return;
  int width = r1.getWidth() + (int) xvalue;
  if (width < 0)
    width = 0;
  if (width > riwidth)
    width = riwidth;
  ViewGroup.LayoutParams param = r1.getLayoutParams();
  param.width = width;
  r1.setLayoutParams(param);
}

private void drawBitmap(Canvas canvas, boolean isLeft, int width) {
  Bitmap image = isLeft ? bitmapLeft : bitmapRight;

  if (image == null)
  return;
  int WIDTH = image.getWidth();
  int HEIGHT = image.getHeight();
  Matrix headingMatrix = new Matrix();
  int p1x = 0;
  int p1y = 0;
  int p2x = WIDTH;
  int p2y = p1y;
  int p3x = p2x;
  int p3y = HEIGHT;
  int p4x = p1x;
  int p4y = p3y;
  float[] src = new float[]{p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y};

  int flat_height = (int)(FLAT_HEIGHT * (1 - (double)width / riwidth));
  p1x = isLeft ? 0 : width / 2;
  p1y = isLeft ? 0 : flat_height;
  p2x = isLeft ? width / 2 : width;
  p2y = isLeft ? flat_height : 0;
  p3x = p2x;
  p3y = isLeft ? HEIGHT - flat_height : HEIGHT;
  p4x = p1x;
  p4y = isLeft ? HEIGHT : HEIGHT - flat_height;

  float[] dst = new float[]{p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y};
  headingMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
  canvas.drawBitmap(image, headingMatrix, solidPaint);
}

转载于:https://www.cnblogs.com/linvaluable/archive/2013/05/02/3049152.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值