2929 */
3030@ SuppressWarnings ({"unused" , "UnusedReturnValue" })
3131public class TitleBar extends FrameLayout
32- implements View .OnClickListener {
32+ implements View .OnClickListener ,
33+ View .OnLayoutChangeListener {
3334
3435 private static final String LOG_TAG = "TitleBar" ;
3536
@@ -274,8 +275,7 @@ public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
274275 addView (mRightView , 2 );
275276 addView (mLineView , 3 );
276277
277- addOnLayoutChangeListener (mConstraintChildViewWidthListener );
278- addOnLayoutChangeListener (mLimitChildViewStatusListener );
278+ addOnLayoutChangeListener (this );
279279
280280 // 如果当前是布局预览模式
281281 if (isInEditMode ()) {
@@ -291,6 +291,72 @@ public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
291291 }
292292 }
293293
294+ @ Override
295+ protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
296+ super .onMeasure (widthMeasureSpec , heightMeasureSpec );
297+
298+ // 如果当前是布局预览模式,避免影响布局预览
299+ if (isInEditMode ()) {
300+ return ;
301+ }
302+
303+ int titleBarWidth = this .getMeasuredWidth ();
304+ int leftViewWidth = mLeftView .getMeasuredWidth ();
305+ int centerViewWidth = mTitleView .getMeasuredWidth ();
306+ int rightViewWidth = mRightView .getMeasuredWidth ();
307+
308+ int maxEdgeWidth = Math .max (leftViewWidth , rightViewWidth );
309+ int calculateTotalWidth = maxEdgeWidth * 2 + centerViewWidth ;
310+ // 算出来总宽度是否大于标题栏的宽度
311+ if (calculateTotalWidth <= titleBarWidth ) {
312+ return ;
313+ }
314+
315+ // 判断是左右项太长还是标题项太长
316+ if (maxEdgeWidth > titleBarWidth / 3 ) {
317+ // 如果是左右项太长,那么就进行动态计算
318+ measureChildWithMargins (mLeftView , MeasureSpec .makeMeasureSpec (titleBarWidth / 4 , MeasureSpec .EXACTLY ), 0 ,
319+ MeasureSpec .makeMeasureSpec (mLeftView .getMeasuredHeight (), MeasureSpec .EXACTLY ), 0 );
320+ measureChildWithMargins (mTitleView , MeasureSpec .makeMeasureSpec (titleBarWidth / 2 , MeasureSpec .EXACTLY ), 0 ,
321+ MeasureSpec .makeMeasureSpec (mTitleView .getMeasuredHeight (), MeasureSpec .EXACTLY ), 0 );
322+ measureChildWithMargins (mRightView , MeasureSpec .makeMeasureSpec (titleBarWidth / 4 , MeasureSpec .EXACTLY ), 0 ,
323+ MeasureSpec .makeMeasureSpec (mRightView .getMeasuredHeight (), MeasureSpec .EXACTLY ), 0 );
324+ } else {
325+ // 如果是标题项太长,那么就进行动态计算
326+ measureChildWithMargins (mLeftView , MeasureSpec .makeMeasureSpec (maxEdgeWidth , MeasureSpec .EXACTLY ), 0 ,
327+ MeasureSpec .makeMeasureSpec (mLeftView .getMeasuredHeight (), MeasureSpec .EXACTLY ), 0 );
328+ measureChildWithMargins (mTitleView , MeasureSpec .makeMeasureSpec (titleBarWidth - maxEdgeWidth * 2 , MeasureSpec .EXACTLY ), 0 ,
329+ MeasureSpec .makeMeasureSpec (mTitleView .getMeasuredHeight (), MeasureSpec .EXACTLY ), 0 );
330+ measureChildWithMargins (mRightView , MeasureSpec .makeMeasureSpec (maxEdgeWidth , MeasureSpec .EXACTLY ), 0 ,
331+ MeasureSpec .makeMeasureSpec (mRightView .getMeasuredHeight (), MeasureSpec .EXACTLY ), 0 );
332+ }
333+ }
334+
335+ @ Override
336+ public void onLayoutChange (View v , int left , int top , int right , int bottom , int oldLeft , int oldTop , int oldRight , int oldBottom ) {
337+ // 解决在外部触摸时触发点击效果的问题
338+ if (!mLeftView .isClickable ()) {
339+ mLeftView .setClickable (true );
340+ }
341+ if (!mTitleView .isClickable ()) {
342+ mTitleView .setClickable (true );
343+ }
344+ if (!mRightView .isClickable ()) {
345+ mRightView .setClickable (true );
346+ }
347+
348+ // TextView 里面必须有东西才能被点击
349+ if (!mLeftView .isEnabled ()) {
350+ mLeftView .setEnabled (TitleBarSupport .isContainContent (mLeftView ));
351+ }
352+ if (!mTitleView .isEnabled ()) {
353+ mTitleView .setEnabled (TitleBarSupport .isContainContent (mTitleView ));
354+ }
355+ if (!mRightView .isEnabled ()) {
356+ mRightView .setEnabled (TitleBarSupport .isContainContent (mRightView ));
357+ }
358+ }
359+
294360 /**
295361 * {@link View.OnClickListener}
296362 */
@@ -880,80 +946,4 @@ public ITitleBarStyle getCurrentStyle() {
880946 public static void setDefaultStyle (ITitleBarStyle style ) {
881947 sGlobalStyle = style ;
882948 }
883-
884- private final View .OnLayoutChangeListener mConstraintChildViewWidthListener = new OnLayoutChangeListener () {
885-
886- @ Override
887- public void onLayoutChange (View v , int left , int top , int right , int bottom , int oldLeft , int oldTop , int oldRight , int oldBottom ) {
888- // 暂时先移除当前的监听,因为 TextView.setMaxWidth 方法会重新触发监听
889- removeOnLayoutChangeListener (this );
890-
891- // 标题栏子 View 最大宽度限制算法
892- post (() -> {
893- // 这里要延迟执行,否则会导致子 View.getWidth 的时候为零
894- int titleBarWidth = right - left ;
895- int leftViewWidth = mLeftView .getWidth ();
896- int centerViewWidth = mTitleView .getWidth ();
897- int rightViewWidth = mRightView .getWidth ();
898-
899- int maxEdgeWidth = Math .max (leftViewWidth , rightViewWidth );
900- int calculateTotalWidth = maxEdgeWidth * 2 + centerViewWidth ;
901- // 算出来子 View 的宽大于标题栏的宽度
902- if (calculateTotalWidth >= titleBarWidth ) {
903- // 判断是左右项太长还是标题项太长
904- if (maxEdgeWidth > titleBarWidth / 3 ) {
905- // 如果是左右项太长,那么按照比例进行划分
906- TitleBarSupport .setMaxWidth (mLeftView , titleBarWidth / 4 );
907- TitleBarSupport .setMaxWidth (mTitleView , titleBarWidth / 2 );
908- TitleBarSupport .setMaxWidth (mRightView , titleBarWidth / 4 );
909- } else {
910- // 如果是标题项太长,那么就进行动态计算
911- TitleBarSupport .setMaxWidth (mLeftView , maxEdgeWidth );
912- TitleBarSupport .setMaxWidth (mTitleView , titleBarWidth - maxEdgeWidth * 2 );
913- TitleBarSupport .setMaxWidth (mRightView , maxEdgeWidth );
914- }
915- } else {
916- // 不限制子 View 的最大宽度
917- TitleBarSupport .setMaxWidth (mLeftView , Integer .MAX_VALUE );
918- TitleBarSupport .setMaxWidth (mTitleView , Integer .MAX_VALUE );
919- TitleBarSupport .setMaxWidth (mRightView , Integer .MAX_VALUE );
920- }
921-
922- removeCallbacks (mAddOnLayoutChangeListenerRunnable );
923- // 这里再次监听需要延迟,否则会导致递归的情况发生
924- post (mAddOnLayoutChangeListenerRunnable );
925- });
926- }
927- };
928-
929- @ SuppressWarnings ("all" )
930- private final View .OnLayoutChangeListener mLimitChildViewStatusListener = new OnLayoutChangeListener () {
931-
932- @ Override
933- public void onLayoutChange (View v , int left , int top , int right , int bottom , int oldLeft , int oldTop , int oldRight , int oldBottom ) {
934- // 解决在外部触摸时触发点击效果的问题
935- if (!mLeftView .isClickable ()) {
936- mLeftView .setClickable (true );
937- }
938- if (!mTitleView .isClickable ()) {
939- mTitleView .setClickable (true );
940- }
941- if (!mRightView .isClickable ()) {
942- mRightView .setClickable (true );
943- }
944-
945- // TextView 里面必须有东西才能被点击
946- if (!mLeftView .isEnabled ()) {
947- mLeftView .setEnabled (TitleBarSupport .isContainContent (mLeftView ));
948- }
949- if (!mTitleView .isEnabled ()) {
950- mTitleView .setEnabled (TitleBarSupport .isContainContent (mTitleView ));
951- }
952- if (!mRightView .isEnabled ()) {
953- mRightView .setEnabled (TitleBarSupport .isContainContent (mRightView ));
954- }
955- }
956- };
957-
958- private final Runnable mAddOnLayoutChangeListenerRunnable = () -> addOnLayoutChangeListener (mConstraintChildViewWidthListener );
959949}
0 commit comments