还是老规矩,小图镇楼~
小厂开发而言,日常的繁杂的业务开发任务相对较重,有些东西,首次遇到,后续也不想再浪费时间。
一直想做一个积累,一个笔记,一个总结,将日常开发中遇到的小细节记录在案,方便查阅,也能方便帮助其他小伙伴~
还是没等到掘金上线图片水印开关,先发文,后更新啦~
有不对地方欢迎大佬指点~
假设 UI 仅提供中间沙发 logo,如何构建如下 UI 效果图?
首先构建外层圆形背景图:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="@dimen/dimen_90_dp"
android:height="@dimen/dimen_90_dp" />
<solid android:color="@color/color_2d0d52" />
</shape>
合并生成一张图:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_circle_2d0d52" />
<item
android:drawable="@drawable/ic_guard_sofa"
android:gravity="center" />
</layer-list>
文字描述不是很清晰,直接看效果图吧:
注意观察,只有底部没有边框~
先实现底层 shape:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dimen_20_dp" />
<gradient
android:angle="120"
android:endColor="@color/color_cf77de_00"
android:startColor="@color/color_b573d8"
android:type="linear" />
</shape>
效果如下:
随后编辑上层 shape:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dimen_20_dp" />
<gradient
android:angle="180"
android:endColor="@color/color_5a13a2"
android:startColor="@color/color_6f1e94"
android:type="linear" />
</shape>
效果如下:
两者结合,孕育新生:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_b573d8_00cf77de" />
<item
android:bottom="-2dp"
android:drawable="@drawable/shape_6f1e94_5a13a2"
android:left="@dimen/dimen_1_dp"
android:right="@dimen/dimen_1_dp"
android:top="@dimen/dimen_1_dp" />
</layer-list>
fun adjustKtvImChatInParentRoot(imChatView: View) {
val layoutParams = imChatView.layoutParams
if (layoutParams is ConstraintLayout.LayoutParams) {
layoutParams.reset() // 重置布局参数
layoutParams.topToTop = R.id.imChatSpace
layoutParams.bottomToBottom = R.id.imChatSpace
layoutParams.startToEnd = R.id.imChatSpace
}
}
fun resetVIPPosition(csRoot: ConstraintLayout) = ConstraintSet().apply { // 动态设置约束的合集
clone(csRoot) // 克隆父布局约束
clear(R.id.vip_view_fl, END) // 移除指定约束
connect(R.id.vip_view_fl, TOP, R.id.view_flipper, BOTTOM, 10.dp) // top_bottom margin 10
}.applyTo(csRoot) // 应用约束
简单说下步骤吧:
xml 布局中通过如下设置比例:
app:layout_constraintDimensionRatio="900:1170"
代码中则可以通过如下方式:
ConstraintSet().apply {
clone(prettyParentCl) <--- 根布局 id
setDimensionRatio(
R.id.buyPrettyNumIv, <--- 要调整的 View Id
if (mIsBindPrettyNum) "900:990" else "900:1170" <--- 调整后的比例
)
}.applyTo(prettyParentCl) <--- 根布局 id
xml 设置滑动方向:
android:scrollbars="vertical"
代码中设置 mode:
textView.movementMethod = ScrollingMovementMethod.getInstance()
如下图所示:
实现重点:
findViewById<TextView>(R.id.comm_indicator_txt).apply {
paint.isFakeBoldText = true // 加粗
}
setTextColor(ContextCompat.getColorStateList(context, [selector resid]))
Way 1: 通过 setCompoundDrawables 方式
private fun TextView.setCardOperateDrawable(resId: Int) {
val drawable = ContextCompat.getDrawable(mContext, resId)?.apply {
// 必须设置 Bounds 否则 drawable 不显示
setBounds(0, 0, minimumWidth, minimumHeight)
}
compoundDrawablePadding = drawablePadding
setCompoundDrawables(drawable, null, null, null)
}
Way 2: 通过 setCompoundDrawablesRelativeWithIntrinsicBounds 方式
sudGameOperatorAudioTxt.apply {
// ...
setCompoundDrawablesRelativeWithIntrinsicBounds(
if (mAudioOperatorStatus) R.drawable.xxx else R.drawable.xxx,
0,
0,
0
)
}
公共方法抽离:
fun getDrawable(context: Context, resId: Int, right: Int = -1, bottom: Int = -1): Drawable? =
ContextCompat.getDrawable(context, resId)?.apply {
// 必须设置 Bounds 否则 drawable 不显示
setBounds(
0,
0,
if (right == -1) minimumWidth else right,
if (bottom == -1) minimumHeight else bottom
)
}
具体设置案例:
private fun resetStatusRes(filterTxt: TypeFontTextView, drawableRes: Int = -1) {
val defaultRes = if (drawableRes == -1) R.drawable.ic_filter_nor else drawableRes
val iconDrawable = getDrawable(mContext, defaultRes, 10.dp, 10.dp)
filterTxt.setCompoundDrawables(null, null, iconDrawable, null)
}
binding.contractDetailOathTxt.apply {
val oathStr = ""
val spannableString = SpannableString(oathStr)
val drawable = resources.getDrawable(R.drawable.icon_edit_white, null)
val resizedBitmap = resizeBitmap(drawableToBitmap(drawable), 14.dp, 14.dp)
val imageSpan =
ImageSpan(context, resizedBitmap, DynamicDrawableSpan.ALIGN_BOTTOM)
spannableString.setSpan(
imageSpan,
oathStr.length - 1,
oathStr.length,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE
)
text = spannableString
android:ems="1"
ems: 代表当前一行可设置几个字符。
highlightColor = R.color.trans.ColorInt
xml 布局中设置如下:(注意宽度要限制)
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
代码中设置 isSelected = true 即可。
大概的就是就是,因为多点触控的关系,导致多个手指点击后,item 执行了多个操作(可能描述不太准确)。
解决方案:
android:overScrollMode="never"
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (recyclerView.scrollState == SCROLL_STATE_IDLE) {
(recyclerView.layoutManager as Your Use LayoutManager).findFirstVisibleItemPosition()
}
}
一直使用的 length 长度,便是实际输入长度,而这里的字符数,则代表字节数。
例如 GBK 编码下一个汉字占据两个字节,而 UTF-8 编码下一个汉字占据三个字节。
用户输入的字节长度,可以用以下方式获取:
下面贴出关键代码:
private val mNikeNameTextWatcher = object : TextWatcherAdapter {
override fun afterTextChanged(s: Editable?) {
super.afterTextChanged(s)
et_content.getEditTextView().removeTextChangedListener(this)
val inputStr = s?.toString()?.trim()
val bytes = inputStr?.toByteArray(Charset.forName("GBK"))
if ((bytes?.size ?: 0) > 16) {
toast("超出规定字符数,请按要求填写")
bytes?.let {
val newBytes = ByteArray(16)
System.arraycopy(it, 0, newBytes, 0, newBytes.size)
val resultText = String(newBytes, Charset.forName("GBK"))
et_content.setEditTextContent(resultText)
Selection.setSelection(
et_content.getEditTextView().editableText,
resultText.length
)
}
}
et_content.getEditTextView().addTextChangedListener(this)
}
}
密码明文展示:
setTransformationMethod(HideReturnsTransformationMethod.getInstance())
密码脱敏展示:
setTransformationMethod(PasswordTransformationMethod.getInstance())
记得更新光标位置:
setSelection(mEtCode.getText().length())
isUserInputEnabled = false
roleScrollView.post {
roleScrollView.fullScroll(View.FOCUS_DOWN)
}
android:textAllCaps="false"
app:contentInsetLeft="@dimen/dimen_0_dp"
app:contentInsetStart="@dimen/dimen_0_dp"
loadingLottie.progress = 0.5f
app:elevation="0dp"
注意是 app 下,并不是 android 下!!!
直接在 name 中写对应的属性即可。
<style name="commUserProfileSeeMoreStyle">
<item name="drawableRightCompat">@drawable/icon_arrow_right_gray</item>
</style>
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
金额类型替换为 BigDecimal
money.divide(BigDecimal(100), 2, BigDecimal.ROUND_DOWN).toString(), // 金额 元
Service 接口方法上追加 @JvmSuppressWildcards
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。