将文本保留在 TextView 中,drawableLeft 居中

Posted

技术标签:

【中文标题】将文本保留在 TextView 中,drawableLeft 居中【英文标题】:Keep text in TextView with drawableLeft centered 【发布时间】:2012-06-30 23:30:37 【问题描述】:

在我的应用程序中,我有一个标题栏,它由一个以 fill_parent 作为宽度的文本视图组成,它具有特定的背景颜色和一些居中的文本。现在我想在标题栏的左侧添加一个drawable,所以我设置了drawableLeft,果然显示了文本和图像。但是这里的问题是文本不再正确居中,例如,当添加可绘制对象时,文本会向右移动一点,如下面的屏幕截图所示:

我是否可以在不使用其他布局项(例如 LinearLayout)的情况下正确地将文本居中并将可绘制对象放置在上方?

【问题讨论】:

是否可以在中心也可以绘制?? 【参考方案1】:

虽然很脆弱,但您可以通过在可绘制对象上设置 negative 填充来避免使用包装布局:

<TextView
    android:layout_
    android:layout_
    android:layout_centerHorizontal="true"
    android:drawableLeft="@drawable/icon"
    android:drawablePadding="-20sp"
    android:text="blah blah blah" />

您必须将填充调整为可绘制对象的宽度,但您只剩下一个 TextView 而不是额外的 LinearLayout 等。

【讨论】:

我觉得 android:drawablePadding="-20sp" 不正确,你应该改用 android:gravity="center" ! 你应该通过获取你设置的drawable的确切宽度来完成java代码。重心不起作用 像这样设置可绘制填充可能在不同的 API 上有不同的行为。像这样使用它也不安全。 @cwhsu 设置android:gravity="center" 如果RelativeLayout 是父级会有不同的效果。 如果您有动态按钮大小,那么不幸的是,这不是您的灵丹妙药。所以要么做一个自定义视图,要么把它包装在一个视图组中——这太烦人了……【参考方案2】:

您可以将TextView的父级设置为宽度为match_parent的RelativeLayout。

<RelativeLayout
    android:layout_
    android:layout_>

<TextView
        android:id="@+id/edit_location_text_view"
        android:layout_
        android:layout_
        android:layout_above="@id/add_location_text_view"
        android:gravity="start|center_vertical"
        android:layout_centerHorizontal="true"
        android:drawableStart="@android:drawable/ic_menu_edit"
        android:text="Edit Location" />

</RelativeLayout>

【讨论】:

【参考方案3】:

我也遇到过类似的问题。通过使用带有layout_width="wrap_content"layout_gravity="center" 参数的单个TextView 来解决它:

<TextView
    android:layout_
    android:layout_
    android:drawableLeft="@drawable/some_drawable"
    android:text="some text"
    android:layout_gravity="center"
    android:gravity="center"
    />

【讨论】:

如果宽度是wrap_content,那么中心点是什么?当宽度设置为 match_parent 或其他值时,棘手的部分是居中。最好指出这种情况。【参考方案4】:

尝试以下操作:

<TextView
    android:id="@+id/textView"
    android:layout_
    android:layout_
    android:layout_gravity="center_horizontal"
    android:padding="10dp"
    android:textAlignment="center" />

【讨论】:

谢谢,这应该是公认的答案。 @雅各布【参考方案5】:

您可以使用android:gravity="center_vertical" 将文本与图像垂直居中。或者可以使用 android:gravity="center" 在 textView 中居中。

<TextView
    android:layout_
    android:layout_
    android:gravity="center"
    android:drawableLeft="@drawable/icon"
    android:text="Your text here" />

【讨论】:

【参考方案6】:

这样用

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="@color/White"
     >
  
  <RelativeLayout
       android:id="@+id/rlheader"
       android:layout_
       android:layout_
       android:layout_alignParentTop="true"
       android:background="@color/HeaderColor"
      
        >
 
        <TextView
           
           android:layout_
           android:layout_
           android:layout_centerHorizontal="true"
           android:layout_centerVertical="true"
           android:text="Header_Title"
            />
 
        <ImageView
           android:id="@+id/ivSetting"
           android:layout_
           android:layout_
           android:layout_alignParentLeft="true"
           android:layout_centerVertical="true"
           android:layout_marginLeft="10dp"
           android:src="@drawable/setting" />
 
        
    </RelativeLayout>

</RelativeLayout>
      

它看起来像我的演示项目的这张快照

【讨论】:

