Skip to content

Commit e2a67c4

Browse files
committed
* fix wrap_content
1 parent f603106 commit e2a67c4

File tree

3 files changed

+108
-80
lines changed

3 files changed

+108
-80
lines changed

TabLayout/src/main/java/com/angcyo/tablayout/DslTabIndicator.kt

+44-8
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ open class DslTabIndicator(val tabLayout: DslTabLayout) : DslGradientDrawable()
133133
/**切换时是否需要动画的支持*/
134134
var indicatorAnim = true
135135

136+
/**在获取锚点view的宽高时, 是否需要忽略对应的padding属性*/
137+
var ignoreChildPadding: Boolean = true
138+
136139
init {
137140
callback = tabLayout
138141
}
@@ -199,6 +202,11 @@ open class DslTabIndicator(val tabLayout: DslTabLayout) : DslGradientDrawable()
199202
)
200203
}
201204

205+
ignoreChildPadding = typedArray.getBoolean(
206+
R.styleable.DslTabLayout_tab_indicator_ignore_child_padding,
207+
!indicatorStyle.have(INDICATOR_STYLE_CENTER)
208+
)
209+
202210
indicatorFlowStep =
203211
typedArray.getInt(R.styleable.DslTabLayout_tab_indicator_flow_step, indicatorFlowStep)
204212
indicatorEnableFlow = typedArray.getBoolean(
@@ -348,6 +356,24 @@ open class DslTabIndicator(val tabLayout: DslTabLayout) : DslGradientDrawable()
348356
}
349357
}
350358

