热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

android幻灯片效果自定义,Android波浪效果自定义View实现

前言最近在Github上看到1139618418大神写了一个波浪效果的View,发现效果非常酷炫,但是代码上有很大的优化空间,就照着思路自

前言

最近在Github上看到@1139618418 大神写了一个波浪效果的View,发现效果非常酷炫,但是代码上有很大的优化空间,就照着思路自己撸了一个。留着以后备用。

需求

实现一个类似于波浪效果的自定义view,并且可以提供一个波浪起伏变化距离的接口。

直接上效果图:

android:layout_width="match_parent"

android:layout_height="500dp"

android:layout_alignParentBottom="true"

app:peakHeight="5dp"

app:waveColor="#ffffff" />

在构造函数中获取xml设置的自定义属性,首先拿到typedArray对象 val ta = context.obtainStyledAttributes(attr, R.styleable.SugarWaveView) ,然后通过在attrs定义好的名称,一个个获取,敲黑板:获取完记得recycle():

constructor(context: Context, attr: AttributeSet) : super(context, attr) {

val ta = context.obtainStyledAttributes(attr, R.styleable.SugarWaveView)

waveColor = ta.getColor(R.styleable.SugarWaveView_waveColor, ContextCompat.getColor(context, R.color.colorPrimaryDark))

waveAlpha = ta.getInt(R.styleable.SugarWaveView_backWaveAlpha, 80)

cycle = ta.getInt(R.styleable.SugarWaveView_cycle, 2)

peakHeight = ta.getDimension(R.styleable.SugarWaveView_peakHeight, 8.0f)

ta.recycle()

}

拿到屏幕的宽度,只有拿到宽度后才知道曲线需要画多长,拿宽度比较合适的时机是在onMeasure之后,在这之前,是拿不到的。

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec)

range = cycle * Math.PI / width // range:周期,决定屏幕内波浪的数量,cycle:常数,通过改变它来改成range,width在java中为getWidth()

}

根据构造函数中拿到的自定义属性,来初始化画笔,mBelowPaint用于画出一个半透明的波浪,看起来有交错感,此处参照了原作者的思路:

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {

super.onLayout(changed, left, top, right, bottom)

mAbovePaint.isAntiAlias = true

mAbovePaint.style = Paint.Style.FILL

mAbovePaint.color = waveColor

mBelowPaint.isAntiAlias = true

mBelowPaint.style = Paint.Style.FILL

mBelowPaint.color = waveColor

mBelowPaint.alpha = waveAlpha

}

OK,下面是最重要的画曲线部分。首先,给定一个初始的初相,画出正弦曲线,正弦曲线的画法为:通过改变x轴的坐标,不断通过y=Asin(ωx+φ)+k来算出y轴坐标。每N个像素算出一个点,将这些点连接起来,此处需要使用到path,然后不断的lineTo(x,y),当点足够密集的时候,看起来就是曲线了。代码如下:

override fun onDraw(canvas: Canvas?) {

super.onDraw(canvas)

canvas!!.drawFilter = drawFilter

mAbovePath.reset()//每次onDraw前初始化path,above为不透明波浪,below为透明的波浪

mBelowPath.reset()

start -= 0.1f//初相

var y1: Float

var y2: Float

mAbovePath.moveTo(left.toFloat(), bottom.toFloat())

mBelowPath.moveTo(left.toFloat(), bottom.toFloat())

for (x in 0..width step 20) {//kotlin写法 java为for(int i&#61;0;i<&#61;getWidth();i&#43;&#61;20)

/**

* 此处根据X不断变化&#xff0c;算出Y的值&#xff0c;得到正弦、余弦曲线的坐标点&#xff0c;最后一个个连接起来

*/

y1 &#61; (peakHeight * Math.cos(range * x &#43; start) &#43; peakHeight &#43; 10).toFloat()

y2 &#61; (peakHeight * Math.sin(range * x &#43; start) &#43; peakHeight).toFloat()

mAbovePath.lineTo(x.toFloat(), y1)

mBelowPath.lineTo(x.toFloat(), y2)

}

val middleY &#61; (peakHeight * Math.cos(range * width/2 &#43; start) &#43; peakHeight).toFloat()

listenr?.onWaveHeightChange(middleY)

mAbovePath.lineTo(right.toFloat(), bottom.toFloat())

mBelowPath.lineTo(right.toFloat(), bottom.toFloat())

canvas.drawPath(mAbovePath, mAbovePaint)

canvas.drawPath(mBelowPath, mBelowPaint)

postInvalidateDelayed(10)//延迟10ms重新绘制

}

然后&#xff0c;通过postInvalidateDelayed来延迟一段时间重新绘制&#xff0c;此时只需改变初相&#xff0c;图像就会得到移动的效果。

最后&#xff0c;定义一个返回中心位置波浪Y轴变化的接口&#xff0c;用于实现其他控件的联动&#xff1a;

interface OnWaveChangeListener{

fun onWaveHeightChange(y:Float)

}

如果使用java实现此自定义view的话&#xff0c;还需要写set各种参数的public 方法&#xff0c;以及setOnWaveChangeListener方法。

到这里就完成了整个自定义View的编写、使用。完整代码及Demo可以在我的Github中查看。如发现有改进之处&#xff0c;望指正&#xff0c;万分感谢&#xff01;



推荐阅读
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
author-avatar
PHP小白
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有