Описание состояний интерфейса в XML вместо кода для Android
Перейдя в Java и Android из мира C# .NET так и хочется притащить в чужой монастырь свой устав. В данном случае речь пойдет о декларативных состояниях интерфейса (Visual States). Начнем сразу с простой проблемки: у нас есть вьюшка, на которой отображается профиль какого-то пользователя, но, в зависимости от роли текущего пользователя, эта вьюшка может чуть-чуть отличаться. Допустим, у нас есть три роли: guest, member и moderator, и состояния этой вьюшки будут выглядеть следующим образом:
Эти состояния похожи, поэтому будет нелогично делать три разных лэйаута (представим, что реальная вьюшка намного сложнее, но между состояниями больше сходств, чем различий). Как вариант — описать один XML со всеми кнопками и потом кодом менять видимость нужных кнопок для нужных состояний. Вот здесь и приходят на помощь вижуал стейты, которые позволят нам описать эти самые состояния прямо в XML нашей вьюшки без кода. Фактически, код будет делать только goToState (stateName). Так это делают в мире C# + XAML, причем, в специальном редакторе (Blend) можно создавать эти состояния, визуально менять интерфейс (он запомнит изменения для текущего стейта), настраивать переходы между стейтами, добавлять анимации, создавать параллельные стейт машины. Я лишь попытался в стиле proof of concept перенести это в Android на уровне минимального функционала. Вот как будет выглядеть разметка и состояния для нашего примера:
Собственно, VisualStateManager — это фэйковый виджет (ViewGroup), который является контейнером именованных стейтов (VisualState), которые в свою очередь являются контейнерами сеттеров. Сеттер — абстрактный класс, с одним методом apply и свойством target. Я описал пяток стандартных сеттеров, но ни что не мешает добавить свои :-).А когда мы переходим в какое-нибудь состояние — выполнятся все его сеттеры.Таким образом, в коде чистота и только одинокий вызов stateManage.goToState («Moderator») вместо кучи лапши, управляющей свойствами виджетов (хотя по сути, лапша перебралась в XML). public class MainActivity extends Activity {
private VisualStateManager visualStateManager;
@Override protected void onCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); visualStateManager = (VisualStateManager)findViewById (R.id.visualStateManager);
//init view with «guest» state (it can be done via XML as well) visualStateManager.goToState («Guest»);
//go to «moderator» state on FB button click ((ImageButton)findViewById (R.id.facebookButton)).setOnClickListener ((view) → { visualStateManager.goToState («Moderator»); }); } } В качестве упреждающего удара комментариям:
Повторюсь, это то, чем в мире XAML очень часто пользуются (в основном благодаря хорошей поддержке редактором — Blend), возможно покажется интересной идеей и Android разработчикам.Ссылка на репозиторий на GitHub с рабочим кодом концепта: тыц.