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

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

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

Avatar for Alex Korovyansky

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