feat(自定义控件): 新增自定义控件

1.自定义CustomTitleBar以便于减少标题栏的重复代码
2.自定义CustomItem以便于减少应用中item项的重复代码
This commit is contained in:
糕小菜 2024-10-14 22:32:07 +08:00
parent d9376b96df
commit 1cc3ebbe3b
7 changed files with 336 additions and 4 deletions

View File

@ -0,0 +1,121 @@
package com.kaixed.kchat.view.widget
import android.content.Context
import android.content.Intent
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import com.kaixed.kchat.R
import com.kaixed.kchat.databinding.ItemCustomBinding
import com.kaixed.kchat.view.activity.ProfileDetailActivity
/**
* @Author: kaixed
* @Date: 2024/10/10 22:28
* @Description: 自定义Item控件以便于复用以减少重复代码
*/
class CustomItem @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : ConstraintLayout(context, attrs, defStyleAttr) {
private var binding: ItemCustomBinding =
ItemCustomBinding.inflate(LayoutInflater.from(context), this, true)
init {
attrs?.let {
val typedArray = context.obtainStyledAttributes(it, R.styleable.CustomItem, 0, 0)
val itemName = typedArray.getString(R.styleable.CustomItem_itemName) ?: ""
val itemIconSize = typedArray.getDimension(R.styleable.CustomItem_iconSize, 0f)
val itemIcon = typedArray.getResourceId(R.styleable.CustomItem_itemIcon, -1)
val itemIconRound = typedArray.getDimension(R.styleable.CustomItem_iconRound, 0f)
val itemDesc = typedArray.getString(R.styleable.CustomItem_itemDesc) ?: ""
val isShowTopDivider =
typedArray.getBoolean(R.styleable.CustomItem_isTopDividerVisible, false)
val isShowBottomDivider =
typedArray.getBoolean(R.styleable.CustomItem_isBottomDividerVisible, false)
if (itemDesc.isNotEmpty()) {
binding.tvItemDesc.visibility = View.VISIBLE
binding.tvItemDesc.text = itemDesc
} else {
binding.tvItemDesc.visibility = View.GONE
}
if (itemIcon != -1) {
binding.ivItemIcon.visibility = View.VISIBLE
binding.ivItemIcon.setImageResource(itemIcon)
val displayMetrics = context.resources.displayMetrics
if (itemIconRound.toInt() != 0) {
val requestOptions =
RequestOptions().transform(RoundedCorners(itemIconRound.toInt()))
Glide.with(context).load(itemIcon).apply(requestOptions)
.into(binding.ivItemIcon)
binding.ivItemIcon.clipToOutline = true
}
if (itemIconSize.toInt() != 0) {
binding.ivItemIcon.layoutParams.width =
(itemIconSize * displayMetrics.density).toInt()
binding.ivItemIcon.layoutParams.height =
(itemIconSize * displayMetrics.density).toInt()
} else {
binding.ivItemIcon.visibility = View.GONE
}
} else {
binding.ivItemIcon.visibility = View.GONE
}
if (itemName.isNotEmpty()) {
binding.tvItemName.text = itemName
}
binding.decorationTop.visibility = if (isShowTopDivider) {
View.VISIBLE
} else {
View.GONE
}
binding.decorationBottom.visibility = if (isShowBottomDivider) {
View.VISIBLE
} else {
View.GONE
}
typedArray.recycle()
}
// binding.root.setOnClickListener {
// val activity = ""
// val fullClassName = "com.kaixed.kchat.view.activity.$activity"
//
// try {
// val activityClass = Class.forName(fullClassName)
// val intent = Intent(context, activityClass)
// context.startActivity(intent)
// } catch (e: ClassNotFoundException) {
// Toast.makeText(context, "跳转出错,请重试", Toast.LENGTH_LONG).show()
// }
// }
}
fun setOnItemClickListener(listener: OnClickListener) {
binding.root.setOnClickListener(listener)
}
}

