【问题标题】:Align baseline with a TextView which is wrapped inside a TextInputLayout将基线与包装在 TextInputLayout 中的 TextView 对齐
【发布时间】:2015-09-22 07:17:01
【问题描述】:

我想将 TextView "Deficient" 的基线与 EditText "10000" 的基线对齐。他们都在里面<android.support.percent.PercentRelativeLayout>

我尝试了以下方法,但无法正常工作。

<android.support.percent.PercentRelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.design.widget.TextInputLayout
        android:id="@+id/textInputLayout_soil_nitrogen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        app:layout_widthPercent="63%">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter N of soil"
            tools:text="10000" />

    </android.support.design.widget.TextInputLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@id/textInputLayout_soil_nitrogen"
        android:layout_toRightOf="@id/textInputLayout_soil_nitrogen"
        app:layout_widthPercent="37%"
        tools:text="Deficient" />

</android.support.percent.PercentRelativeLayout>

为 TextView 提供 20dp 的顶部填充可以解决问题,但如果改为对齐它们的基线会很好。在这种情况下甚至可能吗?

顺便说一句,我已经删除了 textAppearance 和 id 属性。

【问题讨论】:

    标签: android android-layout android-textinputlayout android-percent-library


    【解决方案1】:

    老问题,但这是我的解决方案。

    基本上TextInputLayout 没有为其父级提供基线值。我们需要通过扩展TextInputLayout 来传递EditText 的正确基线。这对我有用,但是,我不确定基线是否会由于来自TextInputLayout 的其他事件而改变。

    public class CTextInputLayout extends TextInputLayout {
        public CTextInputLayout(Context context) {
            super(context);
        }
    
        public CTextInputLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        public int getBaseline()
        {
            EditText editText = getEditText();
            return editText.getPaddingTop() + editText.getBaseline();
        }
    }
    

    我假设PercentRelativeLayout 支持基线对齐。否则,您可以将 CTextInputLayoutTextView 包装在 RelativeLayout 中以实现基线对齐。

    【讨论】:

      【解决方案2】:

      TextInputLayout 内,放置一个RelativeLayout,并将EditTextTextView 作为子代:

               <android.support.design.widget.TextInputLayout
                      android:id="@+id/textInputLayout_soil_nitrogen"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:layout_alignParentLeft="true"
                      android:layout_alignParentStart="true"
                      android:layout_alignParentTop="true"
                      android:layout_widthPercent="63%">
      
                      <RelativeLayout
                          android:layout_width="match_parent"
                          android:layout_height="match_parent">
      
                          <EditText
                              android:id="@+id/edittext_soil_nitrogen"
                              android:layout_width="match_parent"
                              android:layout_height="wrap_content"
                              android:hint="Enter N of soil"
                              android:text="10000" />
      
                          <TextView
                              android:layout_width="wrap_content"
                              android:layout_height="wrap_content"
                              android:layout_alignBaseline="@id/edittext_soil_nitrogen"
                              android:layout_alignParentRight="true"
                              android:layout_widthPercent="37%"
                              android:text="Deficient" />
      
                      </RelativeLayout>
      
                  </android.support.design.widget.TextInputLayout>` 
      

      【讨论】:

      • 这对我有帮助。谢谢!
      • 如果您不介意在 RelativeLayout 周围显示提示和错误,这也可以
      • 我同意@shredder。此外,如果您在 com.google.android.material.textfield.TextInputEditText 周围使用 com.google.android.material.textfield.TextInputLayout,则 TextInputLayout 中定义的任何装饰都不会过滤掉。叹息。
      【解决方案3】:

      Check this image for verification

      请尝试以下代码

      <android.support.design.widget.TextInputLayout
          android:id="@+id/textInputLayout_soil_nitrogen"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentLeft="true"
          android:layout_alignParentStart="true"
          android:layout_alignParentTop="true"
          app:layout_widthPercent="63%">
      
          <EditText
              android:id="@+id/editText"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:hint="Enter N of soil"
              tools:text="10000" />
      
      </android.support.design.widget.TextInputLayout>
      
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignBottom="@id/textInputLayout_soil_nitrogen"
          android:layout_toEndOf="@id/textInputLayout_soil_nitrogen"
          android:layout_toRightOf="@id/textInputLayout_soil_nitrogen"
          android:gravity="bottom|start"
          android:padding="8dp"
          android:text="Deficient"
          android:textColor="@android:color/black"
          app:layout_widthPercent="37%" />
      

      【讨论】:

      • 关闭,但没有雪茄!这并不能真正保证基线对齐。在我测试的所有情况下,它看起来都很接近,但只是引人注目。
      【解决方案4】:

      请替换下面的代码行

       <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_toEndOf="@id/textInputLayout_soil_nitrogen"
              android:layout_toRightOf="@id/textInputLayout_soil_nitrogen"
              app:layout_widthPercent="37%"
              tools:text="Deficient" />
      

      <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignBottom="@+id/textInputLayout_soil_nitrogen"
              android:layout_toEndOf="@id/textInputLayout_soil_nitrogen"
              android:layout_toRightOf="@id/textInputLayout_soil_nitrogen"
              tools:text="Deficient" />
      

      希望对你有帮助!!

      【讨论】:

      • 不行,这样textView的baseline和editText的line(上图中紫色的)在同一水平线,这不是我想要的。 我想对齐它们的基线。我认为这是不可能的,因为 TextView 在 TextInputLayout 内。猜猜我只能通过添加 20dp 的顶部填充来解决。我希望这里有人知道如何实现这一目标。不过谢谢你的回答。祝你有美好的一天。 :)
      • ok 意味着您希望 edittext 和 textview 的底部基线与基于文本的相同。我认为为此您需要定义相同的字体大小并提供 textview 的底部填充。它的作品。
      • 是的,提供填充是使这成为可能的唯一方法。
      【解决方案5】:

      如果您使用的是 Kotlin,我发现了一个可行的解决方案(有点)。它的程序化解决方案。

      我使用了 ConstraintLayout 来包装视图

      假设 textViewDeficient 是与 TextInputLayout 布局的基线对齐的视图。

      这就是我的布局的样子

      <androidx.constraintlayout.widget.ConstraintLayout
          android:id="@+id/cl_wrapper"
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
      
          <com.google.android.material.textfield.TextInputLayout
              android:id="@+id/textInputLayout"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:hint="@string/phone_number"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintLeft_toLeftOf="parent"
              app:layout_constraintTop_toTopOf="parent"
              app:layout_constraintBottom_toBottomOf="parent">
      
              <com.google.android.material.textfield.TextInputEditText
                  android:id="@+id/textInputEditText"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:text="100000"/>
      
          </com.google.android.material.textfield.TextInputLayout>
      
          <TextView
              android:id="@+id/textViewDeficient"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              app:layout_constraintStart_toEndOf="@id/textInputLayout"
              app:layout_constraintLeft_toRightOf="@id/textInputLayout"
              app:layout_constraintTop_toTopOf="@id/textInputLayout"
              android:text="Deficient"/>
      
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      在你的活动中有这个方法

      private fun adjustTextView() {
          fun setTextViewTopMargin() {
              textInputLayout?.post {
                  val frameLayout = textInputLayout?.children?.iterator()?.next()
                  if (frameLayout is FrameLayout) {
                      frameLayout.postIt { fl ->
                          textInputEditText?.postIt { tiet ->
                              val topMargin = fl.marginTop + tiet.marginTop + dpToPx(5)
                              textViewDeficient?.updateLayoutParams<ConstraintLayout.LayoutParams> {
                                  updateMargins(top = topMargin)
                              }
                          }
                      }
                  }
              }
          }
      
          textInputLayout?.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
              setTextViewTopMargin()
          }
          setTextViewTopMargin()
      }
      

      将这些扩展功能添加到您的活动或任何文件中

      fun View.postIt(postAction: (v: View) -> Unit) { post { postAction.invoke(this) }}
      
      fun Context.dpToPx(dp: Int) = TypedValue.applyDimension(
              TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), resources.displayMetrics
          ).toInt()
      

      现在打电话

      adjustTextView()
      

      在活动的 onCreate 方法中

      我希望这会有所帮助。让我知道是否可以改进

      【讨论】:

      • 嗯,您的代码无法编译。调用dpToPx(5) 找不到函数Context.dpToPx(dp: Int)。如果我拿走Context.,它会编译,但我不确定这就是你想要的,也不知道这会如何影响你的代码的工作。你能解释一下吗?
      • 您好,Context用于扩展函数中的resources.displayMertics部分。 Context.dpToPX(dp: Int) 的位置很重要。我建议您将这些函数放在一个空的 kotlin 文件中。 resources.displayMetrics 不会在没有 Context 的情况下运行,所以它基本上是 Context.resources.displayMetrics
      • 我猜您将 dpToPx 函数放在了活动或片段中。活动/片段在其范围内具有上下文。因此,您不需要该方法的前缀 Context 。但是,如果您想在更大的范围内使用它而不仅仅是一个活动/片段,您可以保留 Context 前缀并将扩展函数放在任何文件中(但不在任何类中)
      猜你喜欢
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      • 2017-02-15
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 2015-10-11
      相关资源
      最近更新 更多