【问题标题】:Removing the left padding on an Android EditText删除 Android EditText 上的左侧填充
【发布时间】:2020-10-21 13:50:08
【问题描述】:

默认的 EditText 背景似乎在左侧放置了 ~ 4dp 的填充。这会导致与其他小部件不对齐。

我做了一个简单的应用程序来演示。截图:

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <TextView
        android:background="#00ff00"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="HINT"
        android:text="TEXT"
        android:singleLine="true"/>
    <TextView
        android:background="#00ff00"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

有没有办法阻止它这样做?

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    一种解决方法是在两侧使用负边距 (-4dp)

    这仅在 EditText 背景与 Layout 背景匹配时有效,并且您在 Layout 的两侧没有任何东西会被 EditText 覆盖

    【讨论】:

    • 其实这是最省心的解决方案。伤心。但是是真的。 idk 为什么谷歌会这样做。看起来非常没用。
    【解决方案2】:

    您是否尝试添加 android:background="@android:color/transparent"?

    我对这个结果做了同样的例子

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
    
        <TextView
            android:background="#00ff00"
            android:text="@string/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="HINT"
            android:text="TEXT"
            android:background="@android:color/transparent"
            android:singleLine="true"/>
        <TextView
            android:background="#00ff00"
            android:text="@string/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
    </LinearLayout>
    

    线条的第二种方式

    像这样在drawable中添加一个xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item>
            <shape android:shape="rectangle">
                <solid android:color="@android:color/transparent" /> <!--background color of box-->
            </shape>
        </item>
    
        <item
            android:top="-2dp"
            android:right="-2dp"
            android:left="-2dp">
            <shape>
                <solid android:color="@android:color/transparent" />
                <stroke
                    android:width="1dp"
                    android:color="#000000" />  <!-- color of stroke -->
            </shape>
        </item>
    </layer-list>
    

    然后在您的布局中将其添加到您的 EditText android:background="@drawable/edittext_background"

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
    
        <TextView
            android:background="#00ff00"
            android:text="@string/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="HINT"
            android:text="TEXT"
            android:background="@drawable/edittext_background"
            android:singleLine="true"
            android:layout_marginBottom="3dp"/>
        <TextView
            android:background="#00ff00"
            android:text="@string/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
    </LinearLayout>
    

    你会得到这个

    【讨论】:

    • 对,但现在它看起来不像 EditText。我想使用 EditText 的部分原因是它有一行可以“免费”改变焦点等
    • 对可绘制对象太好了。基于状态的颜色变化呢?
    • 你可以在android:color="#000000" /> 中任意改变颜色 例如:android:color="#DD0000"
    • 当然,但是有选择器?或者我是否需要为每个状态制作一个可绘制并在选择器中引用它们?仍然比需要修改九个补丁/以编程方式为每种颜色着色要好得多
    • 您只需要一个 xml 文件来将颜色定义为选择器
    【解决方案3】:

    在编辑文本字段中使用android:layout_marginLeft="-4dp",如下所示。

    <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="HINT"
            android:text="TEXT"
            android:layout_marginLeft="-4dp"
            android:singleLine="true"/>
    

    【讨论】:

      【解决方案4】:

      这个问题来自?android:attr/editTextBackground的默认值。

      <inset xmlns:android="http://schemas.android.com/apk/res/android"
          android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"
          android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
          android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
          android:insetTop="@dimen/abc_edit_text_inset_top_material">
      
          <selector>
              <item android:state_enabled="false">
                  <nine-patch
                      android:alpha="?android:attr/disabledAlpha"
                      android:src="@drawable/abc_textfield_default_mtrl_alpha"
                      android:tint="?attr/colorControlNormal" />
              </item>
              <item
                  android:state_focused="false"
                  android:state_pressed="false">
                  <nine-patch
                      android:src="@drawable/abc_textfield_default_mtrl_alpha"
                      android:tint="?attr/colorControlNormal" />
              </item>
              <item>
                  <nine-patch
                      android:src="@drawable/abc_textfield_activated_mtrl_alpha"
                      android:tint="?attr/colorControlActivated" />
              </item>
          </selector>
      
      </inset>
      

      如您所见,EditText 所有边缘的插入值是abc_edit_text_inset_top_material = 4dp。这使得 EditText 在其内容周围有小填充。 要删除该填充,您应该使用修改的 editTextBackground 属性创建一个新的 EditText 样式。例如:

      <style name="Widget.App.TextField" parent="@style/Widget.AppCompat.EditText">
              <item name="colorControlActivated">#303E44</item>
              <item name="colorControlHighlight">#E5E9EC</item>
              <item name="colorControlNormal">#E5E9EC</item>
              <item name="editTextBackground">@drawable/background_new_edit_text</item>
      <item name="android:editTextBackground">@drawable/background_new_edit_text</item>
          </style>
      

      New background_edit_text.xml(记得把这个文件放到正确的drawable目录下,这样就不会被覆盖,比如drawable-v21...)

      <?xml version="1.0" encoding="utf-8"?>
      <inset xmlns:android="http://schemas.android.com/apk/res/android"
          android:inset="@dimen/spacing_0dp">
          <selector>
              <item android:state_enabled="false">
                  <nine-patch
                      android:alpha="?android:attr/disabledAlpha"
                      android:src="@drawable/abc_textfield_default_mtrl_alpha"
                      android:tint="?attr/colorControlNormal" />
              </item>
              <item
                  android:state_focused="false"
                  android:state_pressed="false">
                  <nine-patch
                      android:src="@drawable/abc_textfield_default_mtrl_alpha"
                      android:tint="?attr/colorControlNormal" />
              </item>
              <item>
                  <nine-patch
                      android:src="@drawable/abc_textfield_activated_mtrl_alpha"
                      android:tint="?attr/colorControlActivated" />
              </item>
          </selector>
      
      </inset>
      

      为您的EditText 应用新样式:

      <EditText
              android:id="@+id/edt_phone"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:theme="@style/Widget.App.TextField"
              />
      

      【讨论】:

      • 感谢分享,看起来是个不错的方法。但它对我不起作用。设置editTextBackground 对样式没有影响,为了确定,我尝试了其他背景。如果我使用android:editTextBackground,那么我会得到无插入背景,但我会失去颜色,并且不能再使用colorControlActivated。我还没有找到设置颜色的正确方法。也许它是一个主题,我的应用程序主题会覆盖它(如果可能的话)? PS:我还更新了样式参考,一个小错字。
      • 是的,在你的情况下,它可能是一个主题。有了我的,我仍然可以更改 EditText 的colorControlActivated。注意:要在 Android 30 上删除 EditText 的 inset,属性应为 android:editTextBackground(您可以同时使用两者)。
      • 我仍然不知道为什么它不起作用。也许相关,我正在使用材料设计com.google.android.material:material:1.2.0-rc01。此外(对于老问题的灵魂)这里还有很多其他人在让样式在 EditText 上工作时遇到问题:stackoverflow.com/a/10904193/197141
      • 啊,我发现了问题。我相信您无意中遗漏了正确的背景文件。您包含的文件是来自 android source/drawable 的默认“editTextBackground”,但它被 drawable-v21 覆盖。如果你有它工作,你必须包含设置颜色的 v21 版本,看起来像这样:chromium.googlesource.com/android_tools/+/master/sdk/extras/…你能确认这是真的(并更新答案)吗?
      • @arberg 是的,我引用了drawable 文件夹中的文件,而不是drawable-v21。刚刚更新了我的答案。如果您需要,这是我的示例代码:github.com/hoanv810/EditTextSample
      【解决方案5】:

      将 EditText 的背景更改为自定义,它有九个补丁填充

      【讨论】:

      • 是的,我想这会起作用,尽管我不希望需要为每个状态制作一个九个补丁(或者需要将此逻辑放在每个想要使用 EditText 的应用程序中...... )
      • 然后尝试为 TextViews 应用填充?
      • 是的,这就是我正在做的事情,但这是一个严重的黑客攻击。希望有更清洁的解决方案
      • 在任何情况下,默认背景的 EditText 都会有小填充
      • 我认为这应该是公认的答案(也许一个小样本会有所帮助)。它似乎就是这样,EditText 的默认背景在它周围都有插图。恕我直言,其他所有内容确实都是黑客攻击。
      【解决方案6】:

      如果您只想对齐文本而不对齐下面的行,您可以通过编程方式覆盖填充。

      假设这个布局是针对一个活动的。创建活动后,您可以执行以下操作:

      findViewById(R.id.edit_text).setPaddding(
                                       0,
                                       old_top_paddding,
                                       old_right_paddding,
                                       old_bottom_padding);
      

      关键是在应用背景后重新设置填充。您可能需要注意再次设置背景的情况,因此一种想法可能是覆盖 setBackground*() 方法并在那里重新设置填充。

      【讨论】: