Рубрики
Без рубрики

Учебник по пользовательскому интерфейсу Android: Макеты и анимации

Этот учебник посвящен процедуре использования макетов для представления анимации. Цель состоит в том, чтобы дать вам представление о том, каково это-создавать пользовательский интерфейс для Android от начала до конца.

Автор оригинала: Linton Ye.

Эта статья основана на Рабочее время Кодементора размещено на Линтон Йе из зеркала для Android Studio. В этом сеансе Линтон делает быстрое живое кодирование создания пользовательского интерфейса Android и показывает, как использовать различные макеты, представления (TextView, ListView, ImageView, GridView, RecyclerView) и Движения (Анимация свойств, рисованная анимация) с помощью живого кодирования. Вы можете найти это полезным, прежде чем начнете свой собственный проект.

Цель

Этот учебник посвящен процедуре использования макетов для представления анимации. Вместо того, чтобы продумывать все до мелочей, цель состоит в том, чтобы дать вам представление о том, каково это-создавать пользовательский интерфейс для Android от начала до конца.

Вы можете скачать демо-проект на GitHub .

Макеты

  • Расположение рамок
  • Линейный вывод
  • Относительно
  • Решетка

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

Компоновка Рамки

Итак, во-первых, компоновка кадров-это, по сути, просто наложение материалов друг на друга. В этом макете не так много вариантов. Для этого изображения выше вверху находится ImageView , и есть пара текстовых просмотров , а затем ImageView для этой звезды.

Линейная Планировка

Мы можем начать в основном с линейной компоновки сверху, которая является контейнером для всего. А затем мы помещаем ImageView поверх LinearLayout , в котором у него есть возможность размещать свои дочерние элементы горизонтально или вертикально, чтобы вы могли указывать и атрибутировать. Затем мы можем поместить два текстовых представления, одно под другим, внутри линейного отображения с вертикальной ориентацией.

Один из лучших способов создания макета-свести к минимуму количество просмотров, особенно если это то, что будет появляться снова и снова. Мы хотим, чтобы иерархия была как можно более поверхностной.

Относительная Планировка

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

Пользовательский вид

Если вы выполняете весь рендеринг самостоятельно, вы можете добиться этого, просто используя один пользовательский вид. В зависимости от вашей ситуации иногда действительно необходимо создать собственное представление, если у вас есть приложение, критически важное для производительности, так как это улучшит такие вещи, как необходимость очень быстрой прокрутки списков.

Если системе нужно увеличить только один вид элемента, прокрутка будет очень плавной. Но, конечно, у этого есть своя цена, поскольку его немного сложнее реализовать.

Студия Android

Android Studio намного лучше, чем то, что мы использовали в Eclipse, в ADT, где инструмент пользовательского интерфейса вообще не был полезен. Лично я все еще хожу на фактический .xml много. Для своей работы я, как правило, просто добавляю туда некоторые материалы, которые нам нужно создать, а затем настраиваю их в реальном формате .xml, с которым намного проще работать.

! [[Студия Android](https://s3.amazonaws.com/codementor_content/2015-Apr-week 3/ALC/стандарт+xml.png%)

Выше приведен стандартный xml-файл. Система создаст для вас множество вещей. Если вы посмотрите на изображение выше, обратите внимание, что имя тега-это тип представления или макета, который вы хотите добавить в свой пользовательский интерфейс. Обычно все начинается с android: . Если вы не знакомы с .xml и его пространством имен, просто следуйте этой структуре. Когда что-то пойдет не так, когда вы наберете что-то неприемлемое, Android Studio сообщит вам об этом, так что не беспокойтесь об этом.

Относительная планировка

Как упоминалось ранее, это то, что мы хотим получить в относительной компоновке:

В котором соответствующий код будет выглядеть следующим образом:

Относительная компоновка пользовательского интерфейса Android

Однако приведенный выше код в конечном итоге даст вам это вместо этого:

В Android Studio есть этот фантастический способ, с помощью которого вы можете ввести любую часть строки, он покажет вам список предложений для завершения строки. Итак, без лишних слов, давайте начнем исправлять этот код.

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

Внутри relativelayout вы можете указать положение вашего представления относительно его родителя или его братьев и сестер:



Мы хотели, чтобы название альбома находилось в верхнем левом углу, выровняйте родительский левый ” true “. И alignparenttop ” истина “.

Имя исполнителя должно быть ниже идентификатора/имени. Формат “@+идентификатор/имя” , здесь довольно интересный формат, но это тип ресурсов. Все обобщается как ресурс. Когда у нас есть этот крестик “+” , это означает, что, если у нас еще нет этого идентификатора , я собираюсь его создать. Это типичный способ указания ID в макете.

Что касается звезды, то она будет выровнена справа от своего родителя:

Просмотры

Типы представлений:

  • Текстовое представление, изображение, кнопка…
  • Вид списка, вид сетки
  • Вид переработчика
  • Видоискатель

Прежде чем мы поместим все эти вещи в сетку, давайте рассмотрим, что у нас здесь есть:

Вы уже можете иметь свои пользовательские представления , написанные на Java. A ListView отображает объекты в вертикальном списке, который является одним из наиболее часто используемых представлений в Android. Кроме того, Вид сетки немного устарело.

С прошлого лета Google фактически представила RecyclerView . Если вы пишете новые проекты, используйте RecyclerView вместо Просмотр списка потому что это намного более гибко и дает вам множество других возможностей. Во-первых, ListView покажет вам только вертикальные списки. Чтобы создать список с горизонтальной прокруткой, вам придется найти стороннюю библиотеку или просто закодировать его самостоятельно. Однако, если вы используете RecyclerView , вы можете делать практически все, что угодно.

Для нашей сетки здесь мы также будем использовать RecyclerView .   Но идея в том, что вы действительно можете заполнить эти RecyclerView s а затем посмотрите его на реальном устройстве с помощью этого инструмента.

Вот компонент компоновки activity_album_list.xml что я написал.



  
  

Итак, в приведенном выше примере кода используется RecyclerView .

В нашем Java-коде ( AlbumListActivity.java ), у нас есть два вида деятельности, которые являются одним из основных элементов пользовательского интерфейса Android, поэтому он обрабатывает все взаимодействия с пользователем. Вот как мы можем заполнить представления:

public class AlbumListActivity extends ActionBarActivity {
  public static Object sHook;
  @InjectView(R.id.album_list)
  RecyclerView mAlbumList;

  @InjectView(R.id.toolbar)
  Toolbar mToolbar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_album_list);

    ButterKnife.inject(this);
    mToolbar.inflateMenu(R.menu.menu_album_list);
    populate();
  }

  interface OnVHClickedListener {
    void onVHClicked(AlbumVH vh);
  }

  static class AlbumVH extends RecyclerView.ViewHolder implement…
    private final OnVHClickedListener mListener;
    @InjectView(R.id.album_art)
    ImageView albumArt;
    @InjectView(R.id.name)…

Я не собираюсь вдаваться в подробности о том, как написать все эти материалы, но setContentView(R. layout.activity_album_list) является ключевой частью, поскольку он установит представление содержимого этого действия на макет, который мы только что создавали.

После этого мы можем позволить этому коду заполнить представление:

После этого мы можем позволить этому коду заполнить представление:

private void populate() {
  final int[] albumArts = {R.drawable.christina,
    	R.drawable.ellie,
    	R.drawable.foster,
        R.drawable.keane,
        R.drawable.kodaline,
        R.drawable.pinkrobots,};
  RecyclerView.Adapter adapter = new RecyclerView.Adapter() {
    	@Override
        public AlbumVH onCreateViewHolder(ViewGroup parent, int viewType) {
      View albumView = getLayoutInflater().inflate(R.layout.album_grid_item, parent, false);
      return new AlbumVH(albumView, new OnVHClickedListener() {
        @Override
        public void onVHClicked(AlbumVH vh) {
          int albumArtResId = albumArts[vh.getPosition() % albumArts.length];
          Intent intent = new Intent(AlbumListActivity.this, AlbumDetailActivity.class);
          intent.putExtra(AlbumDetailActivity.EXTRA_ALBUM_ART_RESID, albumArtResId);
                    
          View sharedView = vh.albumArt;
          ActivityOptions ops = ActivityOptions.makeSceneTransitionAnimation(AlbumListActivity.this, sharedView, "albumArt");
          startActivity(intent, ops.toBundle());
        }
      });
    }
        
    @Override
    public void onBindViewHolder(AlbumVH holder, int position) {
      holder.albumArt.setImageResource(albumArts[position % albumArts.length]);
      MockData md = new MockData();
      holder.name.setText(md.phrase());
      holder.artist.setText(md.personName());
    }

В принципе, нужно помнить одну вещь: для заполнения этого RecyclerView , нам нужно создать адаптер , и в этом адаптере мы как бы создаем некоторые данные. Для каждого из представленных там представлений вы хотите создать одну вещь, которая называется ViewHolder . Вы хотите расширить из RecyclerViewholder, и вы собираетесь заполнить каждое представление, вы собираетесь обработать его при нажатии на событие. Вот и весь этот обзор вторсырья.

Опять же, этот проект находится на Github так что вы можете попробовать это сами.

Движение

Вот различные типы движения в дизайне приложений:

  • Анимация свойств
  • Выявить эффект
  • Переходы активности
  • Переходы с видом на берег
  • Просмотр анимации изменения состояния
  • Векторная рисованная анимация

Движение становится намного заметнее, чем раньше. Основным строительным блоком является анимация свойств , которую я собираюсь показать вам, что это значит.

Цель состоит в том, чтобы реализовать эту часть анимации:

Пользовательский интерфейс Android в прямом эфире Пример кодирования 1

Не обязательно возвращаться еще раз, но это координация того, чтобы сделать кнопку больше или меньше, и чтобы эти представления появлялись и исчезали.

Если мы проверим наш activity_album_detail.xml в вашей папке макета вы увидите, какие элементы у нас есть для изображений и представлений, и как вы видите в нашем AlbumDetailBox.java , мы собираемся оживить эти элементы с помощью Зеркала.

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

Два следующих кода java являются нашим компонентом нашего AlbumDetailBox.java :

public class AlbumDetailBox extends MirrorSandboxBase {
    @InjectView(R.id.fab)
    View fab;
    @InjectView(R.id.title_container)
    View cyanPanel;
    @InjectView(R.id.info_container)
    View whitePanel;
    @InjectView(R.id.album_art)
    ImageView albumArt;

    public AlbumDetailBox(View root) {
        super(root);
        ButterKnife.inject(this, root);
    }

    @OnClick(R.id.fab)
    public void onFabClick() {
        Animator anim = ViewAnimationUtils.createCircularReveal(albumArt, 100, 100, 1000, 000);
        anim.start();
    }

Например, вот здесь, если вы знакомы с Ножом для масла , это просто простой способ привязать ваши представления к переменным вместо использования “findViewById”.

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

Если вы хотите, чтобы значок fab уменьшился, вы можете сделать это:

@Override
public void $onLayoutDone(View rootView) {
    enterAnimation().start();
    exitAnimation().start();
    ValueAnimator a = ObjectAnimator.ofFloat(fab, "scaleX", 0, 1).setDuration(1000);
    a.start();
}

Вы можете указать ObjectAnimator цель, которую вы хотите анимировать. Вы можете присвоить ему свойство, которое хотите анимировать, а затем присвоить ему несколько значений. Когда я сохраню его, mirror его скомпилирует. Если вы действительно хотите увидеть анимацию, мы можем замедлить ее, установив продолжительность 2000.

Пример живого кодирования пользовательского интерфейса Android 2

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

Набор для движения

Чтобы упростить анимацию, мы фактически написали библиотеку с открытым исходным кодом, которая называется Motion Kit.

@Override
  public AlbumDetailBox(View root) {
    wrap(fab).scale(0, 1).start();
  }

  private MirrorView wrap(View view) { return new MirrorView<>(view); } 

Это всего лишь немного простого кода-оболочки, чтобы сделать его проще. Мы можем сделать это, обернув представление, которое мы хотим анимировать, со шкалой от нуля до единицы, например wrap(fab).масштаб(0, 1).начало() .

Для остальной части анимации мы хотим как бы оживить дно – в основном развернуть два контейнера внизу.

@Override
public void $onLayoutDone(View rootView) {
  wrap(fab).scale(0, 1);
  unfold(cyanPanel).start();
}

private MirrorView wrap(View view) { return new MirrorView<>(view); }

Я создал несколько вспомогательных функций в нижней части AlbumDetailBox.java , и разверните(голубая панель).start() компилирует только связанные файлы и зависимые от них.

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

@Override
public void $onLayoutDone(View rootView) {
  MotionKit.setGlobaSpeed(0.3);
  MotionKit.sequence(unfold(cyanPanel),
    unfold(whitePanel),
    wrap(fab).scale(0, 1)
  ).start();
}

private MirrorView wrap(View view) { return new MirrorView<>(view); }

Итак, как вы можете видеть, мы сначала разворачиваем голубую панель, а затем разворачиваем белую панель, а затем значок fab. Я установил скорость воспроизведения на 0,3, что будет намного медленнее, так что мы действительно сможем это увидеть:

Пример живого кодирования пользовательского интерфейса Android 3

Однако на самом деле не используйте это в своем окончательном коде, если вы хотите, чтобы ваша анимация была быстрой.

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

public MirrorAnimator exitAnimation() {
    return MotionKit.sequence(wrap(fab).scale(1, 0).duration(200),
        fold(whitePanel).duration(100),
        fold(cyanPanel).duration(100)
    );
}

Что заставит панели сжиматься и складываться до упора. Смысл использования этих методов состоит в том, чтобы поэкспериментировать, чтобы увидеть, правильны ли ваши анимации или нет, и таким образом вам не придется компилировать полное приложение.

В нашем AlbumDetailActivity.java , мы хотим воспроизвести эту анимацию, поэтому я собираюсь создать зеркальную песочницу (mBox).:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_album_detail);
    ButterKnife.inject(this);
    populate();
    initTransitions();
    mBox = new AlbumDetailBox(getWindow().getDecorView());
}

Итак, как вы можете видеть, я создал объект с помощью поля сведений об альбоме mBox(GetWindow().getDecorView()) и в основном я буду использовать его в качестве вспомогательного объекта.

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

В любом случае, это код для нашей анимации ввода:

@Override
public void onTransitionEnd(Transition transition) {
  mBox.enterAnimation().start();
}

Этот метод вернет ваши анимационные сюжеты, которые являются простой оболочкой стандартной анимации свойств. Мы можем позвонить начать , что означает, что после системных переходов он будет воспроизводить анимацию ввода.

Чтобы анимация не мерцала, нам также нужно добавить этот фрагмент кода (я не буду вдаваться в подробности об этом).:

@Override
public void onGlobalLayout() {
  mBox.enterAnimation().setupStage();
}

Другая часть анимации заключается в том, что мы хотим показать, как эти две панели складываются, а также показать, как значок fab уменьшается и возвращается к своему первоначальному размеру. Мы делаем это с переопределением (этот переход является эксклюзивным для Android Lollipop):

@Override
public void finishAfterTransition() {
    MirrorAnimator mirrorAnimator = mBox.exitAnimation();
    mirrorAnimator.getAnimator().addListener(new Animator.AnimatorListener() {
    	@Override
    	public void onAnimationStart(Animator animation) {
        
        }
        
        @Override
        public void onAnimationEnd(Animator animation) {
            superFinishAfterTransition();
        }
        
        @Override
        public void onAnimationCancel(Animator animation) {
        
        }
        
        @Override
        public void onAnimationRepeat(Animator animation) {
        
        }
  });
  mirrorAnimator.start();
}

С помощью приведенного выше кода мы сначала убедимся, что наша анимация воспроизводится, прежде чем воспроизводить системную анимацию. Мы также добавим прослушиватель, который вызовет super FinishAfterTransition() после действия, воспроизводящего системную анимацию.

Последние мысли

Конечно, вы можете делать эти анимации без зеркала, но вам придется запустить полное приложение. Вам нужно будет перестроить его, вам нужно будет развернуть его, и вам придется его запустить. С зеркалом вам не нужно этого делать, если вы используете зеркало.

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

Опять же, вся база моего демо-проекта находится на GitHub .

Часть 2: Вопросы и ответы – Как новички могут начать с дизайна пользовательского интерфейса Android, лучший способ планирования макетов и больше

Оригинал: “https://www.codementor.io/@lintonye/android-ui-tutorial-layouts-and-animations-85jkhcblt”