2014-06-08 2 views
17

ich das folgende Layout erreichen müssen:erweitern Textview mit wrap_content, bis der Nachbarn Ansicht des Ende der Mutter erreicht

enter image description here

Ich habe zwei Textviews in einem relativen Layout: die grünen ist fester Text mit wrap_content, der schwarze hat dynamischen Text mit wrap_content. Der schwarze Text kann sich ändern und sehr lang werden. Ich möchte, dass die schwarze Textansicht mit dem Text erweitert wird, bis die grüne Ansicht das Ende der übergeordneten Ansicht erreicht. Wenn das passiert, sollte der schwarze TextView aufhören zu erweitern und das Ende ellipsen.

Wie kann ich das erreichen?

Was ich versucht:

<RelativeLayout 
    android:id="@+id/parent" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" > 


    <TextView 
     android:id="@+id/leftTextView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:maxLines="1" 
     android:layout_alignParentLeft="true" 
     android:textSize="18sp" /> 

    <TextView 
     android:id="@+id/rightTextView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_toRightOf="@id/leftTextView" 
     android:textSize="18sp" /> 

</RelativeLayout> 

Aber wenn der schwarze Text größer und größer wird drückt er den grünen eine aus der Sicht

Antwort

1

das gewünschte Layout zu erwarten sind, können mit Hilfe von layout_weight attirbute erstellt werden was kommt mit LinearLayout. So müssen Sie möglicherweise LinearLayout mit weightSum und layout_weight (übergibt an seine childview) Attribute verwenden.

Hier ist ein Layout, das Ihre Breite des Layouts in vier Teile teilt, die in 3: 1 zwischen beiden unterteilt. Intacting right TextView machen links TextView zeigt Text so viel wie möglich, es kann ohne störende Recht TextView zeigen.

Probieren Sie bitte mit der Variante weightSum und layout_weight Kombination nach Ihren Bedürfnissen ausprobieren.

Layout:

<LinearLayout 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:weightSum="4" > 

    <TextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:singleLine="true" 
     android:text="StackOverflow StackOverflow StackOverflow " 
     /> 

    <TextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="right" 
     android:layout_weight="3" 
     android:maxLines="1" 
     android:text="TextView" 
     android:textColor="@android:color/white" /> 
</LinearLayout> 
+1

ich zu Ihren Code aber Ihre zweite Textview nimmt einige unerwünschte Raum versucht. Wie wenn ich ein A als Text setze, dann nimmt es Platz von 10 Ein –

+0

@IllegalArgument: Wie du gesagt hast, ist deine zweite Textansicht behoben. Sie können mit mehr 'GewichtSumme' und Variantenverteilung von' Layout_weight' in 'TextView' versuchen –

+0

Ich plane auch, diese Frage zu beantworten, aber ich habe eine korrekte Antwort noch nicht gefunden, die Varianten nur verwendet, wenn der Inhalt satic –

0

ich die maxwidth der linken Textview Basis der Breite des rechten Textview setzen, nehmen Sie eine Suche meinen Code. hoffe, das wird helfen.

TextView leftText ; 
TextView rightText; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    leftText = (TextView) findViewById(R.id.leftTextView); 
    rightText = (TextView) findViewById(R.id.rightTextView); 


    measureView(leftText); 
    measureView(rightText); 

    leftText.setMaxWidth(getWidth() - rightText.getMeasuredWidth()); 

} 

private void measureView(View view) { 
    ViewGroup.LayoutParams params = view.getLayoutParams(); 
    int childWidth = ViewGroup.getChildMeasureSpec(0, view.getPaddingLeft() + view.getPaddingRight(), params.width); 
    int childHeight = ViewGroup.getChildMeasureSpec(0, view.getPaddingBottom() + view.getPaddingTop(), params.height); 
    view.measure(childWidth, childHeight); 

} 

private int getWidth() { 
    WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE); 
    Display display = wm.getDefaultDisplay(); 
    return display.getWidth(); 
} 

und die xml ist:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

<TextView 
    android:id="@+id/leftTextView" 
    android:layout_width="wrap_content" 
    android:layout_height="40dp" 
    android:singleLine="true" 
    android:text="abadabadabadabadabadabadabadabadabadabaasdfasdfasdfadabadabadabadabadabadabadabadabadabadabaasdfasdfasdfadabadabadabadabadabadabadabadabadabadabaasdfasdfasdfad"/> 

<TextView 
    android:id="@+id/rightTextView" 
    android:layout_width="wrap_content" 
    android:layout_height="40dp" 
    android:textColor="#adc391" 
    android:singleLine="true" 
    android:text="adsfasd"/> 

</LinearLayout> 

dies ist der Screenshot nach dem Laufen: enter image description here

+0

Ich bin nicht sicher, das ist der richtige Weg, aber können Sie die Ansicht in oncreate selbst messen Ich versuchte, die textveiw Anzahl der Zeilen zu bekommen, aber ich musste Viewtreeobserver becaure requestlayout und measelayout Funktionen von textview wurde nicht aufgerufen, so machen Sie Ihre Antwort –

+0

