@@ -17,6 +17,7 @@ import android.widget.LinearLayout
17
17
import android.widget.OverScroller
18
18
import android.widget.TextView
19
19
import androidx.core.view.GestureDetectorCompat
20
+ import androidx.core.view.GravityCompat
20
21
import androidx.core.view.ViewCompat
21
22
import kotlin.math.abs
22
23
import kotlin.math.max
@@ -660,16 +661,17 @@ open class DslTabLayout(
660
661
val visibleChildList = dslSelector.visibleViewList
661
662
val visibleChildCount = visibleChildList.size
662
663
664
+ // 控制最小大小
665
+ val tabMinHeight = if (suggestedMinimumHeight > 0 ) {
666
+ suggestedMinimumHeight
667
+ } else {
668
+ itemDefaultHeight
669
+ }
670
+
663
671
if (visibleChildCount == 0 ) {
664
672
setMeasuredDimension(
665
673
getDefaultSize(suggestedMinimumWidth, widthMeasureSpec),
666
- getDefaultSize(
667
- if (suggestedMinimumHeight > 0 ) {
668
- suggestedMinimumHeight
669
- } else {
670
- itemDefaultHeight
671
- }, heightMeasureSpec
672
- )
674
+ getDefaultSize(tabMinHeight, heightMeasureSpec)
673
675
)
674
676
return
675
677
}
@@ -682,19 +684,10 @@ open class DslTabLayout(
682
684
683
685
_maxConvexHeight = 0
684
686
685
- // child高度测量模式
686
- var childHeightSpec: Int = - 1
687
687
var childWidthSpec: Int = - 1
688
688
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最大的高度
698
691
699
692
if (heightMode == MeasureSpec .UNSPECIFIED ) {
700
693
if (heightSize == 0 ) {
@@ -776,74 +769,57 @@ open class DslTabLayout(
776
769
777
770
_childAllWidthSum = 0
778
771
779
- var wrapContentHeight = false
780
-
781
772
// 没有设置weight属性的child宽度总和, 用于计算剩余空间
782
773
var allChildUsedWidth = 0
783
774
784
- fun measureChild (childView : View ) {
775
+ fun measureChild (childView : View , heightSpec : Int? = null ) {
785
776
val lp = childView.layoutParams as LayoutParams
786
777
787
- // 横向布局, 不支持竖向margin支持
788
- lp.topMargin = 0
789
- lp.bottomMargin = 0
790
-
791
- val childConvexHeight = lp.layoutConvexHeight
778
+ // child高度测量模式
779
+ var childHeightSpec: Int = - 1
792
780
793
781
val widthHeight = calcLayoutWidthHeight(
794
782
lp.layoutWidth, lp.layoutHeight,
795
783
widthSize, heightSize, 0 , 0
796
784
)
797
785
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 {
801
791
if (widthHeight[1 ] > 0 ) {
802
792
heightSize = widthHeight[1 ]
803
793
childHeightSpec = exactlyMeasure(heightSize)
804
794
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)
813
798
} else {
814
- itemDefaultHeight
799
+ atmostMeasure( Int . MAX_VALUE )
815
800
}
816
-
817
- childHeightSpec = exactlyMeasure(heightSize)
818
-
819
- heightSize + = paddingTop + paddingBottom
820
- } else {
821
- childHeightSpec = atmostMeasure(heightSize)
822
- wrapContentHeight = true
823
801
}
824
802
}
803
+
804
+ val childConvexHeight = lp.layoutConvexHeight
805
+
825
806
// ...end
826
807
827
808
// 计算宽度测量模式
828
809
childWidthSpec // no op
829
810
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)
838
813
} else {
839
814
childView.measure(childWidthSpec, childHeightSpec)
840
815
}
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)
846
821
}
822
+ childMaxHeight = max(childMaxHeight, childView.measuredHeight)
847
823
}
848
824
849
825
visibleChildList.forEachIndexed { index, childView ->
@@ -919,9 +895,14 @@ open class DslTabLayout(
919
895
920
896
if (heightMode == MeasureSpec .AT_MOST ) {
921
897
// wrap_content 情况下, 重新测量所有子view
922
- childHeightSpec = exactlyMeasure(max(childMaxHeight, suggestedMinimumHeight))
898
+ val childHeightSpec = exactlyMeasure(
899
+ max(
900
+ childMaxHeight - _maxConvexHeight ,
901
+ suggestedMinimumHeight - paddingTop - paddingBottom
902
+ )
903
+ )
923
904
visibleChildList.forEach { childView ->
924
- measureChild(childView)
905
+ measureChild(childView, childHeightSpec )
925
906
}
926
907
}
927
908
@@ -936,7 +917,10 @@ open class DslTabLayout(
936
917
itemDefaultHeight
937
918
}
938
919
} else if (heightMode != MeasureSpec .EXACTLY ) {
939
- heightSize = max(childMaxHeight + paddingTop + paddingBottom, suggestedMinimumHeight)
920
+ heightSize = max(
921
+ childMaxHeight - _maxConvexHeight + paddingTop + paddingBottom,
922
+ suggestedMinimumHeight
923
+ )
940
924
}
941
925
942
926
setMeasuredDimension(widthSize, heightSize + _maxConvexHeight )
@@ -1064,6 +1048,7 @@ open class DslTabLayout(
1064
1048
lp.marginEnd = 0
1065
1049
1066
1050
val childConvexHeight = lp.layoutConvexHeight
1051
+ _maxConvexHeight = max(_maxConvexHeight , childConvexHeight)
1067
1052
1068
1053
val widthHeight = calcLayoutWidthHeight(
1069
1054
lp.layoutWidth, lp.layoutHeight,
@@ -1103,7 +1088,6 @@ open class DslTabLayout(
1103
1088
childHeightSpec // no op
1104
1089
1105
1090
if (childConvexHeight > 0 ) {
1106
- _maxConvexHeight = max(_maxConvexHeight , childConvexHeight)
1107
1091
// 需要凸起
1108
1092
val childConvexWidthSpec = MeasureSpec .makeMeasureSpec(
1109
1093
MeasureSpec .getSize(childWidthSpec) + childConvexHeight,
@@ -1261,6 +1245,7 @@ open class DslTabLayout(
1261
1245
visibleChildList.forEachIndexed { index, childView ->
1262
1246
1263
1247
val lp = childView.layoutParams as LayoutParams
1248
+ val verticalGravity = lp.gravity and Gravity .VERTICAL_GRAVITY_MASK
1264
1249
1265
1250
if (isRtl) {
1266
1251
right - = lp.marginEnd
@@ -1279,15 +1264,14 @@ open class DslTabLayout(
1279
1264
}
1280
1265
}
1281
1266
1282
- childBottom = if (lp.gravity.have( Gravity . CENTER_VERTICAL ) ) {
1283
- measuredHeight - paddingBottom -
1267
+ childBottom = when (verticalGravity ) {
1268
+ Gravity . CENTER_VERTICAL -> measuredHeight - paddingBottom -
1284
1269
((measuredHeight - paddingTop - paddingBottom - _maxConvexHeight ) / 2 -
1285
1270
childView.measuredHeight / 2 )
1286
- } else {
1287
- measuredHeight - paddingBottom
1271
+ Gravity . BOTTOM -> measuredHeight - paddingBottom
1272
+ else -> paddingTop + lp.topMargin + childView.measuredHeight
1288
1273
}
1289
1274
1290
- /* 默认垂直居中显示*/
1291
1275
if (isRtl) {
1292
1276
childView.layout(
1293
1277
right - childView.measuredWidth,
@@ -1332,6 +1316,9 @@ open class DslTabLayout(
1332
1316
visibleChildList.forEachIndexed { index, childView ->
1333
1317
1334
1318
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
1335
1322
1336
1323
top + = lp.topMargin
1337
1324
@@ -1341,11 +1328,11 @@ open class DslTabLayout(
1341
1328
}
1342
1329
}
1343
1330
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 -
1346
1333
childView.measuredWidth / 2 )
1347
- } else {
1348
- paddingStart
1334
+ Gravity . RIGHT -> measuredWidth - paddingRight - childView.measuredWidth - lp.rightMargin
1335
+ else -> paddingLeft + lp.leftMargin
1349
1336
}
1350
1337
1351
1338
/* 默认水平居中显示*/
@@ -1433,7 +1420,11 @@ open class DslTabLayout(
1433
1420
a.recycle()
1434
1421
1435
1422
if (gravity == UNSPECIFIED_GRAVITY ) {
1436
- gravity = Gravity .CENTER
1423
+ gravity = if (layoutConvexHeight > 0 ) {
1424
+ Gravity .BOTTOM
1425
+ } else {
1426
+ Gravity .CENTER
1427
+ }
1437
1428
}
1438
1429
}
1439
1430
0 commit comments