谢谢,难道不能在线性布局中做类似的事情,还是我需要在某处使用相对布局? 你可以使用父布局作为线性布局,它适用于你,但子布局是相对的,我放置的 imageview 和 textview 保持原样 为什么在 Android 应用中使用这种 ios 风格的后退按钮? @ChristopherPerry 因为客户的要求 IMO,作为 Android 开发人员,您的工作是为您的客户提供有关 Android 平台的服务,告知客户这是 iOS 模式而非 Android 模式。如果他们仍然坚持并找到另一个客户,我会坚决拒绝实施。【参考方案7】:

这对我有用。

<LinearLayout
    android:layout_
    android:layout_
    android:gravity="center"
    android:orientation="horizontal">

    <TextView
        android:layout_
        android:layout_
        android:drawableLeft="@drawable/trusted"
        android:gravity="center"
        android:text="@string/trusted"/>

</LinearLayout>

【讨论】:

【参考方案8】:
> This line is important ->> android:gravity="start|center_vertical


 <LinearLayout
            android:layout_
            android:layout_margin="@dimen/marginplus2"
            android:layout_>

            <TextView
                android:layout_
                android:layout_weight="1"
                android:text="@string/like"
                android:gravity="start|center_vertical"
                android:drawablePadding="@dimen/marginplus1"
                android:drawableLeft="@drawable/ic_like"
                android:layout_ />

            <TextView
                android:layout_
                android:layout_weight="1.5"
                android:text="@string/comments"
                android:drawablePadding="@dimen/marginplus1"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/ic_comment"
                android:layout_ />
            <TextView
                android:layout_
                android:layout_weight="1"
                android:text="@string/share"
                android:drawablePadding="@dimen/marginplus1"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/ic_share"
                android:layout_ />

        </LinearLayout>

【讨论】:

【参考方案9】:

我遇到了同样的问题,我通过对 Textview 的小改动解决了它,

<TextView
    android:layout_
    android:layout_
    android:gravity="center"
    android:drawableLeft="@drawable/search_red"
    android:text="your text goes here"
    />

【讨论】:

这不起作用,drawable 将转到 View 的左侧。只有文本会居中。 它不适用于宽度作为 match_parent。它将使用宽度作为 wrap_content。 这应该行不通。 Drawable 将左对齐。 根本不起作用。可绘制对象只是转到左侧。并且文本仅居中。【参考方案10】:

drawable 是 TextView 的一部分,所以如果你的文本高度小于 drawable 的高度,那么 textview 的高度就是 drawable 的高度。

可以将TextView的重力属性设置为center_vertical,这样文字就会居中。

【讨论】:

【参考方案11】:

一个简单的解决方案是在文本视图的另一侧使用相同大小的透明图像。 在我的示例中,我复制了我的实际 vector_image 并将颜色更改为透明。

<TextView
        android:id="@+id/name"
        style="@style/TextStyle"
        android:layout_
        android:layout_
        android:drawableEnd="@drawable/ic_vector_caret_down_green"
        android:drawableStart="@drawable/ic_vector_space_18"
        android:gravity="center"
        android:padding="12dp"
        android:textColor="@color/green"/>

【讨论】:

【参考方案12】:

接受的答案对我不起作用,如果 TextView 宽度与父级匹配,我使用 FrameLayout 完成。

 <FrameLayout
        android:layout_
        android:layout_
        android:layout_marginTop="10dp"
        android:background="#000">

        <TextView
            android:layout_
            android:layout_
            android:layout_gravity="center"
            android:drawableStart="@drawable/ic_circle_check_white"
            android:drawablePadding="10dp"
            android:text="Header"
            android:textColor="#fff"
            android:textSize="14sp"/>

    </FrameLayout>

【讨论】:

【参考方案13】:

你可以这样设置你的标题

<RelativeLayout
             android:id="@+id/linearLayout1"
             android:layout_
             android:layout_
             android:background="@drawable/head" >

             <ImageView
                 android:id="@+id/cat"
                 android:layout_
                 android:layout_

                 android:layout_marginLeft="5dp"
                 android:onClick="onClick"
                 android:layout_marginTop="10dp"
                 android:src="@drawable/btn_back_" />


         <RelativeLayout
             android:id="@+id/linearLayout1"
             android:layout_
             android:layout_
             android:gravity="center" >

           <TextView
 android:id="@+id/TvTitle"
 android:layout_
 android:layout_
 android:text=""
 android:layout_marginLeft="10dp"
 android:layout_marginRight="10dp"
 android:textColor="#000000" 

 android:textSize="20sp"/>
             </RelativeLayout>

         </RelativeLayout>

