效果图如下:
核心代码如下:
open class CommonItemView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, mode: Int = MODE_TEXT) : RelativeLayout(context, attrs, defStyleAttr) {
companion object {
const val MODE_TEXT = 0
const val MODE_EDIT = 1
}
private lateinit var mTvRequireFlag: TextView
private lateinit var mTvOrderKey: TextView
private lateinit var mStubOrderItem: ViewStub
private lateinit var mIvOrderGo: ImageView
private lateinit var mTvItemValue: TextView
private lateinit var mEtItemEdit: EditText
private lateinit var mIvItemClear: ImageView
private var isRequire: Boolean = false
private var isGo: Boolean = true
private var mKey: String? = ""
private var mValue: String? = ""
private var mHolder: String? = ""
private var mLeftMargin: Int = dip(110)
private var mMode: Int = mode
init {
val view = LayoutInflater.from(context).inflate(R.layout.view_order_item, this, true)
initAttrs(attrs)
initView(view)
initData()
}
private fun initAttrs(attrs: AttributeSet?) {
attrs?.apply {
val array = context.obtainStyledAttributes(attrs, R.styleable.CommonItemView)
isRequire = array.getBoolean(R.styleable.CommonItemView_orderRequired, false)
isGo = array.getBoolean(R.styleable.CommonItemView_orderGo, true)
mKey = array.getString(R.styleable.CommonItemView_orderKey) ?: ""
mValue = array.getString(R.styleable.CommonItemView_orderValue) ?: ""
mHolder = array.getString(R.styleable.CommonItemView_orderHolder) ?: ""
mLeftMargin = array.getDimensionPixelSize(R.styleable.CommonItemView_orderLeftMargin, dip(110))
mMode = array.getInt(R.styleable.CommonItemView_orderMode, MODE_TEXT)
array.recycle()
}
}
private fun initView(view: View) {
mTvRequireFlag = view.findViewById(R.id.tv_require_flag)
mTvOrderKey = view.findViewById(R.id.tv_order_key)
mStubOrderItem = view.findViewById(R.id.stub_order_item)
mIvOrderGo = view.findViewById(R.id.iv_order_go)
}
private fun initData() {
setPadding(dip(16), 0, dip(16), 0)
setBackgroundResource(R.color.white)
//设置是否必填标志
if (isRequire) {
mTvRequireFlag.visibility = View.VISIBLE
} else {
mTvRequireFlag.visibility = View.GONE
}
//设置是否显示进入图标
if (isGo) {
mIvOrderGo.visibility = View.VISIBLE
} else {
mIvOrderGo.visibility = View.GONE
}
//设置Key
mTvOrderKey.text = mKey
if (mMode == MODE_EDIT) {
mStubOrderItem.layoutResource = R.layout.order_stub_et
val view = mStubOrderItem.inflate()
mEtItemEdit = view.findViewById(R.id.stub_et)
mEtItemEdit.hint = mHolder
mEtItemEdit.setText(mValue)
mIvItemClear = view.findViewById(R.id.stub_clear_iv)
mEtItemEdit.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s.isNullOrEmpty()) {
mIvItemClear.visibility = View.GONE
} else {
mIvItemClear.visibility = View.VISIBLE
}
}
})
mIvItemClear.setOnClickListener {
mEtItemEdit.setText("")
}
} else {
mStubOrderItem.layoutResource = R.layout.order_stub_tv
mTvItemValue = mStubOrderItem.inflate() as TextView
mTvItemValue.hint = mHolder
mTvItemValue.setHintTextColor(ContextCompat.getColor(context, R.color.btn_color_not_active))
mTvItemValue.text = mValue
}
//设置横向的Margin
val params = mStubOrderItem.layoutParams as LayoutParams
params.setMargins(mLeftMargin, 0, 0, 0)
}
/**
* 设置左侧Margin
*/
fun setLeftMargin(leftMargin: Int) {
mLeftMargin = leftMargin
val params = mStubOrderItem.layoutParams as LayoutParams
params.setMargins(mLeftMargin, 0, 0, 0)
}
/**
* 展示进入箭头
*/
fun showGo() {
isGo = true
mIvOrderGo.visibility = View.VISIBLE
}
/**
* 隐藏进入箭头
*/
fun hideGo() {
isGo = false
mIvOrderGo.visibility = View.GONE
}
/**
* 设置Text模式下的TextView颜色
*/
fun setFixTextColor() {
if (mMode == MODE_TEXT) {
mTvItemValue.textColorResource = R.color.text_item_fixed
}
}
/**
* 设置正常模式包含多选下的颜色
*/
fun setNormalTextColor() {
if (mMode == MODE_TEXT) {
mTvItemValue.textColorResource = R.color.text_color_primary
}
}
/**
* 设置Key
*/
fun setItemKey(key: String?) {
mKey = key
mTvOrderKey.text = key
}
fun setMode(mode: Int) {
mMode = mode
}
/**
* 改变Value
*/
fun setItemValue(value: String?) {
mValue = value
if (mMode == MODE_TEXT) {
mTvItemValue.text = value
} else if (mMode == MODE_EDIT) {
mEtItemEdit.setText(value)
}
}
/**
* 获取当前Value
*/
fun getItemValue(): String {
return mValue ?: ""
}
/**
* 获取当前Edit-Value
*/
fun getItemEdit(): String {
var result = ""
if (mMode == MODE_EDIT) {
result = mEtItemEdit.text.toString().trim()
}
return result
}
/**
* 获取当前的Key
*/
fun getItemKey(): String {
return mKey ?: ""
}
/**
* 设置当前Item是否必填
*/
fun setRequire(isRequire: Boolean) {
this.isRequire = isRequire
mTvRequireFlag.visibility = if (isRequire) {
View.VISIBLE
} else {
View.GONE
}
}
/**
* 设置Holder
*/
fun setItemHolder(holder: String?) {
mHolder = holder
if (mMode == MODE_TEXT) {
mTvItemValue.hint = holder
} else if (mMode == MODE_EDIT) {
mEtItemEdit.apply {
inputType = InputType.TYPE_CLASS_TEXT
hint = holder
imeOptions = EditorInfo.IME_ACTION_DONE
}
}
}
fun setMaxLength(maxLength: Int) {
mEtItemEdit.filters = arrayOf(InputFilter.LengthFilter(maxLength))
}
}
styles.xml文件自定义属性
<declare-styleable name="CommonItemView">
<attr name="orderRequired" format="boolean" />
<attr name="orderGo" format="boolean" />
<attr name="orderKey" format="string|reference" />
<attr name="orderValue" format="string|reference" />
<attr name="orderHolder" format="string|reference" />
<attr name="orderLeftMargin" format="dimension|reference" />
<attr name="orderMode" format="enum">
<enum name="Edit" value="1" />
<enum name="Text" value="2" />
</attr>
</declare-styleable>
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<TextView
android:id="@+id/tv_order_key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:maxWidth="100dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textSize="14sp"
android:textColor="#646B7F"
android:text="ITEM名称" />
<TextView
android:id="@+id/tv_require_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="5dp"
android:layout_toEndOf="@id/tv_order_key"
android:text="*"
android:textColor="#f25f2b"
android:textSize="15sp" />
<ViewStub
android:id="@+id/stub_order_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/iv_order_go"
android:paddingTop="10dp"
android:paddingBottom="10dp"
/>
<ImageView
android:id="@+id/iv_order_go"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginStart="3dp"
android:src="@drawable/ic_arrow_grey_right" />
</RelativeLayout>
测试的例子:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.orderitemviewdemo.CommonItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:orderGo="false"
app:orderKey="我是标题"
app:orderValue="内容"
app:orderLeftMargin="110dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="16dp"
android:background="#f4f4f4" />
<com.example.orderitemviewdemo.CommonItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:orderGo="true"
app:orderKey="我是标题"
app:orderValue="内容"
app:orderLeftMargin="110dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="16dp"
android:background="#f4f4f4" />
<com.example.orderitemviewdemo.CommonItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:orderGo="false"
app:orderKey="我是标题"
app:orderHolder="我是提示语"
app:orderLeftMargin="110dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="16dp"
android:background="#f4f4f4" />
<com.example.orderitemviewdemo.CommonItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:orderGo="false"
app:orderKey="我是标题"
app:orderHolder="请输入内容"
app:orderMode="Edit"
app:orderLeftMargin="110dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="16dp"
android:background="#f4f4f4" />
<com.example.orderitemviewdemo.CommonItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:orderGo="false"
app:orderKey="我是标题"
app:orderMode="Edit"
app:orderHolder="请输入必填内容"
app:orderLeftMargin="110dp"
app:orderRequired="true"/>
</LinearLayout>