Использование относительного позиционирования для представлений в ViewSwitcher

У меня возникла проблема с RelativeLayout и ViewSwitcher здесь, и, возможно, кто-то сможет помочь. Итак, я хочу переключить два представления с помощью ViewSwitcher, однако тот факт, что переключатель является частью уравнения, должен быть скрыт от пользователя/разработчика; вместо этого они должны иметь дело только с одним из двух переключаемых представлений.

Чтобы это работало, я предоставляю настраиваемый виджет, который при раздувании удаляет себя из дерева представлений, вставляет ViewSwitcher в свою предыдущую позицию, а затем повторно вставляет себя в качестве дочернего элемента переключателя представлений. Эта часть работает нормально.

Если теперь у меня есть два таких представления, позиционирование их относительно родителя (например, с использованием layout_alignParentBottom) работает просто отлично, но не тогда, когда я пытаюсь расположить их относительно друг друга, используя, например, layout_toRightOf=id.

Однако это работает, когда я копирую идентификатор переключаемого представления в ViewSwitcher (его новый родитель), но я не понимаю, почему это необходимо, и, вероятно, будет дождь из лягушек или что-то в этом роде при наличии более одного представления с одним и тем же идентификатором. в дереве просмотра?

Вот код для пояснения:

// onLayout of the custom view that automatically inserts itself under a ViewSwitcher
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);

    if (!(getParent() instanceof ViewSwitcher)) {

        // uncommenting this line fixes the issue,
        // but I don't want duplicate IDs!
        //switcher.setId(getId());

        // "migrate" this view's LPs to the new parent
        switcher.setLayoutParams(getLayoutParams());

        ViewGroup parent = (ViewGroup) this.getParent();
        System.out.println("PARENT: " + parent);
        int selfIndex = parent.indexOfChild(this);
        parent.removeView(this);
        parent.addView(switcher, selfIndex);

        ViewSwitcher.LayoutParams newParams = new ViewSwitcher.LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        switcher.addView(this, newParams);
    }
}

Затем в XML-файле макета пользователю просто нужно раздуть это пользовательское представление:

<com.myview.CustomView android:id="@+id/one" ... />
<!-- this works: -->
<com.myview.CustomView android:layout_alignParentTop="true" ... />
<!-- this doesn't without the ID hack: -->
<com.myview.CustomView android:layout_toRightOf="@id/one" ... />

другими словами, поскольку layout_toRightOf становится атрибутом нового ViewSwitcher, а идентификатор остается атрибутом пользовательского представления, выравнивание переключателя относительно представления, являющегося дочерним элементом другого переключателя представлений, не работает, и я понятия не имею, почему. Только если я также дам коммутатору тот же идентификатор, что и его дочерний элемент, тогда позиционирование будет работать.

Любые указатели на то, что здесь происходит не так?


person Matthias    schedule 03.05.2012    source источник


Ответы (1)


Не уверен, что я прав, но разве представления не должны находиться на одном уровне иерархии представлений, когда вы позиционируете их относительно друг друга?

Поэтому, возможно, вам следует определить свою ссылку наоборот: представление имеет атрибут android:layout_toRLeftOf"@id/two, и как только вы создадите ViewSwitcher, вы просто скопируете параметр макета дочернего элемента.

person Maria Neumayer    schedule 03.05.2012
comment
Я думаю, вы можете быть правы в том, что можете ссылаться только на представления на одном уровне (т.е. братья и сестры). Хотя не уверен, что понимаю ваши предложения. Не приведет ли это к той же асимметрии? Просто для уточнения: представления внутри переключателя представлений должны сохранять свои идентификаторы, поскольку в противном случае вызов findViewById вернет представление, отличное от того, которое объявлено в макете XML. Более того, они не могут указать layout_toRightOf, так как у них будет ViewSwitcher.LayoutParams, который не поддерживает относительное размещение. Или я просто упускаю из виду вашу мысль? - person Matthias; 03.05.2012
comment
Интересно, читая другой пост здесь, я только что обнаружил, что на самом деле идентификаторы представления не должны быть не уникальными. Затем я проверил, что возвращает findViewById, и это было дочернее представление, а не ViewSwitcher, даже если они имеют общий идентификатор. Это именно то, что мне нужно, но мне интересно, какая логика findViewById применяется, если существует более одного представления с одним и тем же идентификатором? - person Matthias; 03.05.2012
comment
Но вы должны использовать layoutParams родителя, который должен быть RelativeLayout. Таким образом, вы должны иметь возможность получить layoutParams вашего CustomView, установить layoutParams ViewSwitcher (не дочернего!), И все должно быть в порядке. Не уверен, что полностью понял вашу иерархию :) - person Maria Neumayer; 03.05.2012
comment
И что касается второго вопроса (и это просто предположение), я предполагаю, что он использует представление, которое было определено первым, то есть то, которое вы определили в xml. - person Maria Neumayer; 03.05.2012