Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dive into Android. Основы интерфейса пользователя.

Dive into Android. Основы интерфейса пользователя.

Alex Korovyansky

October 13, 2013
Tweet

More Decks by Alex Korovyansky

Other Decks in Programming

Transcript

  1. 5 Петля сообщение сообщение сообщение сообщение добавление новых сообщений в

    очередь обработчик сообщений очередь onKeyPressed onTouch onTouch onCreate системные события cобытия пользователя • Все сообщения обрабатываются последовательно в порядке очереди • Длительная обработка сообщения приводит к блокировке всей очереди
  2. 6 Петля public static final void loop() { Looper me

    = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } msg.target.dispatchMessage(msg); msg.recycle(); } } } • Из кода Looper.java (версия Android 2.2) • классический бесконечный цикл
  3. 7 Построение UI • View - элемент UI • ViewGroup

    - контейнер для View • Паттерн Компоновщик • Интерфейс пользователя является совокупностью объектов View и ViewGroup
  4. 8 View и ViewGroup public class View ... public abstract

    class ViewGroup extends View ... • onMeasure • onDraw • onKeyDown • onTouchEvent • onTrackballEvent • setTag • ... • 9322 строчки кода • addView • removeView • onLayout • onInterceptTouchEvent • ... • 3747 строчек кода
  5. 9 Разметка UI в XML • Самый простой способ объявить

    интерфейс пользователя - создать xml-файл в папке res/ layout и определить в нем структуру интерфейса <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" /> </LinearLayout>
  6. 10 Как верстать интерфейс? • Проблема: Устройства на Android могут

    иметь экраны самого разного размера и плотности • Решение: • Верстать с использованием относительной компоновки за счет комбинирования разных Layouts • При необходимости предоставлять альтернативные ресурсы для разметки (layouts) • Использовать dp (dip) для указания размеров и позиций (ни в коем случае не px!) • Предоставлять альтернативные ресурсы для графики (drawables) • http://developer.android.com/guide/practices/screens_support.html
  7. 11 Способы создания View • Явное создание путем вызова конструктора

    TextView textView = new TextView(context); • Явное создание путем использования LayoutInflater • Неявное создание View и связь с Activity во время вызова setContentView LinearLayout linearLayout = new LinearLayout(context); View view = inflater.inflate(R.layout.custom_view, null); setContentView(R.layout.activity_main);
  8. 12 LayoutInflater • Объект класса View может быть динамически создан

    на основе xml-разметки с помощью объекта класса LayoutInflater: LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View customView = inflater.inflate(R.layout.custom_view, null); • XML-размета res/layout/customview.xml: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ...> <TextView .../> <Button .../> <RelativeLayout .../> </LinearLayout>
  9. 14 View • Визуальный компонент, предоставляющий определенную функциональность для пользователя

    • Android Framework содержит большое количество самых разнообразных View • Все View выделены в пакет android.widget http://d.android.com/reference/android/widget/package- summary.html • Далее мы рассмотрим наиболее интересные стандартные View, разбив их по группам: Views, Layouts, ScrollViews, AdapterViews
  10. 15 Views • AnalogClock • Button • Checkbox • Chronometer

    • DatePicker • EditText • ImageView • ImageButton • MapView • MediaController • Progressbar • RatingBar • RadioButton • SeekBar • TextView • TimePicker • WebView • VideoView
  11. 16 Views • AnalogClock • Button • Checkbox • Chronometer

    • DatePicker • EditText • ImageView • ImageButton • MapView • MediaController • Progressbar • RatingBar • RadioButton • SeekBar • TextView • TimePicker • WebView • VideoView
  12. 17 Views • AnalogClock • Button • Checkbox • Chronometer

    • DatePicker • EditText • ImageView • ImageButton • MapView • MediaController • Progressbar • RatingBar • RadioButton • SeekBar • TextView • TimePicker • WebView • VideoView
  13. 18 Views • AnalogClock • Button • Checkbox • Chronometer

    • DatePicker • EditText • ImageView • ImageButton • MapView • MediaController • Progressbar • RatingBar • RadioButton • SeekBar • TextView • TimePicker • WebView • VideoView
  14. 19 Layouts • FrameLayout • LinearLayout • TableLayout • RelativeLayout

    • TabLayout* • GridLayout • Используя различные комбинации стандартных Layouts, можно описать практически любой интерфейс • * - TabLayout создается на основе TabHost и TabWidget http://d.android.com/resources/ tutorials/views/hello-tabwidget.html
  15. 20 ScrollViews • Стандартные Layouts не предоставляют возможность скроллирования •

    За это отвечают ViewGroups: ScrollView и HorizontallScrollView • ScrollViews поддерживают только один вложенный элемент • Для реализации скроллинга в двух направлениях HorizontallScrollView вкладывается в ScrollView
  16. 21 AdapterViews • Views c динамическим содержимым • Содержимое такого

    View определяется связанным с ним Adapter • ListView • ExpandableListView • Gallery • GridView • Spinner
  17. 22 Создание нового View • Необходимо реализовать подкласс View, переопределив

    соответствующие методы public class LabelView extends View { ... @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint); } }
  18. 23 Атрибуты нового View • Можно объявить собственные атрибуты для

    View, создав XML definition file в res/values <resources> ... <declare-styleable name="LabelView"> <attr name="text" format="string" /> <attr name="textColor" format="color" /> <attr name="textSize" format="dimension" /> </declare-styleable> </resources> • Использование при объявлении layout в XML: <com.example.android.apis.view.LabelView ... android:background="@drawable/blue" app:text="Blue" app:textSize="20dp"/>
  19. 24 Инструменты UI • hierarchyviewer - детальный анализ состояния интерфейса

    во время выполнения • layoutopt - оптимизация интерфейса на этапе разработки • Обе утилиты входят в состав Android SDK
  20. 26 AdapterView • View, содержимое которого определяется динамически с помощью

    специального объекта-адаптера • Примеры: ListView, GridView, Spinner, Gallery ... • http://d.android.com/guide/ topics/ui/binding.html
  21. 27 Необходимость • Мы не можем описать динамическое содержимое с

    помощью статических Layouts • Например, содержимое списка неизвестно заранее и должно формироваться из БД
  22. 28 Необходимость • Мы не можем выделить память сразу под

    все данные большого объема • Например, галерея должна содержать 10000 картинок, и в каждый момент пользователь видит только 3 из них
  23. 29 Замечание • Формы ввода лучше делать на основе статической

    разметки Layout ... <LinearLayout style="@style/FormField"> <TextView style="@style/Text" android:text="Name"/> <EditText style="@style/EditBox" android:hint="Your Name"/> </LinearLayout> <View style="@style/Divider"/> <LinearLayout style="@style/FormField"> <TextView style="@style/Text" android:text="Password"/> <EditText style="@style/PasswordBox" android:hint="Password"/> </LinearLayout>
  24. 36 Метод getView public View getView(int position, View convertView, ViewGroup

    parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item_icon_text, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); holder.icon = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.text.setText(DATA[position]); holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2); return convertView; } static class ViewHolder { TextView text; ImageView icon; }
  25. Теперь вы знаете принципы работы графического фреймворка Android, что такое

    главный поток и очередь сообщений. Во многих случаях интефейс пользователя можно создать на основе стандартных View. При необходимости можно реализовать собственный View. ListView и другие AdapterViews являются особым случаем Views, требующими понимания процесса адаптирования данных. Резюме 39