网站首页 > 技术文章 正文
宗旨都是一样,带大家一起来研究自定义view的实现,与其不同的是本系列省去了简单的坐标之类的讲解,重点在实现思路,用简洁明了的文章,来与大家一同一步步学习。
上一篇介绍了:神奇的贝塞尔曲线,这篇就来研究其应用。
我自己的学习方法是:学习了贝塞尔曲线之后,去研究他的规律,然后开始联想有没有见过类似的效果,最后自己去研究实现,在没有遇到绝对困难的时候,独立思考。只有遇到了绝对困难或者做出来效果之后,才去参考其他人的做法。
好了,废话不多说了,来看看效果图:
图片是从360安全卫士apk里面解压的。一张背景图,一张小绿的图片。
先定义一些属性
private int mWidth; private int mHeight; //线的Y坐标 private int mLineY = 600; //判断是否画线回弹 private boolean isDrawBack = false; private int mBitmapX; private int mBitmapY; //飞行的百分比 private int mFlyPercent = 100; //辅助点坐标 x坐标为线段中点, Point supPoint = new Point(350, mLineY);
首先来画背景图片 ,和小人,这里背景图片大小不对,没想到有什么好的方法,这里先写死(求解决,求不打死)。
Bitmap bitmap = BitmapFactory.decodeResource(getResources, com.wingsofts.my360clean.R.drawable.mb); BitmapFactory.Options opt = new BitmapFactory.Options; opt.inJustDecodeBounds = true; // BitmapFactory.decodeResource(getResources, com.wingsofts.my360clean.R.drawable.t,opt); // int bgWidth = opt.outWidth; // int bgHeight = opt.outHeight; //按线的长度缩放背景图 // Log.e("wing",bgWidth + " " +scale+""); opt.inSampleSize= 2; // opt.outWidth = 500; opt.inJustDecodeBounds = false; Bitmap background =BitmapFactory.decodeResource(getResources, com.wingsofts.my360clean.R.drawable.t,opt); Paint p = new Paint; p.setStyle(Paint.Style.STROKE); p.setStrokeWidth(20); Path path = new Path; //坐标写死微调。。。别打我 canvas.drawBitmap(background,100,mLineY - background.getHeight+100,p); Point endPoint = new Point(600, mLineY);
然后画两个圈圈。
p.setColor(Color.GRAY); canvas.drawCircle(100, endPoint.y, 10, p); canvas.drawCircle(endPoint.x,endPoint.y,10,p);
之后根据一个标记位 isDrawBack来判断是否画线反弹。这里默认是不反弹。
p.setColor(Color.YELLOW); path.moveTo(100, mLineY); path.quadTo(supPoint.x, supPoint.y, endPoint.x, endPoint.y);//绘制贝塞尔曲线, canvas.drawPath(path, p); canvas.drawPoint(supPoint.x, supPoint.y, p); mBitmapX = supPoint.x - bitmap.getWidth / 2; mBitmapY = (supPoint.y -mLineY)/2 + mLineY- bitmap.getHeight; canvas.drawBitmap(bitmap, mBitmapX, mBitmapY, p);
注意上面bitmap的坐标计算,这里为了方便,贝塞尔曲线只画中点的。#实际上是不会# 观察辅助点坐标
猜测辅助点到切线点 和切线点到mLineY的距离相等,然后计算出bitmap所在的坐标,进行绘制。
然后来绘制下拉时候的样子,重写onTouchEvent,主要是改变辅助点坐标和bitmap坐标,在action_move改变坐标 最后通知重绘。重写action_up来改变最重点的坐标, 改变isDrawBack标记位,通知阶段为上弹阶段。
知识补充:getX是相对view的坐标 getRawX是相对屏幕的坐标.
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction) { case MotionEvent.ACTION_MOVE: supPoint.x = (int) event.getX; if(event.getY>mLineY) supPoint.y = (int) event.getY; invalidate; break; case MotionEvent.ACTION_UP: endX = (int) event.getX; endY = (int) event.getY; isDrawBack = true; invalidate; break; } return true; }
最后来绘制回弹的效果,相信看过之前我的文章的都知道我采用一种percent办法。这里给一个参数mFlyPercent,从100开始递减,递减辅助点的y坐标和bitmap的y坐标,来实现动画效果。 如果mFlyPercent<0 则代表绘制完毕 重置标志位和百分比。
if (isDrawBack) { p.setColor(Color.YELLOW); path.moveTo(100, mLineY); path.quadTo(supPoint.x, mLineY + (supPoint.y - mLineY) * mFlyPercent / 100, endPoint.x, endPoint.y); canvas.drawPath(path, p); if(mFlyPercent >0) { canvas.drawBitmap(bitmap, mBitmapX, mBitmapY * mFlyPercent/100, p); mFlyPercent -=5; postInvalidateDelayed(10); }else { mFlyPercent = 100; isDrawBack = false; }
这样,变结束了模仿360内存清理效果,对于x坐标的计算。。。日后再研究。
猜你喜欢
- 2025-06-18 [THE VIEW]下周最受期待十大上线测试新游速递(8月1日-8月5日)
- 2025-06-18 (1图)美军:对作战环境的整体视角(Holistic View)
- 2024-07-31 复盘曼联1-0西汉姆:扭转中场不均衡,小麦的价值不仅是致胜球
- 2024-07-31 「Qt-QML」模型与视图1(草图大师视图拉近时模型被切割掉怎么设置)
- 2024-07-31 1-0!鲁尼转正后赢下首胜,德比郡取胜英冠第三逃离降级区
- 2024-07-31 复盘曼联1-3莱斯特:马蒂奇带来结构性混乱,弗雷德被郁闷打击
- 2024-07-31 Qt编写数据可视化大屏界面电子看板1-布局方案
- 2024-07-31 复盘曼联0-1狼:瘸腿首发让“狼爪”更加锋利,主动失误能出集锦
- 2024-07-31 1-2!1-1!英超Big6仍低迷,上轮集体不胜后两强又翻车
- 2024-07-31 1-1大冷!“小天使”空门打飞,马竞暂无缘128年纪录
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)