ImageVerifierCode 换一换
格式:DOCX , 页数:28 ,大小:226.36KB ,
资源ID:15572673      下载积分:5 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-15572673.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(自定义控件粘性控件DOC.docx)为本站会员(b****6)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

自定义控件粘性控件DOC.docx

1、自定义控件粘性控件DOC自定义控件:粘性控件GooView粘性控件了解几何图形工具的用法掌握画不规则图形的方法应用场景:未读提醒,效果图:绘制一帧的效果画一帧粘性控件的步骤分析 1画一个固定圆 2画一个拖拽圆 3画中间连接部分 将中间连接部分水平放置,四个角的坐标定为固定值,分别标记上点的编号,矩形中心的点为控件点,画曲线时用自定义一个GooView 继承Viewpublic class GooView extends View private Paint paint; public GooView(Context context) this(context,null); public Goo

2、View(Context context, AttributeSet attrs) this(context, attrs,0); public GooView(Context context, AttributeSet attrs, int defStyle) super(context, attrs, defStyle); /初始化画笔 paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.RED); Override protected void onDraw(Canvas canvas) super.on

3、Draw(canvas); /画中间连接部分 Path path = new Path(); /跳到点1,默认为(0f,0f) path.moveTo(250f, 250f); /从点1-点2 画曲线 path.quadTo(150f, 300f, 50f, 250f); /从点2-点3 画直线 path.lineTo(50f, 350f); /从点3-点4 画曲线 path.quadTo(150f, 300f, 250f, 350f); canvas.drawPath(path, paint); /画拖拽圆 canvas.drawCircle(90f, 90f, 16f, paint); /

4、画固定圆 canvas.drawCircle(150f, 150f, 12f, paint); 第20-30 行用Path 画中间曲线部分 第25 行quadTo(x1,y1,x2,y2)方法可以画当前所在点到x2,y2 间的一条曲线,x1,y1 是当前点与x2,y2 间的一个控件点,它的位置决定曲线弯曲的方向和弧度,将GooView 显示到MainActivity 中public class MainActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) requestWind

