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

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


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

【问题讨论】:

  • 是否可以在中心也可以绘制??

标签: android textview


【解决方案1】:

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

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    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_width="match_parent"
    android:layout_height="match_parent">

<TextView
        android:id="@+id/edit_location_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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_width="wrap_content"
        android:layout_height="wrap_content"
        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_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:padding="10dp"
        android:textAlignment="center" />
    

    【讨论】:

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

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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_width="fill_parent"
          android:layout_height="fill_parent"
          android:background="@color/White"
           >
        
        <RelativeLayout
             android:id="@+id/rlheader"
             android:layout_width="fill_parent"
             android:layout_height="50dp"
             android:layout_alignParentTop="true"
             android:background="@color/HeaderColor"
            
              >
       
              <TextView
                 
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_centerHorizontal="true"
                 android:layout_centerVertical="true"
                 android:text="Header_Title"
                  />
       
              <ImageView
                 android:id="@+id/ivSetting"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 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_width="match_parent"
          android:layout_height="wrap_content"
          android:gravity="center"
          android:orientation="horizontal">
      
          <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              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_width="match_parent"
                    android:layout_margin="@dimen/marginplus2"
                    android:layout_height="wrap_content">
        
                    <TextView
                        android:layout_width="0dp"
                        android:layout_weight="1"
                        android:text="@string/like"
                        android:gravity="start|center_vertical"
                        android:drawablePadding="@dimen/marginplus1"
                        android:drawableLeft="@drawable/ic_like"
                        android:layout_height="wrap_content" />
        
                    <TextView
                        android:layout_width="0dp"
                        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_height="wrap_content" />
                    <TextView
                        android:layout_width="0dp"
                        android:layout_weight="1"
                        android:text="@string/share"
                        android:drawablePadding="@dimen/marginplus1"
                        android:gravity="start|center_vertical"
                        android:drawableLeft="@drawable/ic_share"
                        android:layout_height="wrap_content" />
        
                </LinearLayout>
        

        【讨论】:

          【解决方案9】:

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

          <TextView
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              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_width="match_parent"
                    android:layout_height="wrap_content"
                    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_width="match_parent"
                      android:layout_height="50dp"
                      android:layout_marginTop="10dp"
                      android:background="#000">
              
                      <TextView
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          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_width="match_parent"
                             android:layout_height="wrap_content"
                             android:background="@drawable/head" >
                
                             <ImageView
                                 android:id="@+id/cat"
                                 android:layout_width="wrap_content"
                                 android:layout_height="wrap_content"
                
                                 android:layout_marginLeft="5dp"
                                 android:onClick="onClick"
                                 android:layout_marginTop="10dp"
                                 android:src="@drawable/btn_back_" />
                
                
                         <RelativeLayout
                             android:id="@+id/linearLayout1"
                             android:layout_width="fill_parent"
                             android:layout_height="wrap_content"
                             android:gravity="center" >
                
                           <TextView
                 android:id="@+id/TvTitle"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 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_width="wrap_content"
                    android:layout_height="wrap_content"
                    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_width="match_parent"
                      android:layout_height="match_parent">
                  
                      <android.support.v7.widget.CardView
                          android:id="@+id/my_card"
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content">
                  
                          <LinearLayout
                              android:id="@+id/bb"
                              android:layout_width="match_parent"
                              android:layout_height="wrap_content"
                              android:divider="@color/gray"
                              android:orientation="horizontal"
                              android:weightSum="2">
                  
                              <TextView
                                  android:id="@+id/filter_tv"
                                  style="?android:attr/buttonBarButtonStyle"
                                  android:layout_width="wrap_content"
                                  android:layout_height="?attr/actionBarSize"
                                  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_width="1dp"
                                  android:layout_height="match_parent"
                                  android:layout_below="@+id/bb"
                                  android:background="@color/gray" />
                  
                              <TextView
                                  android:id="@+id/sort_tv"
                                  style="?android:attr/buttonBarButtonStyle"
                                  android:layout_width="wrap_content"
                                  android:layout_height="?attr/actionBarSize"
                                  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_width="match_parent"
                          android:layout_height="0.9dp"
                          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_width="wrap_content"
                        android:layout_height="wrap_content"
                        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_width="0dp"
                                android:gravity="center_horizontal"
                                android:layout_height="wrap_content"
                                android:orientation="horizontal">
                        
                                <TextView
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    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_width="wrap_content"
                                          android:layout_height="wrap_content"
                                          android:gravity="center|left"
                                          android:drawableLeft="@drawable/icon"
                                          android:text="something something" />
                          

                          【讨论】:

                          • 重力没有影响,因为您将宽度设置为 wrap_content。
                          • Si se establece android:layout_width="match_parent" , si funciona
                          【解决方案21】:

                          移除 DrawableLeft 并使用容器 FrameLayout。

                          <FrameLayout
                               android:id="@+id/container"
                               android:layout_width="match_parent"
                               android:layout_height="wrap_content" >
                          
                               <ImageView
                                   android:id="@+id/image"
                                   android:layout_width="wrap_content"
                                   android:layout_height="wrap_content"
                                   android:layout_marginLeft="5dp"
                                   android:layout_gravity="center_vertical"
                                   android:src="@drawable/image" />
                          
                               <TextView
                                  android:id="@+id/text"
                                  android:layout_width="match_parent"
                                  android:layout_height="wrap_content"
                                  android:text="Text"
                                  android:layout_gravity="center" />
                          </FrameLayout>
                          

                          【讨论】:

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

                          最简单的方法是:

                          <RelativeLayout
                                   android:id="@+id/linearLayout1"
                                   android:layout_width="match_parent"
                                   android:layout_height="wrap_content"
                                   android:background="@drawable/head" >
                          
                                   <ImageView
                                       android:id="@+id/cat"
                                       android:layout_width="wrap_content"
                                       android:layout_height="wrap_content"
                                       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_width="match_parent"
                                      android:layout_height="match_parent"
                                      android:text=""
                                      android:layout_centerHorizontal="true" 
                                      android:textColor="#000000" 
                                      android:textSize="20sp"/>
                          

                          在哪里

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

                          【讨论】:

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