原理见翻页效果原理实现之翻页的尝试



package com.stone.turnpage.view;import android.content.Context;import android.content.res.Configuration;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.os.Handler;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * author : stone * email  : aa86799@163.com * time   : 16/7/8 10 35 */public class HorizonTurnPageView extends View {    private List mBitmaps;    private float mClipX; //裁剪右端点坐标    private float mCurPointX;// 指尖触碰屏幕时点X的坐标值    private float mAutoAreaLeft, mAutoAreaRight; //控件左侧和右侧自动吸附的区域    private boolean mIsLastPage; //是否最后一页    private boolean mIsNextPage; //是否下一页    private int mPageIndex;    private Runnable mMsgCallback;    private Handler mHandler = new Handler();    public HorizonTurnPageView(Context context) {        super(context);//        ViewConfiguration.get(context).getScaledTouchSlop()    }    public void setBitmaps(List bitmaps) {        if (null == bitmaps || bitmaps.size() == 0) return;        this.mBitmaps = bitmaps;        System.out.println("setBitmaps");        invalidate();    }    /**     * 图片倒序:集合中最先加入的图(最后绘制)就能绘制在最上层     */    private void initBitmaps() {        if (mBitmaps == null) {            return;        }        List temp = new ArrayList();        for (int i = mBitmaps.size() - 1; i >= 0; i--) {            Bitmap bitmap = Bitmap.createScaledBitmap(mBitmaps.get(i), getWidth(), getHeight(), true);            temp.add(bitmap);        }        mBitmaps = temp;    }    private void drawBitmaps(Canvas canvas) {/*        for (int i = 0; i < mBitmaps.size(); i++) {//            canvas.save();            if (i == mBitmaps.size() - 1) {//只有最后一位的图片(即原集合中的首图)时才裁剪一次                canvas.clipRect(0, 0, mClipX, getHeight());            }            canvas.drawBitmap(mBitmaps.get(i), 0, 0, null);//            canvas.restore();        }*/        /*        如果图片太多,那么 其实只要绘制上下两张图即可,  而不用 所有都绘制        代码重构如下         */        mIsLastPage = false;        mPageIndex = mPageIndex < 0 ? 0 : mPageIndex;        mPageIndex = mPageIndex > mBitmaps.size() ? mBitmaps.size() : mPageIndex;        // 计算数据起始位置        int start = mBitmaps.size() - 2 - mPageIndex;//mBitmaps.size() - 2 表示倒数第二个        int end = mBitmaps.size() - mPageIndex;   // end - start = 2        /*         * 如果数据起点位置小于0则表示当前已经到了最后一张图片         */        if (start < 0) {            mIsLastPage = true; // 此时mPageIndex = size - 1            showToast("已经最后一页了");            // 强制重置起始位置            start = 0;            end = 1;        }        for (int i = start; i < end; i++) {//end - start = 2   这里最多循环两次            if (!mIsLastPage && i == end - 1) {                canvas.clipRect(0, 0, mClipX, getHeight()); //之后的绘制会相对当前裁剪区            }            canvas.drawBitmap(mBitmaps.get(i), 0, 0, null);        }    }    @Override    public boolean onTouchEvent(MotionEvent event) {        mIsNextPage = true;        switch (event.getAction() & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_DOWN:                mCurPointX = event.getX();                if (mCurPointX < mAutoAreaLeft) {                    mIsNextPage = false; //上一页                    mPageIndex--;                    mClipX = mCurPointX;                    invalidate();                }                break;            case MotionEvent.ACTION_MOVE:                mClipX = event.getX();                invalidate();                break;            case MotionEvent.ACTION_UP:                judgeSlideAuto();                /*                 * 如果当前页不是最后一页                 * 如果是需要翻下一页                 * 并且上一页已被clip掉,即judgeSlideAuto中执行了向左                 */                if (!mIsLastPage && mIsNextPage && mClipX <= 0) {                    mPageIndex++;                    mClipX = getWidth();                    invalidate();                }                break;        }        return true;    }    /**     * 判断是否要自动滑动: 向左或向右 滑动到底     */    private void judgeSlideAuto() {        if (mClipX < mAutoAreaLeft) {// 小于 1/5 w   向左            while (mClipX > 0) {                mClipX--;                invalidate();            }        } else if (mClipX > mAutoAreaRight) {// 大于 4/5 w  向右            while (mClipX < getWidth()) {                mClipX++;                invalidate();            }        }    }    /*    onMeasure后 调用, 如果是ViewGroup型, 在onLayout时又改变了大小才会 再次调用     */    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        System.out.println("onSizeChanged");        initBitmaps();        mClipX = getWidth();        mAutoAreaLeft = getWidth() / 5f;        mAutoAreaRight = getWidth() / 5f * 4;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (null == mBitmaps || mBitmaps.size() == 0) {            return;        }        drawBitmaps(canvas);    }    private void showToast(final Object msg) {        mHandler.removeCallbacksAndMessages(null);        mMsgCallback = new Runnable() {            @Override            public void run() {                Toast.makeText(getContext(), msg.toString(), Toast.LENGTH_SHORT).show();            }        };        mHandler.postDelayed(mMsgCallback, 200);    }}

我的自定义View项目地址: https://github.com/aa86799/MyCustomView (欢迎start&fork)

本文地址:https://github.com/aa86799/MyCustomView/tree/master/turnpage

更多相关文章

  1. 【Android】五种不同的Toast
  2. 相对布局
  3. Android(安卓)之 ImageView(图片组件)
  4. Android(安卓)手势滑动,多点触摸放大缩小图片
  5. 用android:clipChildren来实现红心变大特效
  6. android 图片压缩的方法
  7. ImageView.setScaleType(ImageView.ScaleType)
  8. android 竖屏拍照旋转90度
  9. Android(安卓)调用手机系统照相机拍照

随机推荐

  1. Android(安卓)Adapte中getItemViewType越
  2. Android的闹钟
  3. Android(安卓)限制显示小数点后两位的实
  4. android mediaplayer VideoPlayerManager
  5. Android图片异步加载框架Android-Univers
  6. Android(安卓)BroadcastReceiver动态注册
  7. Android学习笔记之:android更新ui的几种常
  8. android 组件使用()
  9. Android(安卓)Studio 添加另一个页面(Acti
  10. ADB调试命令大全