5、owFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); setContentView(new GooView(this); 贝塞尔曲线二阶贝塞尔曲线,三阶贝塞尔曲线分别给拖拽圆,固定圆的圆心,半径,两个附着点命名,修改GooView 的onDraw()方法protected void onDraw(Canvas canvas) super.onDraw(canvas); /固定圆的两个附着点 PointF mStickPoints = new PointF new PointF(250f, 250f),ne

6、w PointF(250f, 350f) ; /固定圆的两个附着点 PointF mDragPoints = new PointF new PointF(50f, 250f),new PointF(50f, 350f) ; /控制点 PointF mControlPoint = new PointF(150f, 300f); /画中间连接部分 Path path = new Path(); /跳到点1,默认为(0f,0f) path.moveTo(mStickPoints0.x, mStickPoints0.y); /从点1-点2 画曲线 path.quadTo(mControlPoint.x

7、, mControlPoint.y, mDragPoints0.x, mDragPoints0.y); /从点2-点3 画直线 path.lineTo( mDragPoints1.x, mDragPoints1.y); /从点3-点4 画曲线 path.quadTo(mControlPoint.x, mControlPoint.y, mStickPoints1.x, mStickPoints1.y); canvas.drawPath(path, paint); /画拖拽圆 /拖拽圆圆心 PointF mDragCenter = new PointF(90f, 90f); /拖拽圆半径 floa

8、t mDragRadius = 16f; canvas.drawCircle(mDragCenter.x, mDragCenter.y, mDragRadius, paint); /画固定圆 /固定圆圆心 PointF mStickCenter = new PointF(150f, 150f); /固定圆半径 float mStickRadius = 12f; canvas.drawCircle(mStickCenter.x, mStickCenter.y, mStickRadius, paint);第3-14 行替换附着点及控制点 第30-40 行替换拖拽圆及固定圆的圆心及半径 将替换后的变

9、量转换成GooView 的成员变量/ 固定圆圆心PointF mStickCenter = new PointF(150f, 150f);/ 固定圆半径float mStickRadius = 12f;/ 拖拽圆圆心PointF mDragCenter = new PointF(90f, 90f);/ 拖拽圆半径float mDragRadius = 16f;/ 固定圆的两个附着点PointF mStickPoints = new PointF new PointF(250f, 250f), new PointF(250f, 350f) ;/ 固定圆的两个附着点PointF mDragPoin

10、ts = new PointF new PointF(50f, 250f), new PointF(50f, 350f) ;/ 控制点PointF mControlPoint = new PointF(150f, 300f);Overrideprotected void onDraw(Canvas canvas) super.onDraw(canvas); / 画中间连接部分 Path path = new Path(); / 跳到点1,默认为(0f,0f) path.moveTo(mStickPoints0.x, mStickPoints0.y); / 从点1-点2 画曲线 path.qua

11、dTo(mControlPoint.x, mControlPoint.y, mDragPoints0.x, mDragPoints0.y); / 从点2-点3 画直线 path.lineTo(mDragPoints1.x, mDragPoints1.y); / 从点3-点4 画曲线 path.quadTo(mControlPoint.x, mControlPoint.y, mStickPoints1.x, mStickPoints1.y); canvas.drawPath(path, paint); / 画拖拽圆 canvas.drawCircle(mDragCenter.x, mDragCe

12、nter.y, mDragRadius, paint); / 画固定圆 canvas.drawCircle(mStickCenter.x, mStickCenter.y, mStickRadius, paint);拖拽圆和固定圆的圆心和半径已知,角3 的正弦值为两圆心纵坐标之差比上横坐标之差,则角3 的角度可知,则角1 可知,AB,AC 的长度即可计算出来,mDragPoints0的坐标可以计算出来,同理其它三个附着点坐标也可知。mControlPoint 为两圆心连线的中点几何图形工具/* * 几何图形工具 */public class GeometryUtil /* * As meanin

13、g of method name. * 获得两点之间的距离 * param p0 * param p1 * return */ public static float getDistanceBetween2Points(PointF p0, PointF p1) float distance = (float) Math.sqrt(Math.pow(p0.y - p1.y, 2) + Math.pow(p0.x - p1.x, 2); return distance; /* * Get middle point between p1 and p2. * 获得两点连线的中点 * param p1

14、 * param p2 * return */ public static PointF getMiddlePoint(PointF p1, PointF p2) return new PointF(p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f); /* * Get point between p1 and p2 by percent. * 根据百分比获取两点之间的某个点坐标 * param p1 * param p2 * param percent * return */ public static PointF getPointByPercent(Po

15、intF p1, PointF p2, float percent) return new PointF(evaluateValue(percent, p1.x , p2.x), evaluateValue(percent, p1.y , p2.y); /* * 根据分度值,计算从start 到end 中,fraction 位置的值。fraction 范围为0 - 1 * param fraction * param start * param end * return */ public static float evaluateValue(float fraction, Number st

16、art, Number end) return start.floatValue() + (end.floatValue() - start.floatValue() * fraction; /* * Get the point of intersection between circle and line. * 获取通过指定圆心,斜率为lineK 的直线与圆的交点。 * * param pMiddle The circle center point. * param radius The circle radius. * param lineK The slope of line which

17、 cross the pMiddle. * return */ public static PointF getIntersectionPoints(PointF pMiddle, float radius, DoublelineK) PointF points = new PointF2; float radian, xOffset = 0, yOffset = 0; if(lineK != null) radian= (float) Math.atan(lineK); xOffset = (float) (Math.sin(radian) * radius); yOffset = (flo

18、at) (Math.cos(radian) * radius); else xOffset = radius; yOffset = 0; points0 = new PointF(pMiddle.x + xOffset, pMiddle.y - yOffset); points1 = new PointF(pMiddle.x - xOffset, pMiddle.y + yOffset); return points; 利用几何图形工具类计算四个附着点坐标及控件点坐标protected void onDraw(Canvas canvas) super.onDraw(canvas); float

19、 yOffset = mStickCenter.y - mDragCenter.y; float xOffset = mStickCenter.x - mDragCenter.x; Double lineK = null; if(xOffset != 0) /xOffset 分母不能为0 lineK = (double) (yOffset/xOffset); /计算四个附着点 mDragPoints = GeometryUtil.getIntersectionPoints(mDragCenter, mDragRadius, lineK); mStickPoints = GeometryUtil

20、.getIntersectionPoints(mStickCenter, mStickRadius, lineK); /一个控制点 mControlPoint = GeometryUtil.getMiddlePoint(mDragCenter, mStickCenter); / 画中间连接部分 Path path = new Path(); / 跳到点1,默认为(0f,0f) path.moveTo(mStickPoints0.x, mStickPoints0.y); / 从点1-点2 画曲线 path.quadTo(mControlPoint.x, mControlPoint.y, mDra

21、gPoints0.x, mDragPoints0.y); / 从点2-点3 画直线 path.lineTo(mDragPoints1.x, mDragPoints1.y); / 从点3-点4 画曲线 path.quadTo(mControlPoint.x, mControlPoint.y, mStickPoints1.x, mStickPoints1.y); canvas.drawPath(path, paint); / 画拖拽圆 canvas.drawCircle(mDragCenter.x, mDragCenter.y, mDragRadius, paint); / 画固定圆 canvas

22、.drawCircle(mStickCenter.x, mStickCenter.y, mStickRadius, paint);第3-17 行计算四个附着点及控制点坐标1.4 计算固定圆半径GooView 重写onSizeChanged()方法,计算状态栏高度Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) super.onSizeChanged(w, h, oldw, oldh); /获取状态栏的高度,传入一个显示在屏幕上的view 即可 statusBarHeight = Utils.getSta

23、tusBarHeight(this);Utils.Javapublic class Utils public static Toast mToast; public static void showToast(Context mContext, String msg) if (mToast = null) mToast = Toast.makeText(mContext, , Toast.LENGTH_SHORT); mToast.setText(msg); mToast.show(); /* * 获取状态栏高度 * * param v * return */ public static in

24、t getStatusBarHeight(View v) if (v = null) return 0; Rect frame = new Rect(); v.getWindowVisibleDisplayFrame(frame); return frame.top; 修改onDraw()方法protected void onDraw(Canvas canvas) super.onDraw(canvas); float yOffset = mStickCenter.y - mDragCenter.y; float xOffset = mStickCenter.x - mDragCenter.x

25、; Double lineK = null; if(xOffset != 0) /xOffset 分母不能为0 lineK = (double) (yOffset/xOffset); /计算四个附着点 mDragPoints = GeometryUtil.getIntersectionPoints(mDragCenter, mDragRadius, lineK); mStickPoints = GeometryUtil.getIntersectionPoints(mStickCenter, mStickRadius, lineK); /一个控制点 mControlPoint = Geometr

26、yUtil.getMiddlePoint(mDragCenter, mStickCenter); /移动画布 canvas.save(); canvas.translate(0, -statusBarHeight); / 画中间连接部分 Path path = new Path(); / 跳到点1,默认为(0f,0f) path.moveTo(mStickPoints0.x, mStickPoints0.y); / 从点1-点2 画曲线 path.quadTo(mControlPoint.x, mControlPoint.y, mDragPoints0.x, mDragPoints0.y);

27、/ 从点2-点3 画直线 path.lineTo(mDragPoints1.x, mDragPoints1.y); / 从点3-点4 画曲线 path.quadTo(mControlPoint.x, mControlPoint.y, mStickPoints1.x, mStickPoints1.y); canvas.drawPath(path, paint); / 画拖拽圆 canvas.drawCircle(mDragCenter.x, mDragCenter.y, mDragRadius, paint); / 画固定圆 canvas.drawCircle(mStickCenter.x, m

28、StickCenter.y, mStickRadius, paint); canvas.restore();第18-20 行把画布向上移动状态栏的高度,移动前需要保存一下当前状态,做完操作后需要恢复一下状态,由于在onTouchEvent()中用的是getRawX(),getRawY()获取的是相对屏幕的坐标,所以GooView画图操作时需要向上移到一个状态栏的高度才能刚好和手指重合拖拽圆跟随手指移动时,随着拖拽与固定圆的距离的变大,固定圆的半径越来越小/允许的最大距离float farestDistance = 80f;/* * 通过两圆圆心的距离,计算固定圆的半径 * return */p

29、rivate float computeStickRadius() /通过几何图形工具类可以计算出两圆圆心的距离,distance 是可以大于80f; float distance = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter); /需要的是0.0f - 1.0f 的值,所在大于80f 让distance 等于80f distance = Math.min(farestDistance, distance); float percent = distance/farestDistance; /需要固定圆心半径在12f - 3f 间变化,可以利用类型估值器 return evaluate(percent, mStickRadius, mStickRadius*0.25f);/FloatEvaluator.java 中拷贝public Float evaluate(float fraction, Number startValue, Number endValue) float startFloat = startValue.floatValue(); return startFloat + fraction * (endValue.floatValue() - startFloa

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2