Ich kann die gemessene Breite nach dem Aufruf '' 'measureView()' '' in '' onCreate() '' 'bekommen – Weibo

0

Hier ist ein Layout, das tun, was Sie möchten es an:

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:gravity="left"> 

    <TextView 
    android:id="@+id/leftTextView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toLefOf="@+id/rightTextView" 
    android:maxLines="1" 
    android:textSize="18sp" /> 

    <TextView 
    android:id="@+id/rightTextView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentRight="true" 
    android:textSize="18sp" /> 

</RelativeLayout> 

Die wichtigsten Teile hier sind die Schwerkraft des relativen Layouts und al die rechte Textansicht als alignParentRight mit der linken Textansicht anfügen, die an die linke Textansicht angehängt ist.

0

Ich habe diese Art von Usecase in unserer App konfrontiert. In unserer App gibt es 3 Ansichten. ImageView | TextView | ImageView. Die beiden ImageViews müssen im Layout sichtbar sein. Die TextView sollte am Ende ellipsenförmig sein. Und ich kam mit einer benutzerdefinierten ViewGroup.

public class PriorityLayoutHorizontal extends ViewGroup 
{ 

    private ArrayList<Integer> mPriorityHighChildren; 

    public PriorityLayoutHorizontal(Context context) 
    { 
     this(context, null); 
    } 

    public PriorityLayoutHorizontal(Context context, AttributeSet attrs) 
    { 
     this(context, attrs, 0); 
    } 

    public PriorityLayoutHorizontal(Context context, AttributeSet attrs, int defStyleAttr) 
    { 
     super(context, attrs, defStyleAttr); 

     TypedArray typedArray = null; 
     try 
     { 
      typedArray = context.obtainStyledAttributes(attrs, R.styleable.PriorityLayoutHorizontal, defStyleAttr, 0); 
      final int id = typedArray.getResourceId(R.styleable.PriorityLayoutHorizontal_priorityHigh, -1); 
      if(id != -1) 
      { 
       final int[] highPriorityChildren = getResources().getIntArray(id); 
       setPriorityHigh(highPriorityChildren); 
      } 
     } 
     finally 
     { 
      if(typedArray != null) 
      { 
       typedArray.recycle(); 
      } 
     } 
    } 

    public void setPriorityHigh(int... priorityHigh) 
    { 
     Integer[] priorityHighInteger = new Integer[priorityHigh.length]; 
     int i = 0; 
     for(int value : priorityHigh) 
     { 
      priorityHighInteger[i++] = Integer.valueOf(value); 
     } 
     mPriorityHighChildren = new ArrayList<Integer>(Arrays.asList(priorityHighInteger)); 
    } 

    int mMaxHeight = 0; 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 
     final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
     int widthUsed = 0; 
     int heightUsed = 0; 
     final int childCount = getChildCount(); 

     for(int childPosition : mPriorityHighChildren) 
     { 
      final View childView = getChildAt(childPosition); 
      if(childView.getVisibility() != View.GONE) 
      { 
       measureChildWithMargins(childView, widthMeasureSpec, widthUsed, heightMeasureSpec, heightUsed); 
       widthUsed += getMeasuredWidthWithMargins(childView); 
       heightUsed = Math.max(getMeasuredHeightWithMargins(childView), heightUsed); 
      } 
     } 

     for(int childPosition = 0; childPosition < childCount; childPosition++) 
     { 
      if(! mPriorityHighChildren.contains(Integer.valueOf(childPosition))) 
      { 
       final View childView = getChildAt(childPosition); 
       if(childView.getVisibility() != View.GONE) 
       { 
        measureChildWithMargins(childView, widthMeasureSpec, widthUsed, heightMeasureSpec, heightUsed); 
        widthUsed += getMeasuredWidthWithMargins(childView); 
        heightUsed = Math.max(getMeasuredHeightWithMargins(childView), heightUsed); 
       } 
      } 
     } 

     mMaxHeight = heightUsed; 

     int heightSize = heightUsed + getPaddingTop() + getPaddingBottom(); 
     setMeasuredDimension(widthSize, heightSize); 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) 
    { 
     final int paddingLeft = getPaddingLeft(); 
     final int paddingTop = getPaddingTop(); 

     int spaceUsed = paddingLeft; 
     for (int childPosition = 0; childPosition < getChildCount(); childPosition++) 
     { 
      final View childView = getChildAt(childPosition); 
      if(childView.getVisibility() != View.GONE) 
      { 
       final int top = (mMaxHeight/2) - (childView.getMeasuredHeight()/2); 
       layoutView(childView, spaceUsed, paddingTop + top, childView.getMeasuredWidth(), childView.getMeasuredHeight()); 
       spaceUsed += getWidthWithMargins(childView); 
      } 
     } 
    } 

    private int getWidthWithMargins(View child) 
    { 
     final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 
     return child.getWidth() + lp.leftMargin + lp.rightMargin; 
    } 

    private int getHeightWithMargins(View child) 
    { 
     final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 
     return child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; 
    } 

    private int getMeasuredWidthWithMargins(View child) 
    { 
     final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 
     return child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; 
    } 

    private int getMeasuredHeightWithMargins(View child) 
    { 
     final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); 
     return child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; 
    } 

    private void layoutView(View view, int left, int top, int width, int height) 
    { 
     MarginLayoutParams margins = (MarginLayoutParams) view.getLayoutParams(); 
     final int leftWithMargins = left + margins.leftMargin; 
     final int topWithMargins = top + margins.topMargin; 

     view.layout(leftWithMargins, topWithMargins, leftWithMargins + width, topWithMargins + height); 
    } 

    @Override 
    public LayoutParams generateLayoutParams(AttributeSet attrs) 
    { 
     return new MarginLayoutParams(getContext(), attrs); 
    } 

    @Override 
    protected LayoutParams generateDefaultLayoutParams() 
    { 
     return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
    } 
} 

