Cómo cambiar el margen de TextView

82

He agregado TextView programáticamente en LinearLayout y en algunos eventos externos quiero disminuir el margen inferior de ese TextView a -10, para eso intenté seguir.

LinearLayout.LayoutParams lastTxtParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lastTxtParams.setMargins(0, 0, 0, -10);
mOldTextView.setLayoutParams(lastTxtParams);
mOldTextView.invalidate();

¿Es la forma correcta de modificar el margen del widget que se ha agregado a la vista?
De alguna manera no está funcionando.

Usuario7723337
fuente

Respuestas:

187
TextView forgot_pswrd = (TextView) findViewById(R.id.ForgotPasswordText);
forgot_pswrd.setOnTouchListener(this);     
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llp.setMargins(50, 0, 0, 0); // llp.setMargins(left, top, right, bottom);
forgot_pswrd.setLayoutParams(llp);

Hice esto y funcionó perfectamente. Tal vez debido a que está dando el valor en -ve, es por eso que su código no funciona. Simplemente coloque este código donde está creando la referencia de la vista.

Debarati
fuente
Esta llamada requiere API nivel 19.
Sanjay Kumar
4
@SanjayKumar - No, no hay ninguna restricción de que requiera API nivel 19
Debarati
1
¿Cómo responde esto a la pregunta de OP? Parece que el código es el mismo excepto por el escuchador táctil de configuración de línea adicional redundante, que no llama a invalidate () y no indica explícitamente argumentos en el constructor para LinearLayout.LayoutParams [LayoutParams.WRAP_CONTENT vs LinearLayout.LayoutParams.WRAP_CONTENT]? Además (no es que pueda importar), OP solicita establecer márgenes en TextView creado mediante programación, aunque la respuesta obtiene TextView del diseño xml, a través de findViewById (). Tengo curiosidad por lo que me estoy perdiendo aquí ...
Melquiades
@Melquiades está de acuerdo con usted, eliminado como respuesta seleccionada ya que no responde la pregunta, también como se menciona en los Maybe as you are giving the value in -vemárgenes de respuesta puede ser un valor -ve.
User7723337
61

Su diseño en xml probablemente ya tenga un atributo layout_margin (Izquierda | Derecha | etc.), lo que significa que necesita acceder al objeto generado por ese xml y modificarlo.

Encontré que esta solución es muy simple:

ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) mTextView
        .getLayoutParams();

mlp.setMargins(adjustmentPxs, 0, 0, 0);

break;

Obtenga la instancia de LayoutParams de su vista de texto, descúbrala a MarginLayoutParams y use el método setMargins para establecer los márgenes.

Danny Armstrong
fuente
Esto me da ClassCastException: -> ViewGroup.LayoutParams no se puede convertir en ViewGroup.MarginLayoutParams
Harshil Pansare
10

Este es un problema complicado, configuré el margen para la vista de texto en una fila de un diseño de tabla. ver lo siguiente:

TableLayout tl = new TableLayout(this);
tl.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

TableRow tr = new TableRow(this);        
tr.setBackgroundResource(R.color.rowColor);

LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(4, 4, 4, 4);

TextView tv = new TextView(this);
tv.setBackgroundResource(R.color.textviewColor);
tv.setText("hello");
tr.addView(tv, params);

TextView tv2 = new TextView(this);
tv2.setBackgroundResource(R.color.textviewColor);
tv2.setText("hi");
tr.addView(tv2, params);

tl.addView(tr);
setContentView(tl);

la clase necesaria para importar para LayoutParams para su uso en una fila de tabla es:

import android.widget.**TableRow**.LayoutParams;

importante tener en cuenta que agregué la clase para la fila de la tabla. de manera similar, muchas otras clases están disponibles para usar LayoutParams como:

import android.widget.**RelativeLayout**.LayoutParams;

importar android.widget. LinearLayout .LayoutParams;

así que utilícelo en consecuencia.

Chamán Virk
fuente
5

setMargins () establece los márgenes INTERIORES de TextView, no los márgenes de diseño. ¿Es eso lo que quieres hacer? Estos dos márgenes diferentes pueden ser bastante complicados.

Si desea establecer los márgenes de diseño, cambie los LayoutParams de TextView (textview.getLayoutParams (), luego cambie los parámetros en el objeto LayoutParams devuelto).

No necesitas cambiar nada en tu LinearLayout.

Saludos, Oliver

Oliver
fuente
3

TextView no es compatible con setMargins. Los documentos de Android dicen:

Aunque una vista puede definir un relleno, no proporciona ningún soporte para los márgenes. Sin embargo, los grupos de vistas brindan ese apoyo. Consulte ViewGroup y ViewGroup.MarginLayoutParams para obtener más información.

andig
fuente
1

Aquí hay otro enfoque ...

Cuando me encontré con el mismo problema, no me gustaron las soluciones sugeridas aquí. Entonces, se me ocurrió otra forma: inserté un TextView en el archivo XML entre los dos campos que quería separar con dos campos importantes:

  1. visibilidad establecida en "GONE" (no ocupa ningún espacio ..)
  2. la altura se establece en lo que necesite que sea la separación.

    XML:
    ...//some view up here
    <TextView
        android:id="@+id/dialogSeparator"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:visibility="gone"/>
    ...//some view down here
    

Ahora, el código, todo lo que necesitaba para hacerlo es cambiar la visibilidad a invisible (es decir, está allí y ocupa el espacio necesario, pero no se ve)

    JAVA:

    TextView tvSeparator = (TextView)activity.findViewById(R.id.dialogSeparator);
    tvSeparator.setVisibility(View.INVISIBLE);
    //Inside an activity extended class I can use 'this' instead of 'activity'.

Viola ... tengo el margen necesario. Por cierto, esta solución es para LinearLayout con orientación vertical, pero puede hacerlo con diferentes diseños.

Espero que esto ayude.

JamesC
fuente
0

Probablemente estaba cambiando el margen de diseño después de haberlo dibujado. mOldTextView.invalidate () es inútil. necesitaba llamar a requestLayout () en el padre para retransmitir la nueva configuración. Cuando movió el código de cambio de diseño antes de que se realizara el dibujo, todo funcionó bien.

Radu Simionescu
fuente
0
        TextView tv = (TextView)findViewById(R.id.item_title));
        RelativeLayout.LayoutParams mRelativelp = (RelativeLayout.LayoutParams) tv
                    .getLayoutParams();
        mRelativelp.setMargins(DptoPxConvertion(15), 0, DptoPxConvertion (15), 0);
        tv.setLayoutParams(mRelativelp);

    private int DptoPxConvertion(int dpValue)
    {
       return (int)((dpValue * mContext.getResources().getDisplayMetrics().density) + 0.5);
    }

getLayoutParams () de la vista de texto se debe convertir en los parámetros correspondientes basados ​​en el Padre de la vista de texto en xml .

<RelativeLayout>
   <TextView
    android:id="@+id/item_title">
</RelativeLayout>

Para representar el mismo tamaño real en diferentes dispositivos, use el método DptoPxConvertion () que he usado anteriormente. setMargin (left, top, right, bottom) params tomará valores en píxeles, no en dp . Para obtener más información, consulte esta respuesta de enlace

anand krish
fuente