XML
文件
ItemView
布局R.layout.layout_item_view
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
android:id="@+id/fl"
android:layout_width="46dp"
android:layout_height="46dp"
android:background="@drawable/shape_dmt_bg"
android:layout_margin="3dp">
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
</FrameLayout>
Activity
布局R.layout.activity_main
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_red_light">
<LinearLayout
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:paddingLeft="22dp"
android:paddingRight="22dp"
android:background="@color/black"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>
RecyclerView
的相关类
class MyViewHolder(itemView: View, private val mListener: OnItemSelectListener?) : RecyclerView.ViewHolder(itemView) , MyListViewHelper.ISelectable {
private var mIv: ImageView? = null
private var mFl: FrameLayout? = null
fun bind(index: Int, type: MyType) {
mIv = itemView.findViewById(R.id.iv)
mFl = itemView.findViewById(R.id.fl)
mIv?.setImageResource(type.icon)
itemView.setOnClickListener {
mListener?.onItemSelect(index, type)
}
}
override fun select() {
mFl?.setBackgroundResource(R.drawable.shape_dmt_bg_on)
mIv?.setColorFilter(Color.parseColor("#FFFFD800"))
}
override fun unselect() {
mFl?.setBackgroundResource(R.drawable.shape_dmt_bg)
mIv?.colorFilter = null
}
interface OnItemSelectListener {
fun onItemSelect(index: Int, type: MyType)
}
}
data class MyType (val icon: Int, val type: TYPE) {
enum class TYPE {
A, B, C,
}
}
class MyAdapter : RecyclerView.Adapter<MyViewHolder>() {
private val mData = ArrayList<MyType>().apply {
add(MyType(R.drawable.ic_rect, MyType.TYPE.A))
add(MyType(R.drawable.ic_crop_free, MyType.TYPE.B))
add(MyType(R.drawable.ic_icon_crop_rotate, MyType.TYPE.C))
add(MyType(R.drawable.ic_rect, MyType.TYPE.A))
add(MyType(R.drawable.ic_crop_free, MyType.TYPE.B))
add(MyType(R.drawable.ic_icon_crop_rotate, MyType.TYPE.C))
add(MyType(R.drawable.ic_rect, MyType.TYPE.A))
add(MyType(R.drawable.ic_crop_free, MyType.TYPE.B))
add(MyType(R.drawable.ic_icon_crop_rotate, MyType.TYPE.C))
add(MyType(R.drawable.ic_crop_free, MyType.TYPE.B))
add(MyType(R.drawable.ic_icon_crop_rotate, MyType.TYPE.C))
}
private var mSelectedListener: MyViewHolder.OnItemSelectListener? = null
fun setOnItemSelectListener(listener: MyViewHolder.OnItemSelectListener) {
mSelectedListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.layout_item_view, parent, false)
return MyViewHolder(itemView, mSelectedListener)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bind(position, mData[position])
}
override fun getItemCount(): Int {
return mData.size
}
}
动态添加ItemView
的工具类
- 传入
RecyclerView
的Adapter
,在父View
中动态添加RecyclerView
的每个ItemView
(依次调用Adapter
的onCreateViewHolder
方法和onBindViewHolder
方法)
class MyListViewHelper(private val mContext : Context, private val mColumns : Int = 5, private val mMarginBottom : Float = 20f) {
private val mViews = HashMap<Int, RecyclerView.ViewHolder>()
private var mSelectedIndex = -1
fun <T : RecyclerView.ViewHolder> setAdapter(parentView: ViewGroup, adapter: RecyclerView.Adapter<T>){
val rows = Math.ceil(((adapter.itemCount / (mColumns * 1f)).toDouble())).toInt()
Log.d("yang", "adapter.itemCount = ${adapter.itemCount}, rows = $rows")
for (row in 0 until rows) {
val childLinearLayout = LinearLayout(parentView.context).apply {
orientation = LinearLayout.HORIZONTAL
}
val params = ViewGroup.MarginLayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
).apply {
bottomMargin = dpToPx(mContext, mMarginBottom).toInt()
}
for (column in 0 until mColumns) {
val index = row * mColumns + column
val viewHolder: RecyclerView.ViewHolder
if (index < adapter.itemCount) {
viewHolder = adapter.createViewHolder(childLinearLayout, adapter.getItemViewType(index))
adapter.bindViewHolder(viewHolder, index)
mViews[index] = viewHolder
} else {
viewHolder = adapter.createViewHolder(childLinearLayout, 0)
viewHolder.itemView.visibility = View.INVISIBLE
}
val itemViewParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
leftMargin = 50
rightMargin = 50
}
childLinearLayout.addView(viewHolder.itemView, itemViewParams)
}
childLinearLayout.gravity = Gravity.CENTER_HORIZONTAL
parentView.addView(childLinearLayout, params)
}
}
fun performSelect(index: Int) {
if (index == mSelectedIndex) {
return
}
val vh = mViews[index] ?: return
vh.itemView.performClick()
}
fun select(index: Int) {
if (index == mSelectedIndex) {
return
}
val vh = mViews[index] ?: return
val oldVH = mViews[mSelectedIndex]
(oldVH as ISelectable?)?.unselect()
(vh as ISelectable).select()
mSelectedIndex = index
}
interface ISelectable {
fun select()
fun unselect()
}
}
Activity
代码
class MainActivity : AppCompatActivity() {
private lateinit var mList: ViewGroup
private lateinit var mListHelper: MyListViewHelper
private lateinit var mAdapter : MyAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mList = findViewById(R.id.list)
mAdapter = MyAdapter()
mAdapter.setOnItemSelectListener(object : MyViewHolder.OnItemSelectListener {
override fun onItemSelect(index: Int, type: MyType) {
mListHelper.select(index)
}
})
mListHelper = MyListViewHelper(this, 3)
mListHelper.setAdapter(mList, mAdapter)
mListHelper.performSelect(0)
}
}
效果图