Создать пользовательский вид, раздувая макет?

Я пытаюсь создать пользовательский вид, который заменит определенный макет, который я использую в нескольких местах, но я изо всех сил стараюсь это сделать.

В принципе, я хочу заменить это:

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

Таким образом:

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

Итак, я не хочу настраиваемый макет, мне нужен пользовательский вид (для этого представления не должно быть дочернего).

Единственное, что может измениться от одного экземпляра MyQuantityBox к другому, - это заголовок. Я очень хотел бы указать это в XML (как и в последней строке XML)

Как я могу это сделать? Должен ли я помещать RelativeLayout в XML файл в /res/layout и раздувать его в моем классе MyBoxQuantity? Если да, то как это сделать?

Спасибо!

Ответ 1

Да, вы можете это сделать. RelativeLayout, LinearLayout и т.д. - это виды, поэтому пользовательский макет - это настраиваемый вид. Просто подумайте, потому что если вы хотите создать собственный макет, вы могли бы.

Что вы хотите сделать, это создать составной элемент управления. Вы создадите подкласс RelativeLayout, добавите все наши компоненты в код (TextView и т.д.), А в своем конструкторе вы сможете прочитать атрибуты, переданные из XML. Затем вы можете передать этот атрибут в свой заголовок TextView.

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

Ответ 2

Немного устарел, но я подумал о том, как мне это сделать, на основе ответа chubbsondubs: Я использую FrameLayout (см. Документация), так как он используется для того, чтобы содержать один вид и раздувать в нем представление из xml.

Следующий код:

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

Ответ 3

Используйте разводку макета, как показано ниже

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

Ответ 4

На практике я обнаружил, что вам нужно быть немного осторожным, особенно если вы много раз используете бит xml. Предположим, например, что у вас есть таблица, в которой вы хотите создать строку таблицы для каждой записи в списке. Вы создали несколько xml:

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

Затем вы хотите создать его один раз в строке с некоторым кодом. Предположим, что вы определили родительский TableLayout myTable, чтобы привязать строки к.

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

Для простого простого примера обработки rowButton.setOnClickListener(см. Onclicklistener для запрограммированной кнопки.