只需根据您的需要提供 Textview 的 Hieght、图像源

【讨论】:

我意识到有多种方法可以做到这一点,包括您的上述答案,但是我确实希望尝试限制布局中的元素数量,因此我正在寻找一种仅使用一个 textview 的解决方案,或者关于这是否可能的知识。【参考方案14】:
<TextView
    android:id="@+id/distance"
    android:layout_
    android:layout_
    android:layout_gravity="center_horizontal"
    android:drawableLeft="@drawable/distance"
    android:drawablePadding="10dp"
    android:padding="10dp"
    android:textAlignment="center"
    android:textColor="#ffffff"
    android:textSize="20sp" />

【讨论】:

【参考方案15】:

如果以上解决方案都不适合您?然后尝试以下答案

设计的示例屏幕截图。

对于上图,请在下面找到代码。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_>

    <android.support.v7.widget.CardView
        android:id="@+id/my_card"
        android:layout_
        android:layout_>

        <LinearLayout
            android:id="@+id/bb"
            android:layout_
            android:layout_
            android:divider="@color/gray"
            android:orientation="horizontal"
            android:weightSum="2">

            <TextView
                android:id="@+id/filter_tv"
                style="?android:attr/buttonBarButtonStyle"
                android:layout_
                android:layout_
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:drawableLeft="@drawable/ic_baseline_filter_list"
                android:gravity="center|fill_horizontal"
                android:paddingLeft="60dp"
                android:text="Filter"
                android:textAllCaps="false"
                android:textStyle="normal" />

            <View
                android:layout_
                android:layout_
                android:layout_below="@+id/bb"
                android:background="@color/gray" />

            <TextView
                android:id="@+id/sort_tv"
                style="?android:attr/buttonBarButtonStyle"
                android:layout_
                android:layout_
                android:layout_gravity="center|center_horizontal"
                android:layout_weight="1"
                android:drawableLeft="@drawable/ic_baseline_sort"
                android:drawablePadding="20dp"
                android:gravity="center|fill_horizontal"
                android:paddingLeft="40dp"
                android:text="Sort"
                android:textAllCaps="false" />

        </LinearLayout>
    </android.support.v7.widget.CardView>

    <View
        android:layout_
        android:layout_
        android:layout_below="@+id/my_card"
        android:background="@color/gray" />
</RelativeLayout>

【讨论】:

【参考方案16】:

最好的方法是使用ConstraintLayout,让textview在布局的中心和宽度warp_content(现在不要使用0dp) 这样drawable就会跟随文本。

<TextView
    android:id="@+id/tv_test"
    android:layout_
    android:layout_
    android:text="test"
    android:drawableLeft="@drawable/you_drawable"
    android:drawablePadding="5dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    />

【讨论】:

【参考方案17】:

尝试流动:

public class DrawableCenterTextView extends AppCompatTextView 

    public DrawableCenterTextView(Context context, AttributeSet attrs,
                                  int defStyle) 
        super(context, attrs, defStyle);
    

    public DrawableCenterTextView(Context context, AttributeSet attrs) 
        super(context, attrs);
    

    public DrawableCenterTextView(Context context) 
        super(context);
    

    @Override
    protected void onDraw(Canvas canvas) 
        // We want the icon and/or text grouped together and centered as a group.
        // We need to accommodate any existing padding
        final float buttonContentWidth = getWidth() - getPaddingLeft() - getPaddingRight();

        float textWidth = 0f;
        final Layout layout = getLayout();
        if (layout != null) 
            for (int i = 0; i < layout.getLineCount(); i++) 
                textWidth = Math.max(textWidth, layout.getLineRight(i));
            
        

        // Compute left drawable width, if any
        Drawable[] drawables = getCompoundDrawables();
        Drawable drawableLeft = drawables[0];

        int drawableWidth = (drawableLeft != null) ? drawableLeft.getIntrinsicWidth() : 0;

        // We only count the drawable padding if there is both an icon and text
        int drawablePadding = ((textWidth > 0) && (drawableLeft != null)) ? getCompoundDrawablePadding() : 0;

        // Adjust contents to center
        float bodyWidth = textWidth + drawableWidth + drawablePadding;
        int translate = (int) ((buttonContentWidth - bodyWidth));
        if (translate != 0)
            setPadding(translate, 0, translate, 0);
        super.onDraw(canvas);
    

【讨论】:

不知道为什么你被否决了,这是一个比这里一半赞成的答案更好的解决方案。但是,您应该添加说明为什么这样做。【参考方案18】:

