标签:validate prot sap set 问题 mic miss enter lob
看了Aige的 Android翻页效果原理实现之引入折线if (!mRegionShortSize.contains((int)mTouchX, (int)mTouchY)) { /* 如果不在则通过x坐标强行重算y坐标 通过圆的标准方程: (x-a)^2+(y-b)^2=r^2 (a,b)为圆心 r为半径 x,y为圆弧上的一点 y - b = Math.sqrt(r^2 - (x-a)^2) => y = Math.sqrt(r^2 - (x-a)^2) + b 或 -(y - b) = Math.sqrt(r^2 - (x-a)^2) => y = -1 * Math.sqrt(r^2 - (x-a)^2) + b */ // mTouchY = (float) (Math.sqrt((Math.pow(mW, 2) - Math.pow(mTouchX, 2))) + mH); // 明显值大于mH,不对 mTouchY = (float) (-1 * Math.sqrt((Math.pow(mW, 2) - Math.pow(mTouchX, 2))) + mH); }这样算出来的mTouchY即是圆的轨迹上的对应横坐标的纵坐标值
package com.stone.turnpage.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.graphics.Region; import android.os.Build; import android.support.annotation.RequiresApi; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * author : stone * email : aa86799@163.com * time : 16/9/20 11 18 * * 折线翻页 */ public class FoldTurnPageView extends View { private float mTouchX, mTouchY; private Path mPath; private Paint mPaint; private int mW, mH; private Region mRegionShortSize; public FoldTurnPageView(Context context) { this(context, null); } public FoldTurnPageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FoldTurnPageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPath = new Path(); mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(10); mRegionShortSize = new Region(); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public FoldTurnPageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public boolean onTouchEvent(MotionEvent event) { mTouchX = event.getX(); mTouchY = event.getY(); System.out.println(mTouchY); if (!mRegionShortSize.contains((int)mTouchX, (int)mTouchY)) { /* 如果不在则通过x坐标强行重算y坐标 通过圆的标准方程: (x-a)^2+(y-b)^2=r^2 (a,b)为圆心 r为半径 x,y为圆弧上的一点 y - b = Math.sqrt(r^2 - (x-a)^2) => y = Math.sqrt(r^2 - (x-a)^2) + b 或 -(y - b) = Math.sqrt(r^2 - (x-a)^2) => y = -1 * Math.sqrt(r^2 - (x-a)^2) + b */ // mTouchY = (float) (Math.sqrt((Math.pow(mW, 2) - Math.pow(mTouchX, 2))) + mH); mTouchY = (float) (-1 * Math.sqrt((Math.pow(mW, 2) - Math.pow(mTouchX, 2))) + mH); } invalidate(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: break; } return true; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mW = getMeasuredWidth(); mH = getMeasuredHeight(); computeShortSizeRegion(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPath.reset(); float k = mW - mTouchX; float l = mH - mTouchY; float c = (float) (Math.pow(k, 2) + Math.pow(l, 2)); float x = c / (2 * k); float y = c / (2 * l); mPath.moveTo(mTouchX, mTouchY); //O点 mPath.lineTo(mW - x, mH); //A点 mPath.lineTo(mW, mH - y); //B点 mPath.close(); mPaint.setColor(Color.RED); canvas.drawPath(mPath, mPaint); mPaint.setColor(Color.GREEN); mPath.reset(); mPath.addCircle(0, mH, mW, Path.Direction.CCW); canvas.drawPath(mPath, mPaint); } /** * 计算短边的有效区域 */ private void computeShortSizeRegion() { // 短边圆形路径对象 Path pathShortSize = new Path(); // 添加圆形到Path pathShortSize.addCircle(0, mH, mW, Path.Direction.CCW); RectF bounds = new RectF(); pathShortSize.computeBounds(bounds, true); //region.setPath 参数Region clip, 用于裁剪 mRegionShortSize.setPath(pathShortSize, new Region((int)bounds.left, (int)bounds.top, (int)bounds.right, (int)bounds.bottom)); } }
package com.stone.turnpage.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.graphics.Region; import android.os.Build; import android.os.Handler; import android.os.Message; import android.support.annotation.IntDef; import android.support.annotation.RequiresApi; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * author : stone * email : aa86799@163.com * time : 16/9/20 11 18 * <p> * 折线翻页 */ public class FoldTurnPageView extends View { private float mTouchX, mTouchY; private float mTouchUpX, mTouchUpY;//touch-up 时点的坐标 private Path mPath; private Paint mPaint; private int mW, mH; private Region mRegionShortSize; private int mBuffArea = 20; //底部缓冲区 private float mAutoAreaRight, mAutoAreaBottom, mAutoAreaLeft; private boolean mIsSlide; //是否自动滑动 private static final int LEFT_BOTTOM = 1; //左下 private static final int RIGHT_BOTTOM = 2; //右下 @IntDef({LEFT_BOTTOM, RIGHT_BOTTOM}) @Retention(RetentionPolicy.SOURCE) private @interface SlideDirection {} @SlideDirection private int mSlide; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (!mIsSlide) { return; } if (mSlide == RIGHT_BOTTOM && mTouchX < mW) {//向下滑动 mTouchX += 10; /* 根据直线方程公式:(y-y1)/(y2-y1)=(x-x1)/(x2-x1) y=y1+(x-x1)*(y2-y1)/(x2-x1) mTouchUpX <==> x1 mTouchUpY <==> y1 mW <==> x2 mH <==> y2 不断变化的点 mTouchX <==> x mTouchY <==> y */ mTouchY = mTouchUpY + (mTouchX - mTouchUpX) * (mH - mTouchUpY) / (mW - mTouchUpX); invalidate(); sendMessageDelayed(obtainMessage(0), 25); } else if (mSlide == LEFT_BOTTOM && mTouchX > -mW) {//向左滑动 mTouchX -= 40; mTouchY = mTouchUpY + (mTouchX - mTouchUpX) * (mH - mTouchUpY) / (-mW - mTouchUpX); invalidate(); sendMessageDelayed(obtainMessage(0), 25); } else { slideStop(); } } }; public FoldTurnPageView(Context context) { this(context, null); } public FoldTurnPageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FoldTurnPageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPath = new Path(); mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(10); mRegionShortSize = new Region(); // setLayerType(LAYER_TYPE_SOFTWARE, null); //关闭硬件加速 api11以上 在manifest中关闭 } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public FoldTurnPageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); mTouchX = x; mTouchY = y; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mHandler.removeMessages(0); invalidate(); break; case MotionEvent.ACTION_MOVE: invalidate(); break; case MotionEvent.ACTION_UP: if (x > mAutoAreaRight && y > mAutoAreaBottom) { mSlide = RIGHT_BOTTOM; startSlide(x, y); } else if (x < mAutoAreaLeft) { mSlide = LEFT_BOTTOM; startSlide(x, y); } break; } return true; } private void startSlide(float x, float y ) { mIsSlide = true; mTouchUpX = x; mTouchUpY = y; mHandler.sendEmptyMessage(0); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mW = getMeasuredWidth(); mH = getMeasuredHeight(); computeShortSizeRegion(); mAutoAreaRight = mW / 4 * 3; mAutoAreaBottom = mH / 4 * 3; mAutoAreaLeft = mW / 8; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // canvas.clipRegion(mRegionShortSize); canvas.drawColor(Color.parseColor("#d8ccaa00")); if (!mRegionShortSize.contains((int) mTouchX, (int) mTouchY)) { /* 如果不在则通过x坐标强行重算y坐标 通过圆的标准方程: (x-a)^2+(y-b)^2=r^2 (a,b)为圆心 r为半径 x,y为圆弧上的一点 y - b = Math.sqrt(r^2 - (x-a)^2) => y = Math.sqrt(r^2 - (x-a)^2) + b 或 -(y - b) = Math.sqrt(r^2 - (x-a)^2) => y = -1 * Math.sqrt(r^2 - (x-a)^2) + b */ // mTouchY = (float) (Math.sqrt((Math.pow(mW, 2) - Math.pow(mTouchX, 2))) + mH); // 使用这个明显值偏大 比mH大 mTouchY = (float) (-1 * Math.sqrt((Math.pow(mW, 2) - Math.pow(mTouchX, 2))) + mH); } /* 缓冲区域判断 当B点不在PB线上,而在屏幕上方之外,这时mTouchX, 偏左 此时 mTouchY 越接近mH , 折线出的就不能形成?AOB了 而是一个矩形 */ float area = mH - mBuffArea; if (mTouchY >= area && !mIsSlide) { mTouchY = area; } float k = mW - mTouchX; float l = mH - mTouchY; float c = (float) (Math.pow(k, 2) + Math.pow(l, 2)); float x = c / (2 * k); float y = c / (2 * l); mPath.reset(); mPath.moveTo(mTouchX, mTouchY); //O点 if (y > mH) {//B点超出屏幕上端 //计算,BN边 float bn = y - mH; //MN=BN/BD*OD float mn = bn / (y - (mH - mTouchY)) * (mW - mTouchX); //QN=BN/BP*AP float qn = bn / y * x; mPath.lineTo(mW - mn, 0); //M点 mPath.lineTo(mW - qn, 0); //Q点 mPath.lineTo(mW - x, mH); //A点 在底部 } else { mPath.lineTo(mW, mH - y); //B点 在右部 mPath.lineTo(mW - x, mH); //A点 在底部 } mPath.close(); mPaint.setColor(Color.RED); canvas.drawPath(mPath, mPaint); mPaint.setColor(Color.GREEN); mPath.reset(); mPath.addCircle(0, mH, mW, Path.Direction.CCW); canvas.drawPath(mPath, mPaint); } /** * 计算短边的有效区域 */ private void computeShortSizeRegion() { // 短边圆形路径对象 Path pathShortSize = new Path(); // 添加圆形到Path pathShortSize.addCircle(0, mH, mW, Path.Direction.CCW); RectF bounds = new RectF(); pathShortSize.computeBounds(bounds, true); //region.setPath 参数Region clip, 用于裁剪 boolean flag = mRegionShortSize.setPath(pathShortSize, new Region((int) bounds.left, (int) bounds.top, (int) bounds.right, (int) bounds.bottom)); // boolean flag = mRegionShortSize.setPath(pathShortSize, new Region(0, 1920-1080, 500, 1920)); // System.out.println(bounds + ",," + flag); // System.out.println(mRegionShortSize); } /** * 为isSlide提供对外的停止方法便于必要时释放滑动动画 */ public void slideStop() { mIsSlide = false; } }
if (y > mH) {//B点超出屏幕上端 //计算,BN边 float bn = y - mH; //MN=BN/BD*OD float mn = bn / (y - (mH - mTouchY)) * (mW - mTouchX); //QN=BN/BP*AP float qn = bn / y * x; mPath.lineTo(mW - mn, 0); //M点 mPath.lineTo(mW - qn, 0); //Q点 mPath.lineTo(mW - x, mH); //A点 在底部 /* 生成包含折叠和下一页的路径 OMNPA 五点 */ mPathFoldAndNext.lineTo(mW - mn, 0); //M mPathFoldAndNext.lineTo(mW, 0); //N mPathFoldAndNext.lineTo(mW, mH); //P mPathFoldAndNext.lineTo(mW - x, mH); //A } else { mPath.lineTo(mW, mH - y); //B点 在右部 mPath.lineTo(mW - x, mH); //A点 在底部 /* 生成包含折叠和下一页的路径 OBPA 四点 */ mPathFoldAndNext.lineTo(mW, mH - y); //B点 在右部 mPathFoldAndNext.lineTo(mW, mH); //P点 mPathFoldAndNext.lineTo(mW - x, mH); //A点 在底部 }
标签:validate prot sap set 问题 mic miss enter lob
原文地址:http://blog.csdn.net/jjwwmlp456/article/details/52598387