Deklarieren Sie ein benutzerdefiniertes Attribut in Werten/Attr.xml

<declare-styleable name="PriorityLayoutHorizontal"> 
     <attr name="priorityHigh" format="reference"/> 
</declare-styleable> 

Mit diesem Layout können Sie den Ansichten, die auf jeden Fall im Layout sichtbar sein sollen, hohe Priorität einräumen. Der verbleibende TextView wird basierend auf der verbleibenden Breite auf dem Bildschirm gezeichnet.

Um dieses Layout zu verwenden:

<com.example.component.PriorityLayoutHorizontal 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:orientation="horizontal" 
        app:priorityHigh="@array/priority_array" 
        > 

        <TextView 
         android:id="@+id/contact_name" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:singleLine="true" 
         /> 

        <ImageView 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:src="@drawable/your_drawable" 
         /> 

</com.example.component.PriorityLayoutHorizontal> 

Und die Priority_Array in Werte/arrays.xml Hier

<integer-array name="priority_array"> 
     <item>1</item> 
</integer-array> 

definieren, haben wir die Priorität für die Ansicht "1" genannt. Das ist das zweite TextView in Ihrem Layout. So wird der zweite TextView immer sichtbar sein, und der erste TextView wird ellipsentiert.

S.: Dies ist eine generische Lösung. Dies kann mit verschiedenen Ansichten und mehr als 2 Ansichten in einer Zeile verwendet werden. Sie können dieses Layout verwenden oder eine benutzerdefinierte ViewGroup erstellen, die für Ihren Anwendungsfall spezifisch ist.

1

Ich empfehle, zwei TextView in LinearLayout zu verpacken. Dann wenden Sie android:weightSum="1" an diese LinearLayout an und wenden Sie android:layout_weight="1" auf das Kind TextView an, das sich erweitern muss.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:weightSum="1"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:ellipsize="end" 
     android:maxLines="1" 
     android:padding="8dp" 
     android:text="blabla bla bla bla bla bla bla bla bla bla bla bla bla "/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:padding="8dp" 
     android:text="static text"/> 

</LinearLayout> 

Denken Sie daran, die beiden atributes setzen diese es perfekt zu funktionieren:

android:ellipsize="end" 
android:maxLines="1" 

und LinearLayoutandroid:layout_width="wrap_content"

haben muss Wenn Sie diese ViewGroup möchten ganzen Raum nehmen, wickeln Sie es mit einem anderen ViewGroup:

<RelativeLayout 
    android:layout_height="wrap_content" 
    android:layout_width="match_parent"> 

    <!--The previous view group--> 

</RelativeLayout> 
15

Sie können dieses Layout mit dem Attribut TableLayout und shrinkColumns archivieren.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:orientation="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

    <!-- Row 1 --> 
    <TableLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:shrinkColumns="0"> 

     <TableRow 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:gravity="center_vertical"> 

      <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="4dp" 
        android:maxLines="1" 
        android:ellipsize="end" 
        android:text="abcdefghijklmnopqrstuvwxyz"/> 

      <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="4dp" 
        android:maxLines="1" 
        android:ellipsize="none" 
        android:text="rightText"/> 
     </TableRow> 

    </TableLayout> 


    <!-- Row 2 --> 
    <TableLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:shrinkColumns="0"> 

     <TableRow 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:gravity="center_vertical"> 

      <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="4dp" 
        android:maxLines="1" 
        android:ellipsize="end" 
        android:text="Longer Text view abcdefghijklmnopqrstuvwxyz"/> 

      <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="4dp" 
        android:maxLines="1" 
        android:ellipsize="none" 
        android:text="rightText"/> 
     </TableRow> 

    </TableLayout> 

    <!-- Row 3 --> 
    <TableLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:shrinkColumns="0"> 

     <TableRow 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:gravity="center_vertical"> 

      <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="4dp" 
        android:maxLines="1" 
        android:ellipsize="end" 
        android:text="Text view that is very logn and will not fit the parent width abcdefghijklmnopqrstuvwxyz"/> 

      <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:padding="4dp" 
        android:maxLines="1" 
        android:ellipsize="none" 
        android:text="rightText"/> 
     </TableRow> 

    </TableLayout> 

</LinearLayout> 

enter image description here

Here ist dieselbe Frage;)

Verwandte Themen