【问题标题】:How to use wrap_content with a maximum width?如何使用最大宽度的 wrap_content?
【发布时间】:2015-08-16 06:29:46
【问题描述】:

我正在尝试布局一个应该包装其内容的视图,但它不应比其父宽度小约 100dp。如何使用 RelativeLayout 或其他布局来做到这一点?我现在所拥有的总是会使视图比其父视图小 100dp,以便为另一个视图留出空间。

这张照片是我所拥有的一个例子:

如您所见,文本不会填满整个框,因此它可能会更小。但是,它不应比其父级小 100dp,以便为发送消息的时间留出空间。

这是我的布局。

<?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="wrap_content"
    android:clipChildren="false"
    android:orientation="vertical"
    android:paddingBottom="10dp"
    android:paddingRight="@dimen/horizontalMargin"
    android:paddingTop="10dp">


    <TextView
        android:id="@+id/message_holder"
        android:layout_toLeftOf="@id/blank"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="@dimen/horizontalMargin"
        android:background="@drawable/message_corners"
        style="@style/white_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="alsdkjf; alsdkf" />

    <RelativeLayout
        android:id="@+id/blank"
        android:layout_width="wrap_content"
        android:layout_height="1dp"
        android:layout_alignParentRight="true"
        android:minWidth="100dp">

    </RelativeLayout>

    <TextView
        android:minWidth="100dp"
        android:id="@+id/time"
        style="@style/gray_text"
        android:layout_toRightOf="@id/message_holder"
        android:paddingLeft="10dp"
        android:text="Yesterday,\n11:30 PM" />


    <RelativeLayout
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignBottom="@id/message_holder"
        android:layout_alignParentLeft="true"
        android:background="@drawable/triangle" />

</RelativeLayout>

我尝试在消息框右侧的空白视图上使用“minWidth”属性来提供间距,但它不会调整为更大的大小(这会使消息框变小)。当我没有空白视图时,只需将时间 TextView 放在消息框的右侧,那么当消息框展开时该 TextView 不可见。

更新:

这是我的“message_corners.xml”:

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


    <solid
        android:color="@color/green" >
    </solid>


    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp"    >
    </padding>


    <corners
        android:radius="10dp">
    </corners>

</shape>

更新 2:

这就是我在短文本布局中寻找的内容:

