Можно ли использовать навигационный ящик в android, но вместо обновления фрагментов я хотел бы переключиться между действиями как моими средствами навигации в приложении.
Ящик навигации для переключения действий вместо фрагментов
Ответ 1
Да, возможно - это то, что я сделал для своего приложения. У меня уже было настроено множество действий, и вместо того, чтобы преобразовывать их все в фрагменты, я хотел бы адаптировать навигационный ящик для работы во всех них. К сожалению, это не быстрое решение, поэтому, если у вас есть возможность использовать фрагменты, я бы пошел с этим. Но независимо от того, как я это сделал:
Скажем, у меня есть 2 действия, оба из которых я хочу иметь ящик навигации. В layout.xml для каждого я указал DrawerLayout
с соответствующим ListView
, чтобы сохранить параметры навигации. По сути, ящик навигации создается каждый раз, когда я переключаюсь между действиями, придавая внешнему виду, что он сохраняется. Чтобы сделать жизнь намного проще, я применил общие методы, необходимые для настройки ящика навигации и поместил их в свой класс: NavigationDrawerSetup.java
. Таким образом, мои действия могут использовать один и тот же пользовательский адаптер и т.д.
В этом классе NavigationDrawerSetup.java
у меня есть следующее:
-
configureDrawer()
- это устанавливаетActionBar
,ActionBarDrawerToggle
и требуемые слушатели - Мой пользовательский адаптер массива (для заполнения параметров навигации в списке)
- Метод
selectOptions()
, который обрабатывает клики элемента элемента ящика
Когда вы настраиваете ящик навигации в рамках одного из своих действий, вы просто создаете новый объект NavigationDrawerSetup
и передаете необходимые параметры макета (например, DrawerLayout
, ListView
и т.д.). Затем вы вызываете configureDrawer()
:
navigationDrawer = new NavigationDrawerSetup(mDrawerView, mDrawerLayout,
mDrawerList, actionBar, mNavOptions, currentActivity);
navigationDrawer.configureDrawer();
currentActivity
передается, поскольку навигационный ящик привязан к активности, в которой вы находитесь. Вам придется использовать его при настройке ActionBarDrawerToggle
:
mDrawerToggle = new ActionBarDrawerToggle(currentActivity, // host Activity
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
)
Вам также нужно будет использовать currentActivity
при настройке пользовательского Adapter
:
Что касается того, как переключаться между действиями через ящик навигации, вы можете просто настроить новые намерения в вашем методе selectItem():
private void selectItem(int position) {
// Handle Navigation Options
Intent intent;
switch (position) {
case 0:
intent = new Intent(currentActivity, NewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
currentActivity.startActivity(intent);
break;
case 1:
// etc.
}
Просто убедитесь, что ваш новый Activity
также имеет настройку навигационного ящика и должен отображаться.
Есть тонна вещей, которые вы можете сделать, чтобы настроить этот метод на собственные нужды, но это общая структура того, как я это сделал. Надеюсь, это поможет!
Ответ 2
Вам понадобится BaseDrawerActivity
, который реализует ящик навигации, а затем растягивает BaseDrawerActivity
в каждом действии, в котором вам нужен навигационный ящик.
Сначала создайте BaseDrawerActivity.java
:
public class BaseDrawerActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
DrawerLayout drawerLayout;
Toolbar toolbar;
FrameLayout frameLayout;
NavigationView navigationView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_base_drawer);;
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
frameLayout = (FrameLayout) findViewById(R.id.content_frame);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.setDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
//to prevent current item select over and over
if (item.isChecked()){
drawerLayout.closeDrawer(GravityCompat.START);
return false;
}
if (id == R.id.nav_camera) {
// Handle the camera action
startActivity(new Intent(getApplicationContext(), CameraActivity.class));
} else if (id == R.id.nav_gallery) {
startActivity(new Intent(getApplicationContext(), GalleryActivity.class));
} else if (id == R.id.nav_slideshow) {
startActivity(new Intent(getApplicationContext(), SlideshowActivity.class));
} else if (id == R.id.nav_manage) {
startActivity(new Intent(getApplicationContext(), ManageActivity.class));
} else if (id == R.id.nav_share) {
startActivity(new Intent(getApplicationContext(), ShareActivity.class));
} else if (id == R.id.nav_send) {
startActivity(new Intent(getApplicationContext(), SendActivity.class));
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
}
затем создайте activity_base_drawer.xml
в папке res/layout
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<include layout="@layout/app_bar_home"/>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header_home"
app:menu="@menu/activity_home_drawer" />
</android.support.v4.widget.DrawerLayout>
где @layout/app_bar_home
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
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>
<FrameLayout android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
Затем вы вводите свои действия, в которых есть навигационный ящик, например CameraActivity.java
:
public class CameraActivity extends BaseDrawerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLayoutInflater().inflate(R.layout.activity_camera, frameLayout);
/**
* Setting title
*/
setTitle("Camera");
}
@Override
protected void onResume() {
super.onResume();
// to check current activity in the navigation drawer
navigationView.getMenu().getItem(0).setChecked(true);
}
}
Где R.layout.activity_camera
- ваш макет для CameraActivity.java
.
Затем создайте другое действие, например GalleryActivity.java
и т.д., в котором будет навигационный ящик:
public class GalleryActivity extends BaseDrawerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLayoutInflater().inflate(R.layout.activity_gallery, frameLayout);
// Setting title
setTitle("Gallery");
}
@Override
protected void onResume() {
super.onResume();
navigationView.getMenu().getItem(1).setChecked(true);
}
}
Ответ 3
В качестве небольшого улучшения для решения, поставленного @David-Crozier, чтобы избежать совпадения обеих анимаций (закрытие NavigationDrawer и запуск нового действия), вы можете включить небольшую задержку в свой метод, как это было сделано в iosched app v2014:
private void onNavDrawerItemClicked(final int itemId) {
if (itemId == getSelfNavDrawerItem()) {
mDrawerLayout.closeDrawer(GravityCompat.START);
return;
}
if (isSpecialItem(itemId)) {
goToNavDrawerItem(itemId);
} else {
// launch the target Activity after a short delay, to allow the close animation to play
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
goToNavDrawerItem(itemId);
}
}, NAVDRAWER_LAUNCH_DELAY);
// change the active item on the list so the user can see the item changed
setSelectedNavDrawerItem(itemId);
// fade out the main content
View mainContent = findViewById(R.id.main_content);
if (mainContent != null) {
mainContent.animate().alpha(0).setDuration(MAIN_CONTENT_FADEOUT_DURATION);
}
}
mDrawerLayout.closeDrawer(GravityCompat.START);
}
Здесь ссылка для ссылки: https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java