Pull to refresh

Comments 14

с размахом )
не было бы проще одновременно менять padding и margin у вьюхи URL'а?
легко можно добиться какого угодно эффекта разворачивания со стоянием самого контента на месте
android:paddingTop="20dp"
 
android:layout_marginTop="20dp"


анимируем к:

android:paddingTop="40dp"
android:layout_marginTop="0dp"


«контент» вьюхи на месте на месте, бэкграунд разъехался
ps: в чем сакральный смысл наследоваться от ViewGroup, а не RelativeLayout? все эти onMeasure и тд.
не было бы проще одновременно менять padding и margin у вьюхи URL'а?
Было бы проще, но тогда на каждый шаг анимации приходилось бы по вызову onMargin+onLayout, что, на мой взгляд, не оптимально.
ps: в чем сакральный смысл наследоваться от ViewGroup, а не RelativeLayout? все эти onMeasure и тд.
В данном конкретном случае исключительно в том, чтобы иметь полный контроль над тем, как дочерние вьюхи измеряются и располагаются. В принципе, я бы мог реализовать всё тоже самое с использованием FrameLayout не потеряв в производительности. Но это только потому, что разметка достаточно простая. Чем сложнее разметка, тем ощутимей выгода от использования таких вот ViewGroup. Я как раз собираюсь перевести замечательную статью по этому поводу как только смогу достучаться до автора. Пока можете самостоятельно ознакомится с оригиналом.

Кстати, почему вы упомянули именно RelativeLayout?
Было бы проще, но тогда на каждый шаг анимации приходилось бы по вызову onMargin+onLayout,

если ToolbarLayout будет иметь фиксированную высоту (а в вашем случае это напрашивается) то не должно быть onLayout от изменения дочерних элементов.
Кажется, вы не совсем верно понимаете процедуру размещения элементов. Сама по себе вьюха не имеет возможности разместить себя внутри контейнера, она только может намекнуть ему, что хочет расположиться вот здесь и иметь вот такой размер. А в обязанности контейнера входит задать вьюхе размер в соответствии с запрошенным (или просто по своему усмотрению), вычислить координаты для её размещения и сказать этой вьюхе «теперь ты имеешь вот такой размер и расположена вот по таким координатам». Другими словами, чтобы на самом деле изменить размер любого компонента, нужно заново выполнить measure+layout+draw на его контейнере. Вот материал на эту тему — How Android draws views.
имеется ввиду что если ToolbarLayout имеет фиксированные размеры то при изменении margin/padding его дочерней вьюхи то «measure+layout+draw» выполнится на ToolbarLayout но не вызовет ту же самую цепочку выше по иерархии.
Да, но смысл был избавиться именно от этих вызовов у ToolbarLayout во время работы анимации.
Такого эффекта как на последнем видео я добился следующим образом:
1. В layout, который содержит EditText и Button добавил android:animateLayoutChanges=«true»
2. В слушателе setOnFocusChangeListener изменяю visibility кнопки.

Но вы умолчали о самом интересном — как именно вы заставляете EditText «разъезжаться» по всей ширине контейнера?

PS: возможно вы просто не заметили на видео — изначально ширина и высота EditText'а меньше родительского контейнера. Когда он получает фокус — он не только уезжает своей правой границей на место исчезнувшей кнопки, он занимает собой весь родительский контейнер.
Самый простой способ: LinearLayout + android:layout_weight=1
Всё равно мы не поняли друг друга. Возьмём для примера простой xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60px"
	android:orientation="horizontal">

    <EditText
        android:id="@+id/urlContainer"
        android:layout_width="0px"
        android:layout_height="match_parent"
		android:layout_weight="1"
        android:layout_margin="10px" />

    <Button
        android:id="@+id/tabSwitcher"
        android:layout_width="60px"
        android:layout_height="60px"
        android:layout_gravity="right" />

</LinearLayout>

Допустим, компоненты отресайзились и мы получили следующее:
  • Контейнер, width: 400px, height: 60px
  • Button, width: 60px, height: 60px
  • EditText, width: 400-60-10-10=320px, height:60-10-10=40px

Теперь при получении фокуса мы скрываем кнопку. При вашем подходе EditText расползётся вправо на место пропавшей кнопки, то есть станет 380x40px.

Моя же задача — сделать так, чтобы он стал по размеру родительского контейнера — 400x60px, хотя-бы визуально.
Ну еще добавить изменение padding у LineraLayout. И будет совсем точь в точь)

Конечно, если потребуется более сложное поведение, то без customviewgroup не обойтись.
Ну еще добавить изменение padding у LineraLayout. И будет совсем точь в точь)
Воооот, я как раз надеялся, что вы подскажете как это сделать с использованием данного фреймворка.

Конечно, если потребуется более сложное поведение, то без customviewgroup не обойтись.
Тут дело скорее не в ViewGroup, как я уже отвечал выше, в данном конкретном случае всё то же самое можно сделать с помощью обычного FrameLayout, даже практически onMeasure и onLayout переписывать не придётся. Это уже я заморочился с прицелом на более сложное расположение элементов в будущем.
Опередили вы меня друг, но в дополнение скажу что надо в LayoutTransaction установить «CHANGING»
Код
public class SearchView extends LinearLayout implements View.OnFocusChangeListener {
    EditText editText;
    Button button;
    public SearchView(Context context) {
        super(context);
        init(context);
    }

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

    public SearchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    void init(Context c){
        setOrientation(HORIZONTAL);
        setGravity(Gravity.CENTER_VERTICAL);
        LayoutTransition layoutTransition = new LayoutTransition();
        layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
        setLayoutTransition(layoutTransition);
        button = new Button(c);
        button.setText("+");
        button.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        addView(button);
        editText = new EditText(c);
        editText.setHint("Address");
        editText.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        editText.setOnFocusChangeListener(this);
        addView(editText);
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        button.setVisibility(hasFocus ? GONE : VISIBLE);
    }
}

Только тогда у EditText LayoutParams должны быть
<EditText
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />

И эффект выходит немного другой

Однако для простых анимаций, конечно, гораздо удобней и быстрее пользоваться именно LayoutTransitions.
Sign up to leave a comment.

Articles