当前位置:网站首页>自定义实现乘风破浪的小船
自定义实现乘风破浪的小船
2022-08-03 10:05:00 【OpenLD】
我在昨天的文章中实现了波纹荡漾的效果,这个效果太千篇一律了,今天试着发散一下,实现一个玻璃球中的水波荡漾效果,其次只有水波荡漾怎么够呢,必须给大家来一艘乘风破浪的帆船吧。这就安排。


如果你没看昨天的文章请先去看看,不然这里怕一头雾水。
首先说下思路,这里重点来了。
1.实现水波局限在玻璃球(圆形)中荡漾效果
我第一下就想到了clipPath(),那你在WaveView的onDraw()之中去clipPath()一个圆形行不行呢,这里当然是可以的。
但是这么做我发现了一个坑,因为水波荡漾要结合属性动画实现,会频繁调用invalidate()重新绘制,那就会频繁触发onDraw(),那其中的clipPath()方法也会频繁被触发,这个方法实际上是切割画布的,开销很大。运行的时候画面会时不时闪动一下,当然不符合预期。
于是,我目前的思路是自定义一个CircleLinearLayout(继承自LinearLayout),在其中clipPath()并把裁剪后的Canvas分发给子View去绘制。这样的话既能裁切出圆形,又能保证频繁的WaveView刷新不会频繁触发clipPath()。
这里暂时没想到在WaveView本身中怎样更优雅地切出圆形,如果大家有思路欢迎交流学习。
2.实现帆船乘风破浪效果
要实现帆船乘风破浪效果太简单了,你就drawBitmap()画一艘帆船吧,计算下位置让其初始位置位于波浪上方,然后还是利用属性动画去设置帆船上下移动,无限循环,那最终结合波浪的翻涌效果,就实现了乘风破浪的帆船。
因为今天的效果都是基于昨天的波浪效果实现的,因此代码也很简单。

相比昨天只多了一个CircleLinearLayout
package com.openld.seniorui.testwave
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.widget.LinearLayout
/**
* author: lllddd
* created on: 2022/8/2 14:12
* description:圆形的线性布局
*/
class CircleLinearLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : LinearLayout(context, attrs) {
private var mWidth = 0;
private var mHeight = 0;
private var mPaint = Paint().apply {
isAntiAlias = true
strokeWidth = 5F
color = Color.parseColor("#6495ed")
style = Paint.Style.STROKE
}
private var mCirclePath = Path()
override fun dispatchDraw(canvas: Canvas?) {
mWidth = measuredWidth
mHeight = measuredHeight
canvas!!.save()
mCirclePath.addCircle(
(mWidth shr 1).toFloat(),
(mHeight shr 1).toFloat(),
(mWidth shr 1).coerceAtMost(mHeight shr 1).toFloat(),
Path.Direction.CCW
)
canvas.clipPath(mCirclePath)
canvas.drawCircle(
(mWidth shr 1).toFloat(),
(mHeight shr 1).toFloat(),
(mWidth shr 1).coerceAtMost(mHeight shr 1).toFloat() - 5F,
mPaint
)
super.dispatchDraw(canvas)
canvas.restore()
}
}然后在调用的页面布局里,WaveView肯定要套在CircleLinearLayout里面
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".testwave.TestWaveActivity">
<com.openld.seniorui.testwave.CircleLinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.openld.seniorui.testwave.WaveView
android:id="@+id/wave_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</com.openld.seniorui.testwave.CircleLinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>页面调用的地方依旧简单得我都不想贴了
package com.openld.seniorui.testwave
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.openld.seniorui.R
class TestWaveActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test_wave)
}
}于是大功告成!!!
边栏推荐
猜你喜欢

redis实现分布式锁的原理

Leecode-SQL 1527. 模糊查询匹配(模糊查询用法)

Regulation action for one hundred days during the summer, more than 700 traffic safety hidden dangers were thrown out

2022年起重机械指挥培训试题模拟考试平台操作

mysql 运行的时候 报错

Oracle 数据如何迁移到MySQL 图文详细教程

cmd(命令行)操作或连接mysql数据库,以及创建数据库与表

报告:想学AI的学生数量已涨200%,老师都不够用了

MySQL的分页你还在使劲的limit?

跨域问题的分析
随机推荐
pytorch安装错误
报告:想学AI的学生数量已涨200%,老师都不够用了
Leecode-SQL 1527. 模糊查询匹配(模糊查询用法)
015-Balanced binary tree (1)
以网强算,中国移动算网建设激发澎湃能量
MySQL——几种常见的嵌套查询
go中select语句
System io statistics
Redis的基础与django使用redis
When deleting a folder, the error "Error ox80070091: The directory is not empty" is reported. How to solve it?
播放量暴涨2000w+,单日狂揽24w粉,内卷的搞笑赛道还有机会
redis实现分布式锁的原理
ClickHouse 数据插入、更新与删除操作 SQL
阿里本地生活全域日志平台 Xlog 的思考与实践
MySQL的主从复制
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之二:编码实现
mysql数据库配置性能调优
C语言二维数组用一维数组进行调用
57.【全排列的详细分析】
This article understands the process from RS485 sensor to IoT gateway to cloud platform