studio layout_below espaƱol bottom android android-textview android-relativelayout

android - layout_below - Expanda TextView con wrap_content hasta que la vista del vecino llegue al final del padre



relativelayout android studio (6)

Necesito lograr el siguiente diseño:

Tengo dos TextViews en un diseño relativo: el verde es texto fijo con wrap_content , el negro tiene texto dinámico con wrap_content . El texto negro puede cambiar y hacerse muy largo. Quiero que el TextView negro se expanda con el texto hasta que la vista verde llegue al final del padre. Si eso sucede, el TextView negro debería dejar de expandirse y cambiar de tamaño al final.

¿Cómo puedo lograr eso?

Lo que intenté:

<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>

Pero cuando el texto negro se hace más grande y más grande, empuja el verde fuera de la vista


Aquí hay un diseño que hará lo que le gustaría:

<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>

Las partes clave aquí son la gravedad del diseño relativo y alinear la vista de texto derecha como alignParentRight con la vista de texto izquierda adjunta a la de la izquierda.


El diseño que se espera se puede crear con la ayuda de layout_weight attirbute que viene con LinearLayout . Por lo tanto, es posible que deba usar LinearLayout con los weightSum y layout_weight (que pasan a su vista childview ).

Aquí hay un diseño que divide su ancho de diseño en cuatro partes que se divide en 3: 1 entre ambos Textview . Al TextView TextView a la derecha, TextView izquierda muestra el texto lo más posible que puede mostrar sin perturbar a TextView a la derecha.

Por favor, siéntase libre de probar con la weightSum variante de weightSum y layout_weight según su necesidad.

Diseño:

<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=" " /> <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>


Establecí el ancho máximo de la base de la vista de texto izquierda del ancho de la vista de texto derecha, eché un vistazo a mi código. Espero que esto ayude.

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(); }

y el xml es:

<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>

Esta es la captura de pantalla después de ejecutar:


Le sugiero que TextView dos TextView en LinearLayout . Luego aplique android:weightSum="1" a este LinearLayout y aplique android:layout_weight="1" al TextView secundario que debe extenderse.

<?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>

Recuerda configurar los dos atributos para que funcione perfectamente:

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

y LinearLayout debe tener android:layout_width="wrap_content"

Si desea que este ViewGroup tome todo el espacio, envuélvalo con otro ViewGroup :

<RelativeLayout android:layout_height="wrap_content" android:layout_width="match_parent"> <!--The previous view group--> </RelativeLayout>


Me he enfrentado a este tipo de caso en nuestra aplicación. En nuestra aplicación, hay 3 Vistas. ImageView | TextView | ImageView ImageView | TextView | ImageView . Las dos vistas de imagen deben estar visibles en el diseño. La vista de texto debe ser unlipsizada al final. Y se me ocurrió un ViewGroup personalizado.

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); } }

Declare un atributo personalizado, en valores / attrs.xml

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

Usando este diseño, puede dar alta prioridad a las Vistas que deberían estar visibles en el diseño definitivamente. El resto de un TextView se dibujará en función del ancho restante en la pantalla.

Para utilizar este diseño:

<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>

Y definir la matriz de prioridad en los valores / arrays.xml

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

Aquí, hemos mencionado la prioridad para la Vista "1". Ese es el segundo TextView en su diseño. Por lo tanto, la segunda vista de texto será visible siempre, y la primera vista de texto será ellipsada.

PD: esta es una solución genérica. es decir, esto se puede usar con diferentes Vistas y más de 2 Vistas en una línea. Puede usar este diseño, o podría escribirse un ViewGroup personalizado específico para su caso de uso.


Puede archivar este diseño mediante el atributo TableLayout y shrinkColumns .

<?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>

Here está la misma pregunta;)