这就是我在带有长文本的布局中寻找的内容:

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    给你,一个完全符合你想要的布局。

    <?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="wrap_content"
        android:clipChildren="false"
        android:paddingBottom="10dp"
        android:paddingRight="10dp"
        android:paddingTop="10dp">
    
    
        <RelativeLayout
            android:id="@+id/blank"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#aaaaaa">
            <LinearLayout
                android:id="@+id/message_container"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingRight="100dp">
                <TextView
                    android:id="@+id/message"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Hello?"
                    android:background="#00ff00" />
            </LinearLayout>
    
            <TextView
                android:id="@+id/time"
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/message_container"
                android:layout_marginLeft="-100dp"
                android:text="12:30 PM"
                android:background="#ff0000" />
        </RelativeLayout>
    
    </RelativeLayout>
    

    短消息

    长消息

    【讨论】:

      【解决方案2】:

      我知道这是一个非常古老的问题,但这是我已经多次遇到的令人沮丧的问题,并且现有的答案并不是我想要的。我和一些同事提出了以下建议:

      <?xml version="1.0" encoding="utf-8"?>
      
      <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="wrap_content"
          android:orientation="vertical"
          android:background="#FFFFFF">
      
          <LinearLayout
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:background="#888888"
              android:padding="10dp"
              android:orientation="horizontal">
      
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1"
                  android:background="#00FF00"
                  tools:text="Short message."/>
      
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_marginLeft="10dp"
                  android:layout_weight="0"
                  android:background="#CCCCCC"
                  tools:text="Yesterday,\n11:30pm"/>
      
          </LinearLayout>
      
          <LinearLayout
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="10dp"
              android:background="#888888"
              android:padding="10dp"
              android:orientation="horizontal">
      
              <TextView
                  android:id="@+id/message_text_view"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1"
                  android:background="#00FF00"
                  tools:text="Super ultra mega awesome long message which is going to help us take over the world."/>
      
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_marginLeft="10dp"
                  android:layout_weight="0"
                  android:background="#CCCCCC"
                  tools:text="Yesterday,\n11:31pm"/>
      
          </LinearLayout>
      
      </LinearLayout>
      

      渲染后的样子:

      神奇的似乎是右侧文本框的权重为零(除了左侧文本框的非零权重值,其他一些答案已经有了)。

      老实说,我无法准确解释它为什么会起作用,但在寻找解决方案这么久之后,我没有质疑它! :)

      顺便说一句,我喜欢这种方法,因为它不需要任何显式或最小宽度、任何中间包装视图,也不需要使用剪裁设置、边距、填充等来实现视图覆盖。

      【讨论】:

        【解决方案3】:

        这个问题的作者真正要问的是,如何让TextView展开来适应里面的消息,而不溢出TextView的时间,又不留空白。

        由于您实际上并不知道整个屏幕的宽度,因此您不能告诉您的 TextView 比它小 100dp。 您应该做的是将您的 TextView 包装在一个容器中,该容器将具有 toLeftOf 规则,而 TextView 仅包装它的内容。这样,容器会一直展开到右侧(不会溢出时间 TextView)但 TextView 只会包装它的文本内容(所以,它不会t 扩展任何空格)

        代码

        代替

        <TextView
                android:id="@+id/message_holder"
                android:layout_toLeftOf="@id/blank"
                android:layout_alignParentLeft="true"
                android:layout_marginLeft="@dimen/horizontalMargin"
                android:background="@drawable/message_corners"
                style="@style/white_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="alsdkjf; alsdkf" />
        

        使用

        <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"       
         android:layout_toLeftOf="@id/blank"
         android:layout_alignParentLeft="true"
         android:layout_marginLeft="@dimen/horizontalMargin">
        
             <TextView
                  android:id="@+id/message_holder"
                  android:background="@drawable/message_corners"
                  style="@style/white_text"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="alsdkjf; alsdkf" />
        </LinearLayout>
        

        顺便说一句,你的布局不是很好。你应该优化它。

        【讨论】:

        • 嗯,这回答了一半的问题,但是你怎么有时间立即显示在右边呢?
        • 在这种情况下,将LinearLayout更改为水平,将时间textview添加到其中,使其显示在消息textview的右侧,并将LinearLayout的marginRight添加为100dp,以便在完全展开时留出空间.
        【解决方案4】:

        您可以尝试以下视图排列方式及其宽度:

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                      xmlns:tools="http://schemas.android.com/tools"
                      android:orientation="horizontal"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:padding="6dp"
                >
            <FrameLayout
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    android:layout_height="wrap_content">
                <TextView 
                        android:layout_width="wrap_content" 
                        android:layout_height="wrap_content"
                        android:background="@android:color/holo_blue_bright"
                        tools:text="Some long test is this which is support to wrap at the end of parent view"
                        />
            </FrameLayout>
            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="6dp"
                    tools:text="Yesterday,\n 11:30 PM"
                    />
        </LinearLayout>
        

        【讨论】:

        • 这真的很接近,除非文本较短,然后时间停留在右侧而不是与第一个文本视图齐平。
        【解决方案5】:

        星期六 Sri Akal

        这也可以使用 ConstraintLayout 来实现

        水平链中有 2 个孩子

        第一个孩子 布局宽度 0 约束权重 1 约束最大宽度换行

        第二个孩子 布局宽度换行内容

        【讨论】:

        • 我试过了,确实有效,就是不太好理解。
        • 但在 recyclerview 中无法正常工作
        【解决方案6】:

        如果你想让时间文本在右边,文本消息在左边,你可以这样做(在相对布局中使用它)你也可以使用 ma​​xWidth 而不是 minWidth

        <TextView
                android:id="@+id/view_textView_timeText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"/>
        
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_toLeftOf="@id/view_textView_timeText"
                android:maxWidth="100dp"/>
        

        【讨论】:

          【解决方案7】:

          您可以做的是在两个视图之间放置一个空视图,并将其宽度保持为 MATCH_PARENT,并将文本视图分配给这个空视图的左侧,并将空视图分配给日期视图的左侧。只需确保视图为空即可。

          【讨论】:

            【解决方案8】:

            据我了解,您希望将布局或 textview 设置为比屏幕尺寸小 100 dp 您可以通过获取屏幕宽度(以像素为单位)来完成此操作

            Display display  = getWindowManager().getDefaultDisplay();
             Point size = new Point();
             display.getSize(size);
             int width = size.x;
             int height = size.y;
            

            然后您可以将 textbiew 宽度设置为比屏幕尺寸小 100dp 希望对您有所帮助 P.s 我想你可能想将 dp 转换为 px 但我不确定

            【讨论】:

            • 你能再解释一下吗?我想在消息框上设置最大宽度,但我不知道那个宽度是多少,因为它是为了填满整个屏幕。
            • 将最大高度添加到 message_holder 文本视图
            • 我觉得他不在乎身高
            • 您可以发布您正在考虑的布局吗?我希望它最多比屏幕小 100dp
            • 我希望新的答案会有所帮助
            【解决方案9】:

            你可以这样做(不是问题的直接答案):

             <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="bottom"
                android:orientation="horizontal">
            
            
                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:orientation="horizontal">
            
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:ellipsize="end"
                        android:maxLines="1"
                        android:paddingLeft="45px"
                        android:text="asdfadsfsafasdfsakljkljkhjhkkhjkjhjkjhjkhjkhljkhlkhjlkjhljkhljkhlkjhljkhljkhlfasd"
                        android:textColor="#4a4a4a"
                        android:textSize="40px" />
                </LinearLayout>
            
            
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:maxLines="1"
                    android:paddingLeft="45px"
                    android:paddingRight="48px"
                    android:text="2017.08.09 13:00"
                    android:textColor="#9b9b9b"
                    android:textSize="34px" />
            </LinearLayout>
            

            【讨论】:

              【解决方案10】:

              我有一个通用的解决方案来解决这种布局问题:

              创建一个特定的 ViewGroup!

              对于上面的问题,关键是如何为内容视图设置正确的maxWidth

              1. 创建一个特殊视图组。 contentView 是左视图,timeView 是右视图。
              class SpecialViewGroup @JvmOverloads constructor(
                context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
              ) : LinearLayout(context, attrs, defStyleAttr) {
              
                private lateinit var contentView: TextView
                private lateinit var timeView: TextView
              
                override fun onAttachedToWindow() {
                  super.onAttachedToWindow()
                  contentView = findViewById(R.id.content)
                  timeView = findViewById(R.id.time)
                }
              
                override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
                  // measure the timeView firstly, because the contentView's maxWidth rely on it.
                  timeView.measure(
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                  )
              
                  // then caculate the remained space for the contentView
                  val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
                  val paddingHorizontal = paddingStart + paddingEnd
                  val view1MaxWidth = parentWidth - timeView.measuredWidth - paddingHorizontal
              
                  // set the maxWidth to the contentView
                  contentView.maxWidth = view1MaxWidth
              
                  // The rest thing will be handed over by LinearLayout
                  super.onMeasure(widthMeasureSpec, heightMeasureSpec)
                }
              }
              
              1. 在布局中使用 SpecialViewGroup,就像通常的 LinearLayout 一样。
                <com.example.SpecialViewGroup
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:background="#FFBB86FC"
                  android:orientation="horizontal"
                  android:padding="10dp">
              
                  <TextView
                    android:id="@+id/content"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="#FF3700B3"
                    android:padding="10dp"
                    android:text="adaasdasdasasdadasdasdaaaaaaaaaaaaaaaa"
                    android:textColor="@color/white" />
              
                  <TextView
                    android:id="@+id/time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="#FF018786"
                    android:padding="10dp"
                    android:text="1970-01-01"
                    android:textColor="@color/white" />
              
                </com.example.archview.SpecialViewGroup>
              

              结果:

              这种方法的好处是显而易见的:

              1. 没有额外的嵌套布局。
              2. 常用来解决类似的布局问题。

              【讨论】:

                【解决方案11】:

                有类似的问题。让它在约束下工作。

                <ConstraintLayout>
                
                    <TextView
                         android:id="@+id/title"
                         android:layout_width="0dp"
                         android:layout_height="wrap_content"
                         android:ellipsize="end"
                         android:maxLines="2"
                         app:layout_constraintEnd_toStartOf="@+id/option_info"
                         app:layout_constraintHorizontal_chainStyle="packed"
                         app:layout_constraintHorizontal_weight="1"
                         app:layout_constraintTop_toTopOf="parent"
                         app:layout_constraintWidth_max="wrap" />
                
                    <ImageView
                         android:id="@+id/option_info"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:src="@drawable/ic_info"
                         app:layout_constraintBottom_toBottomOf="@+id/title"
                         app:layout_constraintEnd_toEndOf="parent"
                         app:layout_constraintStart_toEndOf="@+id/title"
                         app:layout_constraintTop_toTopOf="@+id/title" />
                
                </ConstraintLayout>
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-06-04
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-12-25
                  • 2012-03-19
                  • 1970-01-01
                  相关资源
                  最近更新 更多