359+
open fun getChildTargetPaddingLeft(childView: View): Int =
360+
if (ignoreChildPadding) childView.paddingLeft else 0
361+
362+
open fun getChildTargetPaddingRight(childView: View): Int =
363+
if (ignoreChildPadding) childView.paddingRight else 0
364+
365+
open fun getChildTargetPaddingTop(childView: View): Int =
366+
if (ignoreChildPadding) childView.paddingTop else 0
367+
368+
open fun getChildTargetPaddingBottom(childView: View): Int =
369+
if (ignoreChildPadding) childView.paddingBottom else 0
370+
371+
open fun getChildTargetWidth(childView: View): Int =
372+
if (ignoreChildPadding) childView.viewDrawWidth else childView.measuredWidth
373+
374+
open fun getChildTargetHeight(childView: View): Int =
375+
if (ignoreChildPadding) childView.viewDrawHeight else childView.measuredHeight
376+
351377
/**
352378
* [childview]对应的中心x坐标
353379
* */
@@ -360,13 +386,19 @@ open class DslTabIndicator(val tabLayout: DslTabLayout) : DslGradientDrawable()
360386
when (gravity) {
361387
INDICATOR_GRAVITY_START -> childView.left
362388
INDICATOR_GRAVITY_END -> childView.right
363-
else -> childView.left + childView.paddingLeft + childView.viewDrawWidth / 2
389+
else -> childView.left + getChildTargetPaddingLeft(childView) + getChildTargetWidth(
390+
childView
391+
) / 2
364392
}
365393
} else {
366394
when (gravity) {
367395
INDICATOR_GRAVITY_START -> childView.left + contentChildView.left
368396
INDICATOR_GRAVITY_END -> childView.left + contentChildView.right
369-
else -> childView.left + contentChildView.left + contentChildView.paddingLeft + contentChildView.viewDrawWidth / 2
397+
else -> childView.left + contentChildView.left + getChildTargetPaddingLeft(
398+
contentChildView
399+
) + getChildTargetWidth(
400+
contentChildView
401+
) / 2
370402
}
371403
}
372404
}
@@ -383,13 +415,19 @@ open class DslTabIndicator(val tabLayout: DslTabLayout) : DslGradientDrawable()
383415
when (gravity) {
384416
INDICATOR_GRAVITY_START -> childView.top
385417
INDICATOR_GRAVITY_END -> childView.bottom
386-
else -> childView.top + childView.paddingTop + childView.viewDrawHeight / 2
418+
else -> childView.top + getChildTargetPaddingTop(childView) + getChildTargetHeight(
419+
childView
420+
) / 2
387421
}
388422
} else {
389423
when (gravity) {
390424
INDICATOR_GRAVITY_START -> childView.top + contentChildView.top
391425
INDICATOR_GRAVITY_END -> childView.top + childView.bottom
392-
else -> childView.top + contentChildView.top + contentChildView.paddingTop + contentChildView.viewDrawHeight / 2
426+
else -> childView.top + contentChildView.top + getChildTargetPaddingTop(
427+
contentChildView
428+
) + getChildTargetHeight(
429+
contentChildView
430+
) / 2
393431
}
394432
}
395433
}
@@ -403,8 +441,7 @@ open class DslTabIndicator(val tabLayout: DslTabLayout) : DslGradientDrawable()
403441
when (indicatorWidth) {
404442
ViewGroup.LayoutParams.WRAP_CONTENT -> {
405443
tabLayout.dslSelector.visibleViewList.getOrNull(index)?.also { childView ->
406-
result =
407-
indicatorContentView(childView)?.viewDrawWidth ?: childView.viewDrawWidth
444+
result = getChildTargetWidth(indicatorContentView(childView) ?: childView)
408445
}
409446
}
410447
ViewGroup.LayoutParams.MATCH_PARENT -> {
@@ -423,8 +460,7 @@ open class DslTabIndicator(val tabLayout: DslTabLayout) : DslGradientDrawable()
423460
when (indicatorHeight) {
424461
ViewGroup.LayoutParams.WRAP_CONTENT -> {
425462
tabLayout.dslSelector.visibleViewList.getOrNull(index)?.also { childView ->
426-
result =
427-
indicatorContentView(childView)?.viewDrawHeight ?: childView.viewDrawHeight
463+
result = getChildTargetHeight(indicatorContentView(childView) ?: childView)
428464
}
429465
}
430466
ViewGroup.LayoutParams.MATCH_PARENT -> {

TabLayout/src/main/java/com/angcyo/tablayout/DslTabLayout.kt

+63-72
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import android.widget.LinearLayout
1717
import android.widget.OverScroller
1818
import android.widget.TextView
1919
import androidx.core.view.GestureDetectorCompat
20+
import androidx.core.view.GravityCompat
2021
import androidx.core.view.ViewCompat
2122
import kotlin.math.abs
2223
import kotlin.math.max
@@ -660,16 +661,17 @@ open class DslTabLayout(
660661
val visibleChildList = dslSelector.visibleViewList
661662
val visibleChildCount = visibleChildList.size
662663

664+
//控制最小大小
665+
val tabMinHeight = if (suggestedMinimumHeight > 0) {
666+
suggestedMinimumHeight
667+
} else {
668+
itemDefaultHeight
669+
}
670+
663671
if (visibleChildCount == 0) {
664672
setMeasuredDimension(
665673
getDefaultSize(suggestedMinimumWidth, widthMeasureSpec),
666-
getDefaultSize(
667-
if (suggestedMinimumHeight > 0) {
668-
suggestedMinimumHeight
669-
} else {
670-
itemDefaultHeight
671-
}, heightMeasureSpec
672-
)
674+
getDefaultSize(tabMinHeight, heightMeasureSpec)
673675
)
674676
return
675677
}
@@ -682,19 +684,10 @@ open class DslTabLayout(
682684

683685
_maxConvexHeight = 0
684686

685-
//child高度测量模式
686-
var childHeightSpec: Int = -1
687687
var childWidthSpec: Int = -1
688688

689-
//记录child最大的height, 用来实现tabLayout wrap_content
690-
var childMaxHeight = 0 //child最大的高度
691-
692-
childHeightSpec = if (heightMode == MeasureSpec.EXACTLY) {
693-
//固定高度
694-
exactlyMeasure(heightSize - paddingTop - paddingBottom)
695-
} else {
696-
atmostMeasure(Int.MAX_VALUE)
697-
}
689+
//记录child最大的height, 用来实现tabLayout wrap_content, 包括突出的大小
690+
var childMaxHeight = tabMinHeight //child最大的高度
698691

699692
if (heightMode == MeasureSpec.UNSPECIFIED) {
700693
if (heightSize == 0) {
@@ -776,74 +769,57 @@ open class DslTabLayout(
776769

777770
_childAllWidthSum = 0
778771

779-
var wrapContentHeight = false
780-
781772
//没有设置weight属性的child宽度总和, 用于计算剩余空间
782773
var allChildUsedWidth = 0
783774

784-
fun measureChild(childView: View) {
775+
fun measureChild(childView: View, heightSpec: Int? = null) {
785776
val lp = childView.layoutParams as LayoutParams
786777

787-
//横向布局, 不支持竖向margin支持
788-
lp.topMargin = 0
789-
lp.bottomMargin = 0
790-
791-
val childConvexHeight = lp.layoutConvexHeight
778+
//child高度测量模式
779+
var childHeightSpec: Int = -1
792780

793781
val widthHeight = calcLayoutWidthHeight(
794782
lp.layoutWidth, lp.layoutHeight,
795783
widthSize, heightSize, 0, 0
796784
)
797785

798-
//计算高度测量模式
799-
wrapContentHeight = false
800-
if (childHeightSpec == -1) {
786+
if (heightMode == MeasureSpec.EXACTLY) {
787+
//固定高度
788+
childHeightSpec =
789+
exactlyMeasure(heightSize - paddingTop - paddingBottom - lp.topMargin - lp.bottomMargin)
790+
} else {
801791
if (widthHeight[1] > 0) {
802792
heightSize = widthHeight[1]
803793
childHeightSpec = exactlyMeasure(heightSize)
804794
heightSize += paddingTop + paddingBottom
805-
}
806-
}
807-
808-
if (childHeightSpec == -1) {
809-
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT) {
810-
811-
heightSize = if (suggestedMinimumHeight > 0) {
812-
suggestedMinimumHeight
795+
} else {
796+
childHeightSpec = if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT) {
797+
exactlyMeasure(tabMinHeight)
813798
} else {
814-
itemDefaultHeight
799+
atmostMeasure(Int.MAX_VALUE)
815800
}
816-
817-
childHeightSpec = exactlyMeasure(heightSize)
818-
819-
heightSize += paddingTop + paddingBottom
820-
} else {
821-
childHeightSpec = atmostMeasure(heightSize)
822-
wrapContentHeight = true
823801
}
824802
}
803+
804+
val childConvexHeight = lp.layoutConvexHeight
805+
825806
//...end
826807

827808
//计算宽度测量模式
828809
childWidthSpec //no op
829810

830-
if (childConvexHeight > 0) {
831-
_maxConvexHeight = max(_maxConvexHeight, childConvexHeight)
832-
//需要凸起
833-
val childConvexHeightSpec = MeasureSpec.makeMeasureSpec(
834-
MeasureSpec.getSize(childHeightSpec) + childConvexHeight,
835-
MeasureSpec.getMode(childHeightSpec)
836-
)
837-
childView.measure(childWidthSpec, childConvexHeightSpec)
811+
if (heightSpec != null) {
812+
childView.measure(childWidthSpec, heightSpec)
838813
} else {
839814
childView.measure(childWidthSpec, childHeightSpec)
840815
}
841-
842-
if (wrapContentHeight) {
843-
heightSize = childView.measuredHeight
844-
childHeightSpec = exactlyMeasure(heightSize)
845-
heightSize += paddingTop + paddingBottom
816+
if (childConvexHeight > 0) {
817+
_maxConvexHeight = max(_maxConvexHeight, childConvexHeight)
818+
//需要凸起
819+
val spec = exactlyMeasure(childView.measuredHeight + childConvexHeight)
820+
childView.measure(childWidthSpec, spec)
846821
}
822+
childMaxHeight = max(childMaxHeight, childView.measuredHeight)
847823
}
848824

849825
visibleChildList.forEachIndexed { index, childView ->
@@ -919,9 +895,14 @@ open class DslTabLayout(
919895

920896
if (heightMode == MeasureSpec.AT_MOST) {
921897
//wrap_content 情况下, 重新测量所有子view
922-
childHeightSpec = exactlyMeasure(max(childMaxHeight, suggestedMinimumHeight))
898+
val childHeightSpec = exactlyMeasure(
899+
max(
900+
childMaxHeight - _maxConvexHeight,
901+
suggestedMinimumHeight - paddingTop - paddingBottom
902+
)
903+
)
923904
visibleChildList.forEach { childView ->
924-
measureChild(childView)
905+
measureChild(childView, childHeightSpec)
925906
}
926907
}
927908

@@ -936,7 +917,10 @@ open class DslTabLayout(
936917
itemDefaultHeight
937918
}
938919
} else if (heightMode != MeasureSpec.EXACTLY) {
939-
heightSize = max(childMaxHeight + paddingTop + paddingBottom, suggestedMinimumHeight)
920+
heightSize = max(
921+
childMaxHeight - _maxConvexHeight + paddingTop + paddingBottom,
922+
suggestedMinimumHeight
923+
)
940924
}
941925

942926
setMeasuredDimension(widthSize, heightSize + _maxConvexHeight)
@@ -1064,6 +1048,7 @@ open class DslTabLayout(
10641048
lp.marginEnd = 0
10651049

10661050
val childConvexHeight = lp.layoutConvexHeight
1051+
_maxConvexHeight = max(_maxConvexHeight, childConvexHeight)
10671052

10681053
val widthHeight = calcLayoutWidthHeight(
10691054
lp.layoutWidth, lp.layoutHeight,
@@ -1103,7 +1088,6 @@ open class DslTabLayout(
11031088
childHeightSpec //no op
11041089

11051090
if (childConvexHeight > 0) {
1106-
_maxConvexHeight = max(_maxConvexHeight, childConvexHeight)
11071091
//需要凸起
11081092
val childConvexWidthSpec = MeasureSpec.makeMeasureSpec(
11091093
MeasureSpec.getSize(childWidthSpec) + childConvexHeight,
@@ -1261,6 +1245,7 @@ open class DslTabLayout(
12611245
visibleChildList.forEachIndexed { index, childView ->
12621246

12631247
val lp = childView.layoutParams as LayoutParams
1248+
val verticalGravity = lp.gravity and Gravity.VERTICAL_GRAVITY_MASK
12641249

12651250
if (isRtl) {
12661251
right -= lp.marginEnd
@@ -1279,15 +1264,14 @@ open class DslTabLayout(
12791264
}
12801265
}
12811266

1282-
childBottom = if (lp.gravity.have(Gravity.CENTER_VERTICAL)) {
1283-
measuredHeight - paddingBottom -
1267+
childBottom = when (verticalGravity) {
1268+
Gravity.CENTER_VERTICAL -> measuredHeight - paddingBottom -
12841269
((measuredHeight - paddingTop - paddingBottom - _maxConvexHeight) / 2 -
12851270
childView.measuredHeight / 2)
1286-
} else {
1287-
measuredHeight - paddingBottom
1271+
Gravity.BOTTOM -> measuredHeight - paddingBottom
1272+
else -> paddingTop + lp.topMargin + childView.measuredHeight
12881273
}
12891274

1290-
/*默认垂直居中显示*/
12911275
if (isRtl) {
12921276
childView.layout(
12931277
right - childView.measuredWidth,
@@ -1332,6 +1316,9 @@ open class DslTabLayout(
13321316
visibleChildList.forEachIndexed { index, childView ->
13331317

13341318
val lp = childView.layoutParams as LayoutParams
1319+
val layoutDirection = 0
1320+
val absoluteGravity = GravityCompat.getAbsoluteGravity(lp.gravity, layoutDirection)
1321+
val horizontalGravity = absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK
13351322

13361323
top += lp.topMargin
13371324

@@ -1341,11 +1328,11 @@ open class DslTabLayout(
13411328
}
13421329
}
13431330

1344-
childLeft = if (lp.gravity.have(Gravity.CENTER_HORIZONTAL)) {
1345-
paddingStart + ((measuredWidth - paddingStart - paddingEnd - _maxConvexHeight) / 2 -
1331+
childLeft = when (horizontalGravity) {
1332+
Gravity.CENTER_HORIZONTAL -> paddingStart + ((measuredWidth - paddingStart - paddingEnd - _maxConvexHeight) / 2 -
13461333
childView.measuredWidth / 2)
1347-
} else {
1348-
paddingStart
1334+
Gravity.RIGHT -> measuredWidth - paddingRight - childView.measuredWidth - lp.rightMargin
1335+
else -> paddingLeft + lp.leftMargin
13491336
}
13501337

13511338
/*默认水平居中显示*/
@@ -1433,7 +1420,11 @@ open class DslTabLayout(
14331420
a.recycle()
14341421

14351422
if (gravity == UNSPECIFIED_GRAVITY) {
1436-
gravity = Gravity.CENTER
1423+
gravity = if (layoutConvexHeight > 0) {
1424+
Gravity.BOTTOM
1425+
} else {
1426+
Gravity.CENTER
1427+
}
14371428
}
14381429
}
14391430

TabLayout/src/main/res/values/attr_dsl_tab_layout.xml

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
<attr name="tab_indicator_gradient_colors" format="string" />
114114
<attr name="tab_indicator_gradient_start_color" format="color" />
115115
<attr name="tab_indicator_gradient_end_color" format="color" />
116+
<attr name="tab_indicator_ignore_child_padding" format="boolean" />
116117
<!--end...-->
117118

118119
<!--TabLayoutConfig 相关属性-->

0 commit comments

Comments
 (0)