Android: как добавить детей из XML-макета в пользовательский вид - PullRequest
10 голосов
/ 13 февраля 2012

В моих макетах xml у меня есть пользовательское представление, в которое я добавлю таких детей, как:

<com.proj.layouts.components.ScrollLayout
    android:id="@+id/slBody"
    android:layout_width="700dp"
    android:layout_height="400dp">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="child1"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="child2"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="child3"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="child4"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="child5"/>
</com.proj.layouts.components.ScrollLayout>

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

public class ScrollLayout extends LinearLayout {
    // View responsible for the scrolling
    private FrameLayout svContainer;
    // View holding all of the children
    private LinearLayout llContainer;

    public ScrollLayout(Context context) {
        super(context);
        init();
    }

    public ScrollLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        super.removeAllViews(); // kill old containers


        svContainer = new HorizontalScroll(getContext());
        llContainer = new LinearLayout(getContext());
        llContainer.setOrientation(orientation);
        svContainer.addView(llContainer);

        svContainer.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        llContainer.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

        addView(svContainer);


    }

    ... I left out the part which takes care of the scroll event ...
}

Как можно добавить Child * в llContainer?

Ответы [ 3 ]

11 голосов
/ 13 февраля 2012

Почему бы вам просто не добавить всех детей в LinearLayout из вашего ScrollLayout? Это должно быть сделано методом onFinishInflate().

for (int i = 0; i<getChildCount(); i++)
{
    View v = getChildAt(i);
    removeViewAt(i);
    llContainer.addView(v);
}

Когда вы пишете свою структуру в XML-файле - все внутренние представления являются дочерними элементами вашего пользовательского макета. Просто замените его на LinearLayout.

7 голосов
/ 10 декабря 2013

Ответ Jin35 имеет серьезную проблему: getChildCount() меняет значение на итерациях, потому что мы удаляем дочерние элементы.

Это должно быть лучшим решением:

while (getChildCount() > 0) {
    View v = getChildAt(0);
    removeViewAt(0);
    llContainer.addView(v);
}
4 голосов
/ 27 сентября 2015

Я согласен, что ответ Jin35 ошибочен. Также добавлен svContainer, поэтому мы не можем продолжить, пока getChildCount () == 0.

К концу init () getChildCount () == 1, поскольку svContainer был добавлен, а TextViews - нет. К концу onFinishInflate () текстовые представления были добавлены и должны быть в позициях 1, 2, 3, 4 и 5. Но если вы затем удалите просмотр в позиции 1, индексы остальных уменьшатся на 1 ( стандартное поведение списка).

Я бы предложил:

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    View v;
    while ((v = getChildAt(1)) != null) {
        removeView(v);
        llContainer.addView(v);
    }
}
...