package com.com.mr_wrong.CustomView.PageTurnView;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Mr_Wrong on 15/10/17.
*/
public class PageTurnView extends View {
private static final float TEXT_SIZE_NORMAL = 1 / 40F, TEXT_SIZE_LARGER = 1 / 20F;// 标准文字尺寸和大号文字尺寸的占比
private List<Bitmap> mBitmaps;
private TextPaint mTextPaint;// 文本画笔
private Context mContext;// 上下文环境引用
private int mViewWidth, mViewHeight;// 控件宽高
private float mTextSizeNormal, mTextSizeLarger;// 标准文字尺寸和大号文字尺寸
private float mClipX;// 裁剪右端点坐标
private int pageIndex;// 当前显示mBitmaps数据的下标
private float mAutoAreaLeft, mAutoAreaRight;// 控件左侧和右侧自动吸附的区域
private float mCurPointX;// 指尖触碰屏幕时点X的坐标值
private float mMoveValid;// 移动事件的有效距离
private boolean isNextPage, isLastPage;// 是否该显示下一页、是否最后一页的标识值
public PageTurnView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
/*
* 实例化文本画笔并设置参数
*/
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.LINEAR_TEXT_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// 获取控件宽高
mViewWidth = w;
mViewHeight = h;
// 初始化位图数据
initBitmaps();
// 计算文字尺寸
mTextSizeNormal = TEXT_SIZE_NORMAL * mViewHeight;
mTextSizeLarger = TEXT_SIZE_LARGER * mViewHeight;
// 初始化裁剪右端点坐标
mClipX = mViewWidth;
}
@Override
protected void onDraw(Canvas canvas) {
/*
* 如果数据为空则显示默认提示文本
*/
if (null == mBitmaps || mBitmaps.size() == 0) {
defaultDisplay(canvas);
return;
}
// 绘制位图
drawBtimaps(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 每次触发TouchEvent重置isNextPage为true
isNextPage = true;
/*
* 判断当前事件类型
*/
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:// 触摸屏幕时
// 获取当前事件点x坐标
mCurPointX = event.getX();
/*
* 如果事件点位于回滚区域
*/
if (mCurPointX < mAutoAreaLeft) {
// 那就不翻下一页了而是上一页
isNextPage = false;
pageIndex--;
mClipX = mCurPointX;
invalidate();
}
break;
case MotionEvent.ACTION_MOVE:// 滑动时
float SlideDis = mCurPointX - event.getX();
if (Math.abs(SlideDis) > mMoveValid) {
// 获取触摸点的x坐标
mClipX = event.getX();
invalidate();
}
break;
case MotionEvent.ACTION_UP:// 触点抬起时
// 判断是否需要自动滑动
judgeSlideAuto();
/*
* 如果当前页不是最后一页
* 如果是需要翻下一页
* 并且上一页已被clip掉
*/
if (!isLastPage && isNextPage && mClipX <= 0) {
pageIndex++;
mClipX = mViewWidth;
invalidate();
}
break;
}
return true;
}
private void judgeSlideAuto() {
/*
* 如果裁剪的右端点坐标在控件左端十分之一的区域内,那么我们直接让其自动滑到控件左端
*/
if (mClipX < mAutoAreaLeft) {
while (mClipX > 0) {
mClipX--;
invalidate();
}
}
/*
* 如果裁剪的右端点坐标在控件右端十分之一的区域内,那么我们直接让其自动滑到控件右端
*/
if (mClipX > mAutoAreaRight) {
while (mClipX < mViewWidth) {
mClipX++;
invalidate();
}
}
}
private void drawBtimaps(Canvas canvas) {
// 绘制位图前重置isLastPage为false
isLastPage = false;
// 限制pageIndex的值范围
pageIndex = pageIndex < 0 ? 0 : pageIndex;
pageIndex = pageIndex > mBitmaps.size() ? mBitmaps.size() : pageIndex;
// 计算数据起始位置
int start = mBitmaps.size() - 2 - pageIndex;
int end = mBitmaps.size() - pageIndex;
/*
* 如果数据起点位置小于0则表示当前已经到了最后一张图片
*/
if (start < 0) {
// 此时设置isLastPage为true
isLastPage = true;
// 并显示提示信息
// showToast("This is fucking lastest page");
// 强制重置起始位置
start = 0;
end = 1;
}
for (int i = start; i < end; i++) {
canvas.save();
/*
* 仅裁剪位于最顶层的画布区域
* 如果到了末页则不在执行裁剪
*/
if (!isLastPage && i == end - 1) {
canvas.clipRect(0, 0, mClipX, mViewHeight);
}
canvas.drawBitmap(mBitmaps.get(i), 0, 0, null);
canvas.restore();
}
}
public synchronized void setBitmaps(List<Bitmap> mBitmaps) {
if (null == mBitmaps || mBitmaps.size() == 0)
throw new IllegalArgumentException("no bitmap to display");
if (mBitmaps.size() < 2)
throw new IllegalArgumentException("fuck you and fuck to use imageview");
this.mBitmaps = mBitmaps;
invalidate();
}
private void initBitmaps() {
List<Bitmap> temp = new ArrayList<Bitmap>();
for (int i = mBitmaps.size() - 1; i >= 0; i--) {
Bitmap bitmap = Bitmap.createScaledBitmap(mBitmaps.get(i), mViewWidth, mViewHeight, true);
temp.add(bitmap);
}
mBitmaps = temp;
}
private void defaultDisplay(Canvas canvas) {
canvas.drawColor(Color.WHITE);
// 绘制标题文本
mTextPaint.setTextSize(mTextSizeLarger);
mTextPaint.setColor(Color.RED);
canvas.drawText("FBI WARNING", mViewWidth / 2, mViewHeight / 4, mTextPaint);
// 绘制提示文本
mTextPaint.setTextSize(mTextSizeNormal);
mTextPaint.setColor(Color.BLACK);
canvas.drawText("Please set data use setBitmaps method", mViewWidth / 2, mViewHeight / 3, mTextPaint);
}
}