2010-12-01 19 views
61

Estoy tratando de crear una vista personalizada que reemplace un determinado diseño que utilizo en varios lugares, pero estoy luchando para hacerlo.¿Crea una vista personalizada inflando un diseño?

Básicamente, quiero reemplazar esto:

<RelativeLayout 
android:id="@+id/dolphinLine" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
    android:layout_centerInParent="true" 
android:background="@drawable/background_box_light_blue" 
android:padding="10dip" 
android:layout_margin="10dip"> 
    <TextView 
    android:id="@+id/dolphinTitle" 
    android:layout_width="200dip" 
    android:layout_height="100dip" 
    android:layout_alignParentLeft="true" 
    android:layout_marginLeft="10dip" 
    android:text="@string/my_title" 
    android:textSize="30dip" 
    android:textStyle="bold" 
    android:textColor="#2E4C71" 
    android:gravity="center"/> 
    <Button 
    android:id="@+id/dolphinMinusButton" 
    android:layout_width="100dip" 
    android:layout_height="100dip" 
    android:layout_toRightOf="@+id/dolphinTitle" 
    android:layout_marginLeft="30dip" 
    android:text="@string/minus_button" 
    android:textSize="70dip" 
    android:textStyle="bold" 
    android:gravity="center" 
    android:layout_marginTop="1dip" 
    android:background="@drawable/button_blue_square_selector" 
    android:textColor="#FFFFFF" 
    android:onClick="onClick"/> 
    <TextView 
    android:id="@+id/dolphinValue" 
    android:layout_width="100dip" 
    android:layout_height="100dip" 
    android:layout_marginLeft="15dip" 
    android:background="@android:drawable/editbox_background" 
    android:layout_toRightOf="@+id/dolphinMinusButton" 
    android:text="0" 
    android:textColor="#2E4C71" 
    android:textSize="50dip" 
    android:gravity="center" 
    android:textStyle="bold" 
    android:inputType="none"/> 
    <Button 
    android:id="@+id/dolphinPlusButton" 
    android:layout_width="100dip" 
    android:layout_height="100dip" 
    android:layout_toRightOf="@+id/dolphinValue" 
    android:layout_marginLeft="15dip" 
    android:text="@string/plus_button" 
    android:textSize="70dip" 
    android:textStyle="bold" 
    android:gravity="center" 
    android:layout_marginTop="1dip" 
    android:background="@drawable/button_blue_square_selector" 
    android:textColor="#FFFFFF" 
    android:onClick="onClick"/> 
</RelativeLayout> 

Por esto:

<view class="com.example.MyQuantityBox" 
    android:id="@+id/dolphinBox" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:myCustomAttribute="@string/my_title"/> 

Por lo tanto, no quieren un diseño personalizado, quiero una vista personalizada (no debe ser posible para esta vista tener hijos).

Lo único que podría cambiar de una instancia de MyQuantityBox a otra es el título. Me gustaría poder especificar esto en el XML (como lo hago en la última línea XML)

¿Cómo puedo hacer esto? ¿Debería poner RelativeLayout en un archivo XML en/res/layout e inflarlo en mi clase MyBoxQuantity? Si es así, ¿cómo lo hago?

Gracias!

+0

consulte "Controles compuestos" en Android, y este enlace: http://stackoverflow.com/questions/1476371/android-writing-a-custom-compound-component – greg7gkb

Respuesta

18

Sí, puedes hacer esto. RelativeLayout, LinearLayout, etc. son vistas, por lo que un diseño personalizado es una vista personalizada. Algo a tener en cuenta, porque si quisieras crear un diseño personalizado, podrías.

Lo que quiere hacer es crear un control compuesto. Creará una subclase de RelativeLayout, agregará todos sus componentes en el código (TextView, etc.) y en su constructor podrá leer los atributos transferidos desde el XML. A continuación, puede pasar ese atributo a su título TextView.

http://developer.android.com/guide/topics/ui/custom-components.html

10

Utilice el inflado de diseño, ya que se muestra a continuación

