当前位置:首页 » 《关注互联网》 » 正文

Android jetpack compose 创建新拟态风格控件_m0_37508087的博客

27 人参与  2021年09月06日 08:43  分类 : 《关注互联网》  评论

点击全文阅读


前几天开发新程序的时候,选择了jetpack最新的组件compose来构建应用程序的界面。但是因为compose面世不久,网上基本找不到太多相关的资料,想找一个新拟态风格的控件库但是找不到,也就只能自己写一个。

效果图:

 这里以输入框为例,其他的空间做成新拟态的原理是一样的。

一、原理

其实新拟态的原理是很简单的,大致就是给控件加两个阴影,显示出光线明暗的变化,如上图所示,左上加的是白色的阴影,右下加的是灰色的阴影。

二、面临的困难

在compose里面,api实际上是进一步封装的,改变控件的modifier与阴影相关的api只有:

@Stable
public fun Modifier.shadow(
    elevation: Dp,
    shape: Shape,
    clip: Boolean
): Modifier

这样一个。

看到elevation这个单词,应该不会感到陌生,这种阴影效果就是在Android5.0,apiLevel 21引入material design时引入的效果。

这种阴影效果只会出现在控件的右下角,没办法在控件的任意位置添加阴影,而且这种阴影效果是没办法指定颜色的。比如下图中按键的阴影:

 三、实现的思路

可能谷歌官方也知道compose的功能比现有Android framework的功能还是稍显羸弱,所以在绘图方面,compose的Canvas是可以直接借助底层的Android framework绘图工具来绘制的。也就是:

public inline fun DrawScope.drawIntoCanvas(
    block: (Canvas) → Unit
): Unit

这个api来调用底层的canvas,然后使用画笔,设置好阴影相关的底层属性,然后在canvas上面绘制两个阴影。

四、效果实现

修改控件的外观需要用到Modifier,所以一般习惯把实现封装成Modifier的扩展函数:

@RequiresApi(Build.VERSION_CODES.O)
fun Modifier.drawColoredShadow(
    color: Color,
    alpha: Float = 0.2f,
    borderRadius: Dp = 0.dp,
    shadowRadius: Dp = 20.dp,
    offsetX: Dp = 0.dp,
    offsetY: Dp = 0.dp,
    roundedRect: Boolean = true
) = this.drawBehind {
    
}

其中参数的含义:

color:阴影的颜色;

alpha:阴影的不透明度;

borderRadius:绘制的圆角矩形阴影的圆角半径;

shadowRadius:阴影所使用的高斯模糊算法的模糊半径,这里高斯模糊算法,就是把一个点的色彩用周围一定范围内的图像的色彩来取均值(或者加权均值)。这个范围的大小就是半径了。

offsetX:阴影在水平方向的偏移,大于零则向右偏移,小于零则向左。

offsetY:阴影在竖直方向的偏移,大于零则向下偏移,小于零则向上。

roundedRect:是否两边都是半圆的圆角矩形。

之所以这个地方调用了this.drawBehind,是因为底层Android framework里面的阴影是依附于图形的。也就是说,设置好了阴影,你只有画一个图形,才能显示出图形的阴影。而我们并不想让这个图形显示出来而且不让它影响控件的触发事件,所以这个时候就要调用drawBehind把阴影依附的图形绘制到控件的下面(z轴方向,类似于前端css里面的after伪类)。

首先初始化两个颜色,一个是阴影依附的图形的颜色,这个地方为了不显示出来,这里直接把不透明度alpha值设置为0f,第二个是阴影的颜色:

val transparentColor = android.graphics.Color.toArgb(color.copy(alpha = .0f).value.toLong())
    val shadowColor = android.graphics.Color.toArgb(color.copy(alpha = alpha).value.toLong())

然后调用drawIntoCanvas来调用底层android framework的canvas:

this.drawIntoCanvas {
        
    }

在drawIntoCanvas里面,初始化一个画笔对象:

val paint = Paint()
        val frameworkPaint = paint.asFrameworkPaint()

设置好画笔颜色和阴影效果:

frameworkPaint.color = transparentColor
        frameworkPaint.setShadowLayer(
            shadowRadius.toPx(),
            offsetX.toPx(),
            offsetY.toPx(),
            shadowColor
        )

上面这段代码中的setShadowLayer就是Android 底层设置阴影的api,第一个参数是阴影的半径,第二个是水平偏移,第三个是竖直偏移,第四个是阴影的颜色。

最后用画笔在canvas上面画一个跟控件尺寸一样,而且透明的图形,阴影就显示出来了:

it.drawRoundRect(
            0f,
            0f,
            this.size.width,
            this.size.height,
            if(roundedRect) this.size.height / 2 else borderRadius.toPx(),
            if(roundedRect) this.size.height / 2 else borderRadius.toPx(),
            paint
        )

在需要新拟态风的控件Modifier上调用这个扩展函数即可:

TextField(value = password, onValueChange = { password = it }, modifier = Modifier
                        .fillMaxWidth()
                        .background(Color.Transparent)
                        .padding(horizontal = 30.dp)
                        .drawColoredShadow(
                            Color.Black,
                            0.1f,
                            borderRadius = 25.dp,
                            shadowRadius = 10.dp,
                            offsetX = passwordAnimation.value.dp,
                            offsetY = passwordAnimation.value.dp
                        )
                        .drawColoredShadow(
                            Color.White,
                            0.9f,
                            borderRadius = 25.dp,
                            shadowRadius = 10.dp,
                            offsetX = (-passwordAnimation.value).dp,
                            offsetY = (-passwordAnimation.value).dp
                        )
                )


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/27097.html

阴影  控件  偏移  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 高冷校草捂不热,热恋竹马他悔了!(岑梨傅辞衍)_高冷校草捂不热,热恋竹马他悔了!(岑梨傅辞衍)
  • 月亮近在咫尺小说无删减阅读无干扰(周既明高凌)番外+续集
  • 嫡姐抢亲,她转身嫁王爷夺江山后续(云七夕单连城)(嫡姐抢亲,她转身嫁王爷夺江山)整本畅享在线+无广告结局
  • 冒充新帝皇嫂,被强制爱了续集(冒充新帝皇嫂,被强制爱了)章节前文+全书阅读(冯幼萤萧仰)最新连载
  • 完结文假装失忆后,我终于才知道谁最爱我列表_完结文假装失忆后,我终于才知道谁最爱我(夏晚夏柠)
  • 商业联姻没感情,咦?不对劲!(黎夏贺聿琛)全书免费_(黎夏贺聿琛)商业联姻没感情,咦?不对劲!后续(黎夏贺聿琛)
  • 全球高武我的召唤兽画风清奇列表_全球高武我的召唤兽画风清奇(叶青青李娜)
  • 小妻不乖:坏坏老公,晚上见小说完本章节前文+全篇阅读(盛司珩沈繁星)连载中
  • 高分_他死后春风难渡(顾骁萧若姗)(他死后春风难渡)全本完整阅读
  • 替身新娘撕毁婚约后,冷情总裁红了眼(季凉城许清颜),替身新娘撕毁婚约后,冷情总裁红了眼
  • 将我妖丹剜给心上人后,他哭瞎双眼求我原谅(戚竹月慕轻尘)_将我妖丹剜给心上人后,他哭瞎双眼求我原谅戚竹月慕轻尘
  • 全民船娘我的船娘全是BUG级!(郑郝周航)_全民船娘我的船娘全是BUG级!郑郝周航

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1