View File

@ -0,0 +1,59 @@
package com.kaixed.kchat.view.widget
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import com.kaixed.kchat.R
import com.kaixed.kchat.databinding.ViewTitleBarBinding
/**
* @Author: kaixed
* @Date: 2024/10/10 22:13
* @Description: 自定义标题栏控件
*/
class CustomTitleBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : ConstraintLayout(context, attrs, defStyleAttr) {
private var binding: ViewTitleBarBinding =
ViewTitleBarBinding.inflate(LayoutInflater.from(context), this, true)
init {
attrs?.let {
val typedArray = context.obtainStyledAttributes(it, R.styleable.CustomTitleBar, 0, 0)
val titleName = typedArray.getString(R.styleable.CustomTitleBar_titleName) ?: ""
val titleIcon = typedArray.getResourceId(R.styleable.CustomTitleBar_titleIcon, -1)
if (titleIcon != -1) {
binding.ivSetting.visibility = View.VISIBLE
binding.ivSetting.setImageResource(titleIcon)
} else {
binding.ivSetting.visibility = View.GONE
}
if (titleName.isNotEmpty()) {
binding.tvTitleName.visibility = View.VISIBLE
binding.tvTitleName.text = titleName
} else {
binding.tvTitleName.visibility = View.GONE
}
typedArray.recycle()
}
binding.ivBack.setOnClickListener {
(context as? Activity)?.finish()
}
}
}

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:minHeight="50dp">
<View
android:id="@+id/decoration_top"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="#E5E5E5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/tv_item_name"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:text="xxx"
android:textColor="@color/black"
android:textSize="17sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginTop="0dp" />
<TextView
android:id="@+id/tv_item_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="aaaa"
android:textColor="#797979"
android:textSize="17sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/iv_arrow_right"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_item_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="10dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/iv_arrow_right"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_arrow_right"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="15dp"
android:src="@drawable/icon_arrow_right"
app:layout_constraintBottom_toBottomOf="@id/tv_item_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_item_name" />
<View
android:id="@+id/decoration_bottom"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="#E5E5E5"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/tv_item_name" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:id="@+id/iv_back"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginStart="15dp"
android:src="@drawable/ic_left_arrow"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_title_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_setting"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginEnd="15dp"
android:src="@drawable/ic_setting"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginEnd="15dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,7 @@
<resources>
<style name="Widget.Theme.KChatAndroid.MyView" parent="">
<item name="android:background">@color/gray_600</item>
<item name="exampleColor">@color/light_blue_600</item>
</style>
</resources>

View File

@ -1,8 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomToolbar">
<attr name="customTitle" format="string"/>
<attr name="customLogo" format="reference"/>
<attr name="customTitleColor" format="color"/>
<declare-styleable name="CustomPreference">
<attr name="isShowTopDivider" format="boolean" />
<attr name="isShowBottomDivider" format="boolean" />
</declare-styleable>
<declare-styleable name="CustomPreferenceCategory">
<attr name="itemTitle" format="string" />
</declare-styleable>
<declare-styleable name="CustomItem">
<attr name="itemName" format="string" />
<attr name="itemDesc" format="string" />
<attr name="isTopDividerVisible" format="boolean" />
<attr name="isBottomDividerVisible" format="boolean" />
<attr name="iconSize" format="dimension" />
<attr name="iconRound" format="dimension" />
<attr name="itemIcon" format="reference" />
</declare-styleable>
<declare-styleable name="CustomTitleBar">
<attr name="titleName" format="string" />
<attr name="titleIcon" format="reference" />
</declare-styleable>
</resources>

View File

@ -0,0 +1,7 @@
<resources>
<style name="Widget.Theme.KChatAndroid.MyView" parent="">
<item name="android:background">@color/gray_400</item>
<item name="exampleColor">@color/light_blue_400</item>
</style>
</resources>