Alinear 2 textos, 1 normal, 1 opuesto
Yo hago un Android aplicación con un botón donde hay un total de 4 textos y quiero alinear los primeros 2. Uno en el lado izquierdo más de la parte inferior del texto y el otro y el lado derecho del texto inferior.
Así que de esto:
- ¿Cómo puedo utilizar onTouchListeners en cada palabra en un TextView?
- ¿Cómo puedo tener EditText con Clickable Spannables y todavía seleccionable por longClick?
- Android Development: Cómo reemplazar parte de un EditText con un Spannable
- Incorpore la línea que envuelve al usar bulletspan
- Alineación de ImageSpan en la parte superior del TextView
setText(item.title + " " + item.roomId + "\n" + item.teacher + " " + item.classes);
A esto:
setText(declare here a spannable);
Creo que debo trabajar con Spannable , he probado algunas cosas con Alignment.ALIGN_NORMAL
y Alignment.ALIGN_OPPOSITE
pero creo que es primero debe calcular la longitud del texto inferior y luego hacer la alineación. (He encontrado un buen ejemplo aquí, pero no está funcionando en mi configuración).
Espero que alguien me pueda apuntar a una buena dirección.
Editar:
La razón por la que no puedo (creo) usar RelativeLayout
o LinearLayout
es que estoy extendiendo el botón en una clase diferente ( ScheduleItemView.java
):
/** * Custom view that represents a {@link ScheduleItem} instance, including its * title and time span that it occupies. Usually organized automatically by * {@link ScheduleItemsLayout} to match up against a {@link TimeRulerView} * instance. */ public class ScheduleItemView extends Button { private ScheduleItem mItem; public ScheduleItemView(Context context, ScheduleItem item) { super(context); mItem = item; setSingleLine(false); setText(item.title + " " + item.roomId + "\n" + item.teacher + " " + item.classes); // TODO: turn into color state list with layers? int textColor = Color.WHITE; int accentColor = item.accentColor; LayerDrawable buttonDrawable = (LayerDrawable) context.getResources() .getDrawable(R.drawable.btn_block); buttonDrawable.getDrawable(0).setColorFilter(accentColor, PorterDuff.Mode.SRC_ATOP); buttonDrawable.getDrawable(1).setAlpha(item.containsStarred ? 255 : 0); setTextColor(textColor); setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources() .getDimensionPixelSize(R.dimen.text_size_small)); setGravity(Gravity.CENTER | Gravity.BOTTOM); setBackgroundDrawable(buttonDrawable); } public ScheduleItem getScheduleItem() { return mItem; } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec( getMeasuredHeight(), MeasureSpec.EXACTLY)); // layout(getLeft(), getTop(), getRight(), getBottom()); setGravity(Gravity.CENTER); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getRight() - getLeft(), getBottom() - getTop()); } }
He intentado hacer esto en protected void onLayout
( ScheduleItemsLayout.java
):
child.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
Pero eso no funciona. No estoy seguro si debo utilizar new RelativeLayout(this)
.
¿Es mejor utilizar Spannable
en este caso?
El origen del proyecto se puede descargar aquí (que puede importar en Eclipse)
- Html Tag Handler no se llama en Android N para "ul", "li"
- Cadena spannable para Android con espaciado de líneas
- El primer setSpan no funcionó
- Android SpannableString establecer fondo detrás de parte del texto
- A veces, las extensiones de la imagen no son visibles cuando el contenido cubre varias líneas en la vista de texto
- Altura de línea de Android Spannable
- TextView fromHtml enlaces rotos en Lollipop
- Ajuste de la alineación del texto mediante SpannableString
Bueno, si no puedes pasar de Button
a ViewGroup
, esto es lo que puedes hacer en tu clase extendida de Button:
Retirar:
setText(item.title + " " + item.roomId + "\n" + item.teacher + " " + item.classes);
Agregue lo siguiente al constructor ScheduleItemView's
:
float[] fl1 = new float[item.title.length()]; getPaint().getTextWidths(item.title, fl1); float[] fl2 = new float[item.roomId.length()]; getPaint().getTextWidths(item.roomId, fl2); float[] fl3 = new float[item.teacher.length() + item.classes.length() + 1]; getPaint().getTextWidths(item.teacher + " " + item.classes, fl3); float differenceInWidth = sumUpTheArray(fl3) - sumUpTheArray(fl1) - sumUpTheArray(fl2); float fSpaceArray[] = new float[1]; getPaint().getTextWidths(" ", fSpaceArray); int numOfSpaces = (int) (differenceInWidth / fSpaceArray[0]); char[] spaceCharArr = new char[numOfSpaces]; Arrays.fill(spaceCharArr, ' '); setText(item.title + String.valueOf(spaceCharArr) + item.roomId + "\n" + item.teacher + " " + item.classes);
Agregue este método auxiliar que resume un array de float
:
public float sumUpTheArray(float[] arr) { float sum = 0f; for (int i = 0; i < arr.length; i++) { sum += arr[i]; } return sum; }
No está seguro de por qué está sobreescribiendo los onDraw(Canvas)
y onMeasure(int, int)
.
Huelga decir que este es un fragmento de código complicado. Lo que pasa es que estamos midiendo cuánto espacio debemos poner entre title
y roomId
para obtener la alineación deseada. El código es sencillo (aunque cringe-digno), por lo que no se han incluido comentarios.
Por otro lado, puede extender RelativeLayout:
public class ScheduleItemAlternateView extends RelativeLayout { private ScheduleItem mItem; public ScheduleItemAlternateView(Context context, ScheduleItem item) { super(context); mItem = item; int textColor = Color.WHITE; int accentColor = item.accentColor; LayerDrawable buttonDrawable = (LayerDrawable) context.getResources() .getDrawable(R.drawable.btn_block); buttonDrawable.getDrawable(0).setColorFilter(accentColor, PorterDuff.Mode.SRC_ATOP); buttonDrawable.getDrawable(1).setAlpha(item.containsStarred ? 255 : 0); // Three TextViews to hold the `title`, `roomId` // and `teacher&room` independently TextView tvTitle = new TextView(context); TextView tvRoomId = new TextView(context); TextView tvTeacherAndClasses = new TextView(context); // Example ids tvTitle.setId(100); tvRoomId.setId(101); tvTeacherAndClasses.setId(102); tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources() .getDimensionPixelSize(R.dimen.text_size_small)); tvRoomId.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources() .getDimensionPixelSize(R.dimen.text_size_small)); tvTeacherAndClasses.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources() .getDimensionPixelSize(R.dimen.text_size_small)); tvTitle.setPadding(30, 20, 30, 0); tvRoomId.setPadding(30, 20, 30, 0); tvTeacherAndClasses.setPadding(30, 5, 30, 20); tvTitle.setTextColor(textColor); tvRoomId.setTextColor(textColor); tvTeacherAndClasses.setTextColor(textColor); // Set text tvTitle.setText(item.title); tvRoomId.setText(item.roomId); tvTeacherAndClasses.setText(item.teacher + " " + item.classes); // LayoutParms RelativeLayout.LayoutParams paramsTitle = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); paramsTitle.addRule(RelativeLayout.ALIGN_LEFT, tvTeacherAndClasses.getId()); RelativeLayout.LayoutParams paramsRoomId = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); paramsRoomId.addRule(RelativeLayout.ALIGN_RIGHT, tvTeacherAndClasses.getId()); RelativeLayout.LayoutParams paramsTeacherAndClasses = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); paramsTeacherAndClasses.addRule(RelativeLayout.CENTER_HORIZONTAL); paramsTeacherAndClasses.addRule(RelativeLayout.BELOW, tvTitle.getId()); // Add Views to this RelativeLayout addView(tvTitle, paramsTitle); addView(tvRoomId, paramsRoomId); addView(tvTeacherAndClasses, paramsTeacherAndClasses); // Set the background as LayerDrawable setBackgroundDrawable(buttonDrawable); } }
Aquí, creamos tres TextViews, y establecer su LayoutParams para obtener la alineación adecuada.
El resultado es el mismo para ambos, aunque yo recomendaría el segundo enfoque:
Una de las maneras más fáciles que he encontrado para lograr este tipo de comportamiento es tomar ventaja de la propiedad android layout_weight como así:
<?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:layout_margin="30dp" android:background="@color/Orange" android:orientation="vertical" android:padding="20dp" > <LinearLayout android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/top_left_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="SCHK" /> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > </LinearLayout> <TextView android:id="@+id/top_right_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="G102" /> </LinearLayout> <TextView android:id="@+id/bottom_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="VIM M4O3WI, M404WI, M402SJ" /> </LinearLayout>
De esta manera el LinearLayout con un peso de 1 ocupará el espacio necesario para separar correctamente las dos cadenas en la línea superior como se desee.
¿Por qué estás "extendiendo el botón en una clase diferente"? Si está haciendo esto simplemente para obtener la esquina redondeada / fondo naranja que se muestra en su pregunta, puede obtener este mismo efecto estableciendo el fondo de la disposición lineal de nivel superior a la del estilo del botón.
Utilice 3 TextViews dentro de RelativeLayout.
Para el title
android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true"
Para roomId
android:id="@+id/roomId" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true"
Para el teacher
android:id="@+id/teacher" android:layout_below="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerHorizontal="true" android:layout_centerVertical="true"
- ¿Cómo optimizar la red de cola de tomar en android Volley? (Volley Google IO 2013)
- Hipervínculos con esquema no HTTP en GMAIL