Введение
- В этой серии я буду размещать все свои заметки по Android. По мере того, как я узнаю что-то новое о разработке Android, я буду добавлять в эту серию уроки.
Код на GitHub
- ЗДЕСЬ
Видеоверсия
- ЗДЕСЬ
Что мы будем делать
- В этом уроке я покажу, как мы можем иметь различные макеты для нашего приложения в зависимости от размера экрана. Это в конечном итоге означает, что приложение будет иметь один вид для вертикального положения и другой для горизонтального.
- Если вам интересно узнать больше об этой теме, вы можете прочитать официальную документацию ЗДЕСЬ.
К концу этого урока мы сможем увидеть, как мы можем сделать эти два вида:
- И когда наше приложение повернется к горизонтальному виду, оно отобразит это представление:
SlidingPaneLayout
- Класс
SlidingPaneLayout
— это то, что делает за нас всю тяжелую работу. Он позволяет приложению плавно переходить от одного вида к другому. Чтобы использовать его, мы должны обернуть его вокруг классов, которые мы хотим отобразить, как показано ниже:
<androidx.slidingpanelayout.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="280dp"
android:layout_gravity="start"
android:layout_height="match_parent"
tools:context=".fragments.MainFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:layout_marginBottom="100dp"
android:contentDescription="add new calf"
android:src="@drawable/ic_add_black_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/recyclerview"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/detail_container"
android:layout_width="300dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:name="com.elliottsoftware.calftracker2.fragments.NewCalfFragment" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
- Как вы можете видеть из XML-файла выше, мы обернули все, что хотим отобразить, в тег
<SlidingPaneLayout>
. Это означает несколько вещей: 1) перекрытие, если нет ширины для отображения дочерних представлений, в нашем случаеFragmentContainerView
иConstraintLayout
, то они будут перекрывать друг друга. Это даст нам возможность проводить пальцем между этими представлениями. Если мы проведем пальцем от одной стороны экрана к другой, мы сможем перемещаться между всеми видами, вложенными вSlidingPaneLayout
.2) ширина,layout_width
дочерних видов определяет, когда мы сможем увидеть объединенные виды. Обратите внимание, что в XML выше ширина комбинированного представления равна580dp
, что означает, что комбинированное представление будет отображаться только в том случае, если ширина экрана составляет минимум 580dp. В целом, мы хотим, чтобы комбинированное представление было меньше 600dp, если основным устройством, на котором работает наше приложение, является телефон. Еще один важный атрибут, на который следует обратить внимание, этоandroid:layout_weight="1"
, который работает аналогично тому, как он работает внутри LinearLayout. Подробнее оlayout_weight
читайте ЗДЕСЬ. Поскольку только один дочерний элемент имеет layout_weight=»1″, если размер больше 580, то дочерний элемент с layout_weight=»1″ будет расширяться, заполняя остальное пространство.
Вложенный фрагмент
-
Для повторного использования фрагмента мы используем класс
FragmentContainerView
, который представляет собой класс макета, специально разработанный для хранения фрагментов. Обратите внимание, что мы указали атрибутandroid:name
, когда это будет сделано внутри FragmentContainerView, произойдут три вещи -
1) Создается новый экземпляр фрагмента
-
2) Вызывает Fragment.onInflate (раздувает представление)
-
3) выполняется FragmentTransaction для добавления фрагмента в соответствующий FragmentManager.
Обнаружение изменения ориентации
- Были некоторые части моего представления, которые я не хотел показывать при смене ориентации на горизонтальную. Поэтому, чтобы скрыть определенные представления, мы должны обнаружить изменение ориентации. Для этого поместите этот код внутрь метода
onViewCreated()
:
val orientation:Int = resources.configuration.orientation
if(orientation == Configuration.ORIENTATION_LANDSCAPE){
//code to hide
fabButton.hide()
}
- Сначала я определяю ориентацию, а затем скрываю вид. Большинство представлений можно скрыть от пользователя, сначала получив ссылку на них, а затем вызвав метод
hide()
.
Странные ошибки, с которыми я столкнулся в горизонтальном представлении
-
1) Первая ошибка, с которой я столкнулся, была связана с
EditText
. В горизонтальной конфигурации, когда пользователь нажимал на EditText, появлялась массивная белая клавиатура, которая закрывала все вокруг (мягкая клавиатура). Чтобы исправить это, я применилandroid:imeOptions="flagNoExtractUi"
к каждому EditText в моих XML файлах. Это указывает системе Android не показывать полную клавиатуру при вводе текста. Это позволяет сделать пользовательский интерфейс менее раздражающим, когда EditText отображается на весь экран. -
2) Вторая ошибка заключалась в том, что эффект прокрутки в представлении EditText перестал работать. Это означало, что пользователь не мог видеть, что он набирает. Чтобы исправить это, я обернул ScrollView вокруг LinearLayout следующим образом:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout>
</LinearLayout>
</ScrollView>
ScrollView
позволяет пользователю прокручивать представление EditText, если оно не видно при наборе текста.
Программная замена панели деталей
- руководство об этом будет в моем следующем посте.
Заключение
- Спасибо, что нашли время, чтобы прочитать эту статью в моем блоге. Если у вас есть какие-либо вопросы или проблемы, пожалуйста, комментируйте их ниже или свяжитесь со мной в Twitter.