不要测试太多,另一种方式

    class CenterDrawableToggleButton @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
    ) : AppCompatToggleButton(context, attrs, defStyleAttr) 

        private val centerMatrix = Matrix()

        override fun onDraw(canvas: Canvas?) 
            canvas?.save()?:return
            centerMatrix.reset()
            centerMatrix.postTranslate(width / 2F - (getDrawWidth() / 2), 0F)
            canvas.concat(centerMatrix)
            super.onDraw(canvas)
            canvas.restore()
        

        private fun getDrawWidth(): Float 
            return paint.measureText(text.toString()) + compoundPaddingRight + compoundPaddingLeft
        
    

【讨论】:

【参考方案19】:

将您的 TextView 包装在 LinearLayout 中。然后将android:gravity="center_horizontal" 设置为您的LinearLayout..

<LinearLayout
        android:layout_
        android:gravity="center_horizontal"
        android:layout_
        android:orientation="horizontal">

        <TextView
            android:layout_
            android:layout_
            android:drawableStart="@drawable/your_drawable"
            android:drawablePadding="5dp"
            android:ellipsize="end"
            android:maxLines="1"
            android:textAlignment="center"
            android:textColor="@color/ic_text_color"
            android:textSize="15sp"
            tools:text="Your Text.." />

    </LinearLayout>

【讨论】:

【参考方案20】:

就这么简单..试试看..

            <TextView
                android:layout_
                android:layout_
                android:gravity="center|left"
                android:drawableLeft="@drawable/icon"
                android:text="something something" />

【讨论】:

重力没有影响,因为您将宽度设置为 wrap_content。 Si se establece android:layout_ , si funciona【参考方案21】:

移除 DrawableLeft 并使用容器 FrameLayout。

<FrameLayout
     android:id="@+id/container"
     android:layout_
     android:layout_ >

     <ImageView
         android:id="@+id/image"
         android:layout_
         android:layout_
         android:layout_marginLeft="5dp"
         android:layout_gravity="center_vertical"
         android:src="@drawable/image" />

     <TextView
        android:id="@+id/text"
        android:layout_
        android:layout_
        android:text="Text"
        android:layout_gravity="center" />
</FrameLayout>

【讨论】:

这不是答案,这是一个丑陋的解决方法:))。附:正如您所说,不要“回答问题以获得积分” @farid 我提供了这个答案,因为 drawableLeft 是不可信的。如果太长,请确保文本不会与图像重叠。正确设置左右边距【参考方案22】:

最简单的方法是:

<RelativeLayout
         android:id="@+id/linearLayout1"
         android:layout_
         android:layout_
         android:background="@drawable/head" >

         <ImageView
             android:id="@+id/cat"
             android:layout_
             android:layout_
             android:layout_marginLeft="5dp"
             android:onClick="onClick"
             android:layout_marginTop="10dp"
             android:layout_alignParentLeft="true"
             android:src="@drawable/btn_back_d" />

       <TextView
            android:id="@+id/TvTitle"
            android:layout_
            android:layout_
            android:text=""
            android:layout_centerHorizontal="true" 
            android:textColor="#000000" 
            android:textSize="20sp"/>

在哪里

ImageView 的 alignParentLeft 设置为 true 并且 TextView 的 centerHorizo​​ntal 设置为 true

【讨论】:

谢谢,难道不能在线性布局中做类似的事情,还是我需要在某处使用相对布局? 为什么要使用线性布局?相对布局是更灵活的解决方案,它不会比线性布局占用太多负载。如果您想了解更多关于两种解决方案之间的效率差异的信息,您可以查看此链接:***.com/questions/4069037/… 好吧,我认为我的整体设计更适合线性布局,所以我必须做 header,所以如果我可以避免使用额外的线性布局,那就太好了。当然,如果那不可能,我猜也可以。 有趣的是,这是唯一对我有用的解决方案,所以我并没有真正得到反对意见。 Drawable left 糟透了,这行得通。但是,可以使用 FrameLayout 和layout_gravity 对其进行简化。

以上是关于将文本保留在 TextView 中,drawableLeft 居中的主要内容,如果未能解决你的问题,请参考以下文章

Textview drawable 不在远程视图中显示可绘制图像

如何使用 Compound Drawable 垂直对齐 TextView 中的文本

如何将复合可绘制对象放在文本视图的左上角

如何在按钮中设置textview和drawable之间的距离?

UI组件:TextView及其子类

旋转时在 TextView 中保留文本