前言
在app开发中,许多场景需求在有限的规模内显示完整的内容。假如内容自身没有超出控件规模,那么没有任何问题。可是假如内容的长度超过了控件的规模,那么就需求酌情处理了。而跑马灯作用便是处理方式之一。
跑马灯并不是什么新东西,在xml的时代,textview就能够经过简略的特点设置完成作用。不知道用过的xdm有没有跟我相同的感受,便是往往很难一下子完美的完成作用,由于什么焦点啊,行数啊这些特点都会影响到终究的作用并且有些场景需求多个textview按需跑马灯等等这些问题,总之让这个简略的功用完成起来不是那么顺利~
当然啊,好歹xml的方式还是能够完成的。而强大的Compose居然在1.4.0-alpha04版别之前不支撑跑马灯作用!这几天看文档发现从1.4.0-alpha04已经支撑了跑马灯这个或许有点迟来的功用。下面就来一起探究一下Compose的跑马灯完成吧。
最快完成
完成十分简略,调用Modifier.basicMarquee()
即可!不必像之前xml的时分,需求设置焦点行数等。
Text(
modifier = Modifier.padding(padding).basicMarquee(),
text = "套马杆的汉子你威武雄壮!套马杆的汉子你威武雄壮!套马杆的汉子你威武雄壮!套马杆的汉子你威武雄壮!套马杆的汉子你威武雄壮!套马杆的汉子你威武雄壮!套马杆的汉子你威武雄壮!",
)
主页作用是用到了大话Compose炼体(1)-先一餐吃3碗饭 – ()这篇的完成。感兴趣的能够去看看点个赞,这儿主要看Text
的跑马灯作用就好
别的咱们缩减Text的text内容,再来看看
Text(
modifier = Modifier.padding(padding).basicMarquee(),
text = "套马杆的汉子你威武雄壮!",
)
由于这儿的Text的宽没有约束啊,所以是屏幕宽度。那么这儿的控件宽度必定大于内容,发现这是是没有跑马灯作用的
假如咱们再把Text的宽度指定到一个肖小于内容的值示例为50dp
Text(
modifier = Modifier.padding(padding).width(50.dp).basicMarquee(),
text = "套马杆的汉子你威武雄壮!",
)
发现跑马灯作用又呈现了。这儿就不再贴图演示了。
定论:只要内容超出了有限规模才会有跑马灯作用,反之没有!
配合焦点完成跑马灯
考虑到电量优化和性能优化,许多时分让跑马灯无条件并无限时长的运转并不是个好主意。上面提到要完成跑马灯咱们要调用Modifier.basicMarquee
办法。这个办法都有默许参数,所以咱们上面没有传参就能完成了。稍微看了一下参数类型和默许值,发现animationMode
这个字段能够操控跑马灯动画的触发条件
fun Modifier.basicMarquee(
iterations: Int = DefaultMarqueeIterations,
//要害参数
animationMode: MarqueeAnimationMode = Immediately,
delayMillis: Int = DefaultMarqueeDelayMillis,
initialDelayMillis: Int = if (animationMode == Immediately) delayMillis else 0,
spacing: MarqueeSpacing = DefaultMarqueeSpacing,
velocity: Dp = DefaultMarqueeVelocity
): Modifier
//动画模式
value class MarqueeAnimationMode private constructor(private val value: Int) {
override fun toString(): String = when (this) {
Immediately -> "Immediately"
WhileFocused -> "WhileFocused"
else -> error("invalid value: $value")
}
companion object {
/**
*不论有没焦点状态,当即执行
*/
@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
@ExperimentalFoundationApi
@get:ExperimentalFoundationApi
val Immediately = MarqueeAnimationMode(0)
/**
* 只要控件有焦点或者子控件有焦点时才执行
*/
@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
@ExperimentalFoundationApi
@get:ExperimentalFoundationApi
val WhileFocused = MarqueeAnimationMode(1)
}
}
看到这心里就有个完成主意了,经过点击来操控焦点,然后经过是否有焦点来操控跑马灯动画是否运转。对Compose焦点办理不了解的xdm能够花个几分钟看看这篇文章Jetpack Compose中的焦点办理 – ()。
改造代码如下:
//获取并记住焦点请求器,后边用它来请求焦点
val focusRequester = remember { FocusRequester() }
//获取焦点办理器 后边用它来清理焦点
val focusManager = LocalFocusManager.current
//声明一个变量来记录当时是否有焦点
var isFocused = false
Text(
text = "套马杆的汉子你威武雄壮!套马杆的汉子你威武雄壮!",
Modifier
.padding(padding)
.width(200.dp)
//传参 MarqueeAnimationMode.WhileFocused用焦点来操控跑马灯动画
.basicMarquee(animationMode = MarqueeAnimationMode.WhileFocused)
//设置焦点请求器
.focusRequester(focusRequester)
//设置焦点改变监听
.onFocusChanged {
isFocused = it.isFocused
}
//这句必须要有,调用后表明能够被聚集
.focusable()
//设置点击事情
.clickable {
if (isFocused) {
//假如当时有焦点,也便是在跑动画时。清楚焦点,中止动画。
focusManager.clearFocus()
} else {
//假如当时没有焦点,请求焦点,开端动画
focusRequester.requestFocus()
}
},
)
能够看到作用是契合预期的
定论:能够经过焦点来操控动画的起止。失去焦点中止动画,并回到初始的状态而不是动画中止时的状态。
都能跑 才是好的跑马灯
之前大多数场景用到跑马灯,都是Text这种控件。可是Compose的跑马灯是否只能用在Text上呢?答案是“并不是哟”
。一切可组合项都能够用到跑马灯作用!这个便是发挥xdm脑洞的时分了,下面展示一个简略作用:
调快一点速度,默许是30dp,这儿改成了60;削减一点动画头尾的距离,默许是3/1屏幕宽,这儿改成10/1
Row(modifier = Modifier
.padding(padding)
.basicMarquee(velocity =60.dp, spacing = MarqueeSpacing.fractionOfContainer(1f / 10f))) {
Image(painter = painterResource(id = R.drawable.avatar1) , contentDescription = null)
Image(painter = painterResource(id = R.drawable.avatar2) , contentDescription = null)
Image(painter = painterResource(id = R.drawable.avatar3) , contentDescription = null)
Image(painter = painterResource(id = R.drawable.avatar4) , contentDescription = null)
Image(painter = painterResource(id = R.drawable.avatar5) , contentDescription = null)
Image(painter = painterResource(id = R.drawable.avatar6) , contentDescription = null)
}
小结
经过上面的内容,能够发现。在Compose中要完成跑马灯作用十分简略,中心办法便是basicMarquee()
,并且一切可组合项都能够经过Modifier来完成。详细有哪些其他的当地能够用到,这就看我们的想象力了!欢迎留言说说你的主意!