@@ -4,28 +4,30 @@ import android.annotation.SuppressLint
44import android.content.Context
55import android.graphics.Rect
66import android.util.AttributeSet
7+ import android.util.DisplayMetrics
78import android.util.Log
89import android.view.View
910import android.view.View.OnLongClickListener
1011import android.view.ViewGroup
12+ import android.view.WindowManager
1113import kotlin.math.max
1214
13- private const val TAG = " TagLayout"
15+ private const val TAG = " TagLayout===> "
1416
1517/* *
1618 * 标签布局
1719 * @author yhw
1820 */
1921class TagLayout : ViewGroup {
20- private val mViewRectList = mutableListOf<Rect >()
21- private val mChildViewList = mutableListOf<View >()
22+ private val mViewRectMap = mutableMapOf<View , Rect >()
2223 private var choiceMode = ChoiceMode .None .choiceMode // 选择模式
2324 private var defChoicePosition: Int = 0 // 单选时默认选中
2425 private lateinit var mAdapter: TagAdapter
2526 var onItemClickListener: OnItemClickListener ? = null
2627 var onItemLongClickListener: OnItemLongClickListener ? = null
2728 var onSingleCheckedChangeListener: OnSingleCheckedChangeListener ? = null
2829 var onMultipleCheckedChangeListener: OnMultipleCheckedChangeListener ? = null
30+ var mScreenWidth = 0 // 屏幕宽度
2931
3032 constructor (context: Context ) : this (context, null )
3133 constructor (context: Context , attrs: AttributeSet ? ) : this (context, attrs, 0 )
@@ -38,6 +40,12 @@ class TagLayout : ViewGroup {
3840 choiceMode = ta.getInt(R .styleable.TagLayout_choiceMode , ChoiceMode .None .choiceMode)
3941 defChoicePosition = ta.getInt(R .styleable.TagLayout_defaultChoicePosition , 0 )
4042 ta.recycle()
43+
44+ val windowManager = context
45+ .getSystemService(Context .WINDOW_SERVICE ) as WindowManager
46+ val displayMetrics = DisplayMetrics ()
47+ windowManager.defaultDisplay.getMetrics(displayMetrics)
48+ this .mScreenWidth = displayMetrics.widthPixels
4149 }
4250
4351 @SuppressLint(" DrawAllocation" )
@@ -52,9 +60,8 @@ class TagLayout : ViewGroup {
5260 var height = 0 // 最终父布局高度
5361 var lineWidth = 0 // 行宽
5462 var lineHeight = 0 // 行高
55-
63+ Log .i( TAG , " widthSize is $widthSize widthMode is $widthMode mScreenWidth: ${mScreenWidth} " )
5664 measureChildren(widthMeasureSpec, heightMeasureSpec)
57-
5865 for (i in 0 until childCount) {
5966 val childView = getChildAt(i)
6067 val marginLayoutParams: MarginLayoutParams =
@@ -83,72 +90,76 @@ class TagLayout : ViewGroup {
8390 lineHeight = max(childHeight, lineHeight)
8491 }
8592
86- if (! mChildViewList.contains(childView)) {
87- if (choiceMode == ChoiceMode .SingleChoice .choiceMode) {
88- if (i in 0 until childCount && i == defChoicePosition)
89- childView.isSelected = true
90- }
91- mChildViewList.add(childView)
92- val childLeft = lineWidth - childWidth + marginLayoutParams.leftMargin
93- val childRight =
94- lineWidth - childWidth + childWidth - marginLayoutParams.rightMargin
95- val childTop = height + marginLayoutParams.topMargin
96- val childBottom = height + childHeight - marginLayoutParams.bottomMargin
97- val rect = Rect (childLeft, childTop, childRight, childBottom)
98- Log .i(
99- TAG , " onMeasure left:${rect.left} top:${rect.top} ," +
100- " right:${rect.right} ,bottom:${rect.bottom} "
101- )
102- mViewRectList.add(rect)
103-
104- if (onItemClickListener != null || onSingleCheckedChangeListener != null || onMultipleCheckedChangeListener != null ) {
105- childView.isClickable = true
106- childView.isFocusable = true
107- childView.setOnClickListener {
108- changedCheckedItemView(i)
109- if (onItemClickListener != null ) {
110- onItemClickListener?.onItemClick(i, it)
111- }
112- if (choiceMode == ChoiceMode .SingleChoice .choiceMode) {
113- this .defChoicePosition = i
114- if (onSingleCheckedChangeListener != null ) {
115- onSingleCheckedChangeListener?.onCheckedChanged(defChoicePosition)
116- }
117- } else if (choiceMode == ChoiceMode .MultipleChoice .choiceMode) {
118- if (onMultipleCheckedChangeListener != null ) {
119- onMultipleCheckedChangeListener?.onCheckedChanged(getCheckedList())
120- }
121- }
122- }
123- }
124-
125- if (onItemLongClickListener != null ) {
126- childView.isClickable = true
127- childView.isFocusable = true
128- childView.setOnLongClickListener(OnLongClickListener { v ->
129- onItemLongClickListener?.onItemLongClick(i, v)
130- true
131- })
132- }
93+ if (choiceMode == ChoiceMode .SingleChoice .choiceMode) {
94+ if (i in 0 until childCount && i == defChoicePosition)
95+ childView.isSelected = true
13396 }
97+ val childLeft = lineWidth - childWidth + marginLayoutParams.leftMargin + paddingLeft
98+ var childRight = childView.measuredWidth + childLeft
99+ if (childRight > mScreenWidth) {
100+ childRight = mScreenWidth - marginLayoutParams.rightMargin - paddingRight
101+ // childRight = childView.measuredWidth
102+ }
103+ val childTop = height + marginLayoutParams.topMargin + paddingTop
104+ val childBottom =
105+ height + childHeight - marginLayoutParams.bottomMargin + paddingTop
106+ val rect = Rect (childLeft, childTop, childRight, childBottom)
107+ Log .i(
108+ TAG , " onMeasure left:${rect.left} top:${rect.top} ," +
109+ " right:${rect.right} ,bottom:${rect.bottom} measuredWidth:${childView.measuredWidth} "
110+ )
111+ mViewRectMap[childView] = rect
134112
135113 // 最后一行处理
136114 if (i == childCount - 1 ) {
137115 width = max(lineWidth, width)
138116 height + = lineHeight
139117 }
140118 }
141- setMeasuredDimension(
142- if (widthMode == MeasureSpec .EXACTLY ) widthSize else width,
143- if (heightMode == MeasureSpec .EXACTLY ) heightSize else height
144- )
119+ val measuredWidth =
120+ if (widthMode == MeasureSpec .EXACTLY ) widthSize else width + paddingLeft + paddingRight
121+ val measuredHeight =
122+ if (heightMode == MeasureSpec .EXACTLY ) heightSize else height + paddingTop + paddingBottom
123+ Log .i(TAG , " measuredWidth :${measuredWidth} measuredHeight:${measuredHeight} width:${width} lineWidth:${lineWidth} " )
124+ setMeasuredDimension(max(measuredWidth, width), measuredHeight)
145125 }
146126
147127 override fun onLayout (changed : Boolean , l : Int , t : Int , r : Int , b : Int ) {
148- for (i in 0 until childCount) {
149- val childView = getChildAt(i)
150- val rect = mViewRectList[i]
128+ Log .i( TAG , " =========onLayout========== $changed $l $t $r $b " )
129+ var i = 0
130+ for ((childView, rect) in mViewRectMap) {
151131 childView.layout(rect.left, rect.top, rect.right, rect.bottom)
132+ if (onItemClickListener != null || onSingleCheckedChangeListener != null || onMultipleCheckedChangeListener != null ) {
133+ childView.isClickable = true
134+ childView.isFocusable = true
135+ val position = i
136+ childView.setOnClickListener {
137+ changedCheckedItemView(position)
138+ if (onItemClickListener != null ) {
139+ onItemClickListener?.onItemClick(position, it)
140+ }
141+ if (choiceMode == ChoiceMode .SingleChoice .choiceMode) {
142+ this .defChoicePosition = position
143+ if (onSingleCheckedChangeListener != null ) {
144+ onSingleCheckedChangeListener?.onCheckedChanged(defChoicePosition)
145+ }
146+ } else if (choiceMode == ChoiceMode .MultipleChoice .choiceMode) {
147+ if (onMultipleCheckedChangeListener != null ) {
148+ onMultipleCheckedChangeListener?.onCheckedChanged(getCheckedList())
149+ }
150+ }
151+ }
152+ }
153+
154+ if (onItemLongClickListener != null ) {
155+ childView.isClickable = true
156+ childView.isFocusable = true
157+ childView.setOnLongClickListener(OnLongClickListener { v ->
158+ onItemLongClickListener?.onItemLongClick(i, v)
159+ true
160+ })
161+ }
162+ i++
152163 }
153164 }
154165
@@ -157,7 +168,8 @@ class TagLayout : ViewGroup {
157168 */
158169 private fun changedCheckedItemView (position : Int ) {
159170 Log .i(TAG , " choiceMode is $choiceMode " )
160- for ((index, view) in mChildViewList.withIndex()) {
171+ var index = 0
172+ for ((view, _) in mViewRectMap) {
161173 if (position == - 1 ) {
162174 view.isSelected = false
163175 continue
@@ -171,6 +183,7 @@ class TagLayout : ViewGroup {
171183 } else {
172184 view.isSelected = false
173185 }
186+ index++
174187 }
175188 }
176189
@@ -179,10 +192,12 @@ class TagLayout : ViewGroup {
179192 */
180193 fun getCheckedList (): MutableList <Int > {
181194 val checkedList = mutableListOf<Int >()
182- for ((index, view) in mChildViewList.withIndex()) {
195+ var index = 0
196+ for ((view, _) in mViewRectMap) {
183197 if (view.isSelected) {
184198 checkedList.add(index)
185199 }
200+ index++
186201 }
187202 return checkedList
188203 }
@@ -204,8 +219,7 @@ class TagLayout : ViewGroup {
204219
205220 private fun changedAdapter () {
206221 removeAllViews()
207- mChildViewList.clear()
208- mViewRectList.clear()
222+ mViewRectMap.clear()
209223 for (i in 0 until mAdapter.getItemCount()) {
210224 val itemView = mAdapter.onCreateView(this )
211225 mAdapter.onBindView(itemView, i)
0 commit comments