В чем разница между фрагментом, расширяющим базовый класс, и включенным?
Я новичок в Android, и я пытаюсь понять, как сделать повторно используемые части пользовательского интерфейса, с которыми я могу взаимодействовать. Я знаю, что есть несколько методов, но я не понимаю, когда один будет лучше, чем другой, или все они могут использоваться взаимозаменяемо. Если кто-то может указать на различия (или если я неправильно понял), это будет оценено.
- Создание фрагмента или фрагмента деятельности, который заботится о новой странице. Этот фрагмент может затем использоваться всякий раз, когда это применимо, но необходимо соблюдать особую осторожность, чтобы заботиться о жизненных циклах фрагмента.
- Расширение базового класса, который имеет макет и все остальное, что необходимо. Любой другой класс может затем расширить эту базу и заставить базовый интерфейс также появляться и работать.
- С помощью
<include layout=...
позволяет повторно использовать только части пользовательского интерфейса. Для этого я не уверен, где логика для этого макета должна идти.
Я предполагаю, что я прошу об исчерпании каждого из них, и если я могу использовать тот, который мне удобнее, без каких-либо негативных последствий.
PS: Я бы использовал их для таких вещей, как создание многоразовой навигационной панели, которую я могу разместить на каждой странице, или если на разных страницах есть кнопка помощи.
1 ответ
Каждый из предложенных вами методов незаменим для создания пользовательских интерфейсов многократного использования, и каждый из них используется по-разному.
Во-первых, макеты просто определяют визуальную структуру пользовательского интерфейса, а действия и фрагменты - это компоненты, которые определяют, как действует эта визуальная структура. Это создает четкое разделение между визуальной структурой и поведением пользовательского интерфейса.
Следовательно <include/>
тег используется для повторного использования определенной визуальной структуры. Эта визуальная структура может быть включена в любой макет, но каждое действие или фрагмент могут определять, как эта визуальная структура ведет себя отдельно.
Чтобы создать многократно используемое поведение, вы можете создать подкласс Activity
, Например; FragmentActivity
сохраняет поведение, определенное в Activity
класс, но добавляет возможность размещения одного или нескольких фрагментов. Любой класс, который подклассы FragmentActivity
сохранит каждое из этих поведений также.
Фрагменты были разработаны для повторного использования сегментов Activity
и может определять собственную визуальную структуру и поведение. Поэтому, если вы хотите иметь возможность повторно использовать как визуальную структуру, так и поведение раздела Activity
Вы можете создать Fragment
для того, чтобы сделать это. Фрагменты могут также быть разделены на подклассы, это может использоваться, чтобы изменить визуальную структуру, поведение или оба из расширенного класса.
И это не единственные способы создания многоразового интерфейса. Вы можете определить повторно используемые ресурсы, представления, стили или анимации для создания модульного пользовательского интерфейса. Изучение того, как использовать эти различные компоненты в соответствии с вашими потребностями, является важной частью разработки Android (и разработки в целом).
Наконец, я рассмотрю ваш пост сценарий; как создать многоразовую панель навигации для каждой страницы, которая включает кнопку справки. Надеюсь, это покажет простой способ создания многократно используемого интерфейса, и что это не такая сложная задача.
Один из способов реализации многократно используемой кнопки справки для каждого Activity
это создать menu
ресурс, который можно использовать как меню опций в базовом классе:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_help" android:title="@string/action_help"
android:icon="@drawable/ic_help_white_24dp" android:orderInCategory="100"
app:showAsAction="ifRoom"/>
</menu>
Затем этот ресурс меню раздувается внутри базового класса. Базовый класс расширяется AppCompatActivity
(который расширяет FragmentActivity
) для того, чтобы использовать Support Library
:
public abstract class BaseActivity extends AppCompatActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.base, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.action_help:
dispatchHelpIntent();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
protected void dispatchHelpIntent() {
// Handle help options button
}
}
При этом вы можете либо обработать щелчок кнопки справки в базовом классе, либо переопределить дочерний класс dispatchHelpIntent()
обрабатывать это отдельно. Вы также можете переопределить onCreateOptionsMenu()
а также onOptionsItemSelected()
в дочернем классе, чтобы добавить больше элементов в меню. Просто убедитесь, что вы звоните super
в обоих методах, как я делаю здесь, чтобы сохранить кнопку справки.
Затем, чтобы создать многоразовую панель навигации (обычно называемую панелью приложений в Android), все, что вам нужно сделать, это создать layout
файл, который будет включен в layout
файл для каждого Activity
:
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/app_bar"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
Затем вы можете включить этот макет в любой другой Activity
используя <include/>
тег:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_height="match_parent"/>
<include layout="@layout/app_bar_base"/>
<!-- Activity content goes here -->
</android.support.design.widget.CoordinatorLayout>
И, наконец, добавить это как ActionBar
("Панель действий" - это старый термин для панели приложений) в любом Activity
что расширяет BaseActivity
:
public class MainActivity extends BaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setupActionBar();
}
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
actionBar.setDisplayShowTitleEnabled(true);
}
}
}
Причина, по которой это не может быть сделано в BaseActivity
потому что, если каждый Activity
использует тот же макет, каждый Activity
должен определить свой собственный макет с setContentView()
, Toolbar
будет недоступен до тех пор, пока не будет настроено представление содержимого, поэтому с помощью этого метода необходимо настроить панель действий (панель приложения) в каждом действии отдельно.