Android ItemLayout工具类
Posted 左郁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ItemLayout工具类相关的知识,希望对你有一定的参考价值。
1. 在开发中,经常会遇到千篇一律的子条目列表,比如个人中心里一堆功能设置
像这样的:
这样的:
每个子条目都是一个布局里嵌套三到四个组件,虽说可以通过 style 样式表去节省一部分重复代码,但是整体看 xml 还是好长一串
总结一下,大概有以下这几种情况:
所以,为了布局 “看起来” 简洁一些, 我这边封装了一个自定义view:ItemLayout,注意哈,这里只是为了让布局看起来简洁,因为内部还是布局嵌套组件。
下面先来看一下效果图:
2. 自定义view:效果展示和调用方式
对应调用代码片段:
<!-- 情况一:左侧图标 + 左侧文字 -->
<com.sunny.widget.ItemLayout
android:id="@+id/item1"
style="@style/style_register_item_layout"
app:startIcon="@drawable/svg_chat_duty"
app:startAfterText="用户信息"
app:lineVisible="true" />
<!-- 情况二:左侧图标 + 左侧文字 -->
<com.sunny.widget.ItemLayout
android:id="@+id/item2"
style="@style/style_register_item_layout"
app:startAfterText="收藏文件"
app:startIcon="@drawable/svg_chat_product"
app:endIcon="@drawable/svg_btn_more"
app:lineVisible="true" />
<!-- 情况三:左侧图标 + 左侧文字 + 右侧文字 + 右侧图标 -->
<com.sunny.widget.ItemLayout
android:id="@+id/item3"
style="@style/style_register_item_layout"
app:startIcon="@drawable/svg_chat_edit"
app:startAfterText="个人简介"
app:endIcon="@drawable/svg_btn_more"
app:endText="听说android还不错.."
app:lineVisible="true" />
<!-- 情况四:左侧文字 + 右侧文字 -->
<com.sunny.widget.ItemLayout
android:id="@+id/item4"
style="@style/style_register_item_layout"
app:startText="登录账号"
app:endText="131****6393"
app:lineVisible="true" />
<!-- 情况五:左侧文字 + 右侧图标 -->
<com.sunny.widget.ItemLayout
android:id="@+id/item5"
style="@style/style_register_item_layout"
app:startText="通知设置"
app:endIcon="@drawable/svg_btn_more"
app:lineVisible="true" />
<!-- 情况六:左侧文字 + 右侧文字 + 右侧图标 -->
<com.sunny.widget.ItemLayout
android:id="@+id/item6"
style="@style/style_register_item_layout"
app:startAfterText="清除缓存"
app:endIcon="@drawable/svg_btn_more"
app:endText="20M" />
下面来看看具体怎么实现的:
3. 自定义View属性:attr.xml 文件
<declare-styleable name="ItemLayout">
<!-- 左侧图标 -->
<attr name="startIcon" format="reference|color" />
<attr name="startIconWidth" format="dimension" />
<attr name="startIconHeight" format="dimension" />
<!-- 左侧文字 -->
<attr name="startText" format="string" />
<attr name="startTextSize" format="dimension" />
<attr name="startTextColor" format="reference" />
<!-- 左侧图标 + 文字 -->
<attr name="startAfterText" format="string" />
<attr name="startAfterTextSize" format="dimension" />
<attr name="startAfterTextColor" format="reference" />
<!-- 右侧图标 -->
<attr name="endIcon" format="reference" />
<attr name="endIconWidth" format="dimension" />
<attr name="endIconHeight" format="dimension" />
<!-- 右侧文字 -->
<attr name="endText" format="string" />
<attr name="endTextSize" format="dimension" />
<attr name="endTextColor" format="color" />
<!-- 右侧文字 + 图标 -->
<attr name="endBeforeText" format="string" />
<attr name="endBeforeTextSize" format="dimension" />
<attr name="endBeforeTextColor" format="reference" />
<!-- 子条目之间的分割线 -->
<attr name="lineColor" format="color" />
<attr name="lineHeight" format="dimension" />
<attr name="lineVisible" format="boolean" />
<!-- 左右边距 -->
<attr name="leftMargin" format="dimension" />
<attr name="rightMargin" format="dimension" />
</declare-styleable>
4. 自定义view:ItemLayout
/**
* Desc 自定义子条目View
* Author ZY
* Date 2020/02/04
*/
class ItemLayout : RelativeLayout
val startImageView: ImageView by lazy
ImageView(context).apply
id = R.id.iv_start
val startTextView: TextView by lazy
TextView(context).apply
id = R.id.tv_start
val startAfterTextView: TextView by lazy
TextView(context)
var endImage = 0
val endImageView: ImageView by lazy
ImageView(context).apply
id = R.id.iv_end
val endTextView: TextView by lazy
TextView(context).apply
id = R.id.tv_end
val endBeforeTextView: TextView by lazy
TextView(context)
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
val defaultMargin = resources.getDimension(R.dimen.dp_10)
val defaultTextSize = resources.getDimension(R.dimen.sp_14)
val defaultTextColor = ContextCompat.getColor(context, R.color.font_black)
val defaultLineColor = ContextCompat.getColor(context, R.color.color_line)
val defaultLineHeight = resources.getDimension(R.dimen.dp_1)
val typeArray = context.theme.obtainStyledAttributes(attrs, R.styleable.ItemLayout, defStyleAttr, 0)
/**
* 最外层View
*/
val leftMargin = typeArray.getDimension(R.styleable.ItemLayout_leftMargin, defaultMargin)
val rightMargin = typeArray.getDimension(R.styleable.ItemLayout_rightMargin, defaultMargin)
val parentLayout = RelativeLayout(context)
val layout = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
layout.leftMargin = leftMargin.toInt()
layout.rightMargin = rightMargin.toInt()
addView(parentLayout, layout)
/**
* 最左侧图标
*/
val startImage = typeArray.getResourceId(R.styleable.ItemLayout_startIcon, 0)
if (startImage != 0)
val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
lp.addRule(CENTER_VERTICAL)
startImageView.setImageResource(startImage)
parentLayout.addView(startImageView, lp)
/**
* 最左侧文字
*/
val startText = typeArray.getString(R.styleable.ItemLayout_startText) ?: ""
val startTextSize = typeArray.getDimension(R.styleable.ItemLayout_startTextSize, defaultTextSize)
val startTextColor = typeArray.getColor(R.styleable.ItemLayout_startTextColor, defaultTextColor)
if (startText.isNotEmpty())
val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
startTextView.text = startText
startTextView.setTextColor(startTextColor)
startTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, startTextSize)
startTextView.gravity = Gravity.CENTER_VERTICAL
parentLayout.addView(startTextView, lp)
/**
* 最左侧文字/图标 —— 文字
*/
val startAfterText = typeArray.getString(R.styleable.ItemLayout_startAfterText) ?: ""
val startAfterTextSize = typeArray.getDimension(R.styleable.ItemLayout_startAfterTextSize, defaultTextSize)
val startAfterTextColor = typeArray.getColor(R.styleable.ItemLayout_startAfterTextColor, defaultTextColor)
if (startAfterText.isNotEmpty())
val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
startAfterTextView.text = startAfterText
startAfterTextView.setTextColor(startAfterTextColor)
startAfterTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, startAfterTextSize)
startAfterTextView.gravity = Gravity.CENTER_VERTICAL
val mLeft = when
startImage != 0 -> startImageView.id
startText.isNotEmpty() -> startTextView.id
else -> 0
if (mLeft != 0)
lp.leftMargin = defaultMargin.toInt()
lp.addRule(RIGHT_OF, mLeft)
parentLayout.addView(startAfterTextView, lp)
/**
* 最右侧图标
*/
endImage = typeArray.getResourceId(R.styleable.ItemLayout_endIcon, 0)
if (endImage != 0)
val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
endImageView.setPadding(defaultMargin.toInt(), 0, 0, 0)
lp.addRule(ALIGN_PARENT_RIGHT)
lp.addRule(CENTER_VERTICAL)
endImageView.setImageResource(endImage)
parentLayout.addView(endImageView, lp)
/**
* 最右侧文字
*/
val endText = typeArray.getString(R.styleable.ItemLayout_endText) ?: ""
val endTextSize = typeArray.getDimension(R.styleable.ItemLayout_endTextSize, defaultTextSize)
val endTextColor = typeArray.getColor(R.styleable.ItemLayout_endTextColor, defaultTextColor)
if (endText.isNotEmpty())
val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
if (endImage != 0)
lp.addRule(LEFT_OF, endImageView.id)
else
lp.addRule(ALIGN_PARENT_RIGHT)
endTextView.text = endText
endTextView.setTextColor(endTextColor)
endTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, endTextSize)
endTextView.gravity = Gravity.CENTER_VERTICAL
parentLayout.addView(endTextView, lp)
/**
* 文字 —— 最右侧文字/图标
*/
val endBeforeText = typeArray.getString(R.styleable.ItemLayout_endBeforeText) ?: ""
val endBeforeTextSize = typeArray.getDimension(R.styleable.ItemLayout_endBeforeTextSize, defaultTextSize)
val endBeforeTextColor = typeArray.getColor(R.styleable.ItemLayout_endBeforeTextColor, defaultTextColor)
if (endBeforeText.isNotEmpty())
val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
endBeforeTextView.text = endBeforeText
endBeforeTextView.setTextColor(endBeforeTextColor)
endBeforeTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, endBeforeTextSize)
endBeforeTextView.gravity = Gravity.CENTER_VERTICAL
val mRight = if (endText.isNotEmpty())
endTextView.id
else
endImageView.id
if (mRight != 0)
lp.addRule(LEFT_OF, mRight)
else
lp.addRule(ALIGN_PARENT_RIGHT)
lp.marginEnd = defaultMargin.toInt()
parentLayout.addView(endBeforeTextView, lp)
/**
* 分割线
*/
val lineColor = typeArray.getColor(R.styleable.ItemLayout_lineColor, defaultLineColor)
val lineHeight = typeArray.getDimension(R.styleable.ItemLayout_lineHeight, defaultLineHeight)
val lineVisible = typeArray.getBoolean(R.styleable.ItemLayout_lineVisible, false)
if (lineVisible)
val view = View(context)
view.setBackgroundColor(lineColor)
val lp = LayoutParams(LayoutParams.MATCH_PARENT, lineHeight.toInt())
lp.addRule(ALIGN_PARENT_BOTTOM)
addView(view, lp)
typeArray.recycle()
5. 自定义view的属性,随意搭配,总有一种是你需要的,哈哈,还是那句话,布局代码看起来是不是简洁了好多~
以上是关于Android ItemLayout工具类的主要内容,如果未能解决你的问题,请参考以下文章
Android中具有自定义子布局的Expandablelistview
Bootstrap 类 dropdown-menu dropdown-menu-right 不适用于自定义子菜单