Aligning drawableLeft with text of button

后端 未结 14 1972
长情又很酷
长情又很酷 2021-01-30 06:41

Here is my layout:

\"enter

The issue I\'m facing is with the drawable checkmark. H

相关标签:
14条回答
  • 2021-01-30 07:18

    I had the same issue, and I've come up with a solution that doesn't require XML changes or custom Views.

    This code snippet retrieves the width of the text and the left/right drawables, and sets the Button's left/right padding so there will only be enough space to draw the text and the drawables, and no more padding will be added. This can be applied to Buttons as well as TextViews, their superclasses.

    public class TextViewUtils {
        private static final int[] LEFT_RIGHT_DRAWABLES = new int[]{0, 2};
    
        public static void setPaddingForCompoundDrawableNextToText(final TextView textView) {
            ViewTreeObserver vto = textView.getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    shinkRoomForHorizontalSpace(textView);
                }
            });
    
        }
    
        private static void shinkRoomForHorizontalSpace(TextView textView) {
            int textWidth = getTextWidth(textView);
            int sideCompoundDrawablesWidth = getSideCompoundDrawablesWidth(textView);
            int contentWidth = textWidth + sideCompoundDrawablesWidth;
            int innerWidth = getInnerWidth(textView);
            int totalPadding = innerWidth - contentWidth;
            textView.setPadding(totalPadding / 2, 0, totalPadding / 2, 0);
        }
    
        private static int getTextWidth(TextView textView) {
            String text = textView.getText().toString();
            Paint textPaint = textView.getPaint();
            Rect bounds = new Rect();
            textPaint.getTextBounds(text, 0, text.length(), bounds);
            return bounds.width();
        }
    
        private static int getSideCompoundDrawablesWidth(TextView textView) {
            int sideCompoundDrawablesWidth = 0;
            Drawable[] drawables = textView.getCompoundDrawables();
            for (int drawableIndex : LEFT_RIGHT_DRAWABLES) {
                Drawable drawable = drawables[drawableIndex];
                if (drawable == null)
                    continue;
                int width = drawable.getBounds().width();
                sideCompoundDrawablesWidth += width;
            }
            return sideCompoundDrawablesWidth;
        }
    
        private static int getInnerWidth(TextView textView) {
            Rect backgroundPadding = new Rect();
            textView.getBackground().getPadding(backgroundPadding);
            return textView.getWidth() - backgroundPadding.left - backgroundPadding.right;
        }
    }
    

    Notice that:

    • It actually still leaves some more space than needed (good enough for my purposes, but you may look for the error)
    • It overwrites whatever left/right padding is there. I guess it's not difficult to fix that.

    To use it, just call TextViewUtils.setPaddingForCompoundDrawableNextToText(button) on your onCreate or onViewCreated().

    0 讨论(0)
  • 2021-01-30 07:19

    Solution 1

    Set android:paddingLeft inside your first button. This will force the drawableLeft by paddingLeft amount to the right. This is the fast/hacky solution.

    Solution 2

    Instead of using a ButtonView, use a LinearLayout that contains both a textview and imageview. This is a better solution. It gives you more flexibility in the positioning of the checkmark.

    Replace your ButtonView with the following code. You need the LinearLayout and TextView to use buttonBarButtonStyle so that the background colors are correct on selection and the text size is correct. You need to set android:background="#0000" for the children, so that only the LinearLayout handles the background coloring.

    <LinearLayout
        style="?android:attr/buttonBarButtonStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="horizontal" >
        <ImageView 
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="false"
            android:background="#0000"
            android:src="@drawable/ic_checkmark_holo_light"/>
        <TextView
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:clickable="false"
            android:background="#0000"
            android:text="Done" />
    </LinearLayout>
    

    Here are some screenshots I took while trying this out.

    enter image description here enter image description here enter image description here

    0 讨论(0)
提交回复
热议问题