public View myView(){ 
    View v; // Creating an instance for View Object 
    LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    v = inflater.inflate(R.layout.myview, null); 

    TextView text1 = (TextView) v.findViewById(R.id.dolphinTitle); 
    Button btn1 = (Button) v.findViewById(R.id.dolphinMinusButton); 
    TextView text2 = (TextView) v.findViewById(R.id. dolphinValue); 
    Button btn2 = (Button) v.findViewById(R.id. dolphinPlusButton); 


    return v; 
} 
+0

Suyo funcionó perfectamente –

+0

He intentado lo mismo. está funcionando bien.pero, cuando hago clic en btn1, llamará a los servicios web y después de recibir la respuesta del servidor, quiero actualizar algunos textos en la posición particular text2 ... ¿Alguna ayuda por favor? – harikrishnan

5

En la práctica, he encontrado que tiene que ser un poco cuidadoso, especialmente si usted está usando un poco de XML en varias ocasiones . Supongamos, por ejemplo, que tiene una tabla en la que desea crear una fila de tabla para cada entrada en una lista. Que haya configurado algunas xml:

En my_table_row.xml:

<?xml version="1.0" encoding="utf-8"?> 
<TableRow xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" android:id="@+id/myTableRow"> 
    <ImageButton android:src="@android:drawable/ic_menu_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/rowButton"/> 
    <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="TextView" android:id="@+id/rowText"></TextView> 
</TableRow> 

entonces usted quiere crear una vez por fila con algo de código. Supone que ha definido un padre TableLayout myTable para adjuntar las Filas.

for (int i=0; i<numRows; i++) { 
    /* 
    * 1. Make the row and attach it to myTable. For some reason this doesn't seem 
    * to return the TableRow as you might expect from the xml, so you need to 
    * receive the View it returns and then find the TableRow and other items, as 
    * per step 2. 
    */ 
    LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View v = inflater.inflate(R.layout.my_table_row, myTable, true); 

    // 2. Get all the things that we need to refer to to alter in any way. 
    TableRow tr  = (TableRow) v.findViewById(R.id.profileTableRow); 
    ImageButton rowButton = (ImageButton) v.findViewById(R.id.rowButton); 
    TextView rowText = (TextView) v.findViewById(R.id.rowText); 

    // 3. Configure them out as you need to 
    rowText.setText("Text for this row"); 
    rowButton.setId(i); // So that when it is clicked we know which one has been clicked! 
    rowButton.setOnClickListener(this); // See note below ...   

    /* 
    * To ensure that when finding views by id on the next time round this 
    * loop (or later) gie lots of spurious, unique, ids. 
    */ 
    rowText.setId(1000+i); 
    tr.setId(3000+i); 
} 

Para un ejemplo simple clara sobre el manejo de rowButton.setOnClickListener (esto), ver Onclicklistener for a programatically created button.

+0

Hola Neil, lo he intentado igual. está funcionando bien. pero, cuando hago clic en rowButton, llamará a los servicios web y después de recibir la respuesta del servidor, quiero actualizar algunos textos en una posición particular rowText ... ¿Alguna ayuda por favor? – harikrishnan

+0

vea mi pregunta también. https://stackoverflow.com/questions/48719970/android-adding-view-from-inflate-layout-and-how-to-update-particular-textview-va – harikrishnan

75

un poco viejo, pero pensé compartir la forma en que lo haría, basado en la respuesta chubbsondubs': utilizo FrameLayout (ver Documentation), ya que se utiliza para contener una sola vista, e inflar en él la vista del xml.

siguiente código:

public class MyView extends FrameLayout { 
    public MyView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     initView(); 
    } 

    public MyView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     initView(); 
    } 

    public MyView(Context context) { 
     super(context); 
     initView(); 
    } 

    private void initView() { 
     View view = inflate(getContext(), R.layout.my_view_layout, null); 
     addView(view); 
    } 
} 
+4

Dado que la clase View tiene el método static inflate() no hay Necesito para LayoutInflater.from() – outlying

+0

gracias a las afueras, he editado el código con su comentario –

+1

¿No es esta la solución de Johannes desde aquí: http://stackoverflow.com/questions/17836695/android-custom-view -from-inflated-layout Aún así, se infla otro diseño dentro. Por lo tanto, no es realmente la mejor solución que supongo. –

Cuestiones relacionadas