2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > Android初学 自定义View和Layout实现流心雨效果

Android初学 自定义View和Layout实现流心雨效果

时间:2022-05-21 06:39:58

相关推荐

Android初学 自定义View和Layout实现流心雨效果

参考资源:

心形线方程

android 控件动画效果实现

效果图

实现过程

1. 绘制心形并为其添加抖动动画效果

绘制心形采用的是参数方程:

如果需要在xml中使用该View, 设置心形的颜色, 还需要自定义属性:

src/main/res/values/attrs.xml:

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="HeartView"><attr name="heart_color" format="color" /></declare-styleable></resources>

使用自定义属性, 需要在View中去解析, View解析自定义属性一般是在第二种构造函数中.

public class HeartView extends View {// 默认值 宽高和颜色private int mWidth = 50;private int mHeight = 50;private int heartColor = Color.parseColor("#db5860");public HeartView(Context context) {super(context);}public HeartView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);if (context != null) {// 解析xml中的对应属性TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.HeartView);heartColor = ta.getColor(R.styleable.HeartView_heart_color, Color.parseColor("#db5860"));ta.recycle();}}public HeartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public HeartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}@Overridepublic void draw(Canvas canvas) {super.draw(canvas);mHeight = getHeight();mWidth = getWidth();// drawCoordinateSystem(canvas);Paint paint = new Paint();paint.setAntiAlias(true);paint.setColor(heartColor);Path path = new Path();float x = 0, y = 0;path.moveTo((float) mWidth / 2, (float) mHeight / 2);for (int t = 0; t < 10000; t++) {x = (float) getWidth() * 1 / 50 * (float) (16 * Math.pow(Math.sin(t), 3));y =(float) getWidth() * 1 / 50 * (float) (13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t));path.lineTo(x + (float) mWidth / 2, -y + (float) mHeight / 2);}canvas.drawPath(path, paint);}/*** 画坐标系** @param canvas 画布*/private void drawCoordinateSystem(Canvas canvas) {Paint paint = new Paint();paint.setStrokeWidth(5);paint.setColor(Color.parseColor("#263055"));canvas.drawLine(0, (float) mHeight / 2, mWidth, (float) mHeight / 2, paint);canvas.drawLine((float) mWidth / 2, 0, (float) mWidth / 2, mHeight, paint);Path path = new Path();path.addCircle((float) mWidth / 2, (float) mHeight / 2, 10, Path.Direction.CW);path.close();canvas.drawPath(path, paint);}@Overridepublic boolean onTouchEvent(MotionEvent event) {HearTrembleAni hearTrembleAni = new HearTrembleAni();hearTrembleAni.setDuration(1000);hearTrembleAni.setRepeatCount(2);this.startAnimation(hearTrembleAni);return true;}/*** 抖动效果动画** @see <a href="/keke921231/article/details/78889491">android 控件动画效果实现</a>*/static class HearTrembleAni extends Animation {@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {t.getMatrix().setTranslate((float) Math.sin(interpolatedTime * 150) * 2,(float) Math.sin(interpolatedTime * 150) * 2);super.applyTransformation(interpolatedTime, t);}}public void setHeartColor(int heartColor) {this.heartColor = heartColor;}}

心形的绘制效果如下:

2. 自定义Layout

在点击位置添加心形, 同时开启线程控制下落.

public class HeartLayout extends FrameLayout {ExecutorService mExecutorService = new ScheduledThreadPoolExecutor(30);public HeartLayout(@NonNull Context context) {super(context);}public HeartLayout(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public HeartLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public HeartLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}@Overridepublic boolean onTouchEvent(MotionEvent event) {float rawX = event.getX();float rawY = event.getRawY();drawHeart(rawX, rawY);switch (event.getAction()) {case MotionEvent.ACTION_DOWN:drawHeart(rawX, rawY);break;default:break;}return super.onTouchEvent(event);}private void drawHeart(float rawX, float rawY) {HeartView heartView = new HeartView(this.getContext());LayoutParams layoutParams = new LayoutParams(50, 50);layoutParams.topMargin = (int) rawY - 50;layoutParams.leftMargin = (int) rawX - 25;addView(heartView, layoutParams);mExecutorService.execute(() -> {for (int i = 0; i < getHeight(); i += 5) {try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}heartView.setTranslationY(i);}});}}

结束Peace

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。