Я искал и думал, как реализовать поведение желания, которое я хочу, при переключении назад и вперед между фрагментами при использовании ящика навигации. На самом деле в документации сказано: При использовании фрагментов в вашем приложении отдельные объекты FragmentTransaction могут представлять изменения контекста, которые должны быть добавлены в задний стек. Например, если вы реализуете поток «главный/подробный» на телефоне путем замены фрагментов, вы должны убедиться, что нажатие кнопки «Назад» на подробном экране возвращает пользователя к основному экрану
Итак, в моем приложении у меня есть MainActivity, которая управляет всем, и макет навигации внутри, который вы можете менять между предопределенными параметрами. Это вид при запуске приложения
Когда вы щелкаете элемент в навигационном ящике, он открывает новый фрагмент, который заменяет main_content следующим образом:
На этом этапе поведение является правильным, поэтому, если вы хотите изменить параметры, вам нужно снова открыть панель навигации, чтобы переключаться между параметрами меню.
Это основное действие (обратите внимание, что нет переключателя ящиков)
MainActivity.java
public class MainActivity extends AppCompatActivity {
ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout drawerLayout;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSnackBarView = findViewById(R.id.myCoordinatorLayout);
setToolbar(); // Set Toolbar como action bar
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null) {
setupDrawerContent(navigationView);
}
drawerTitle = getResources().getString(R.string.app_name);
if (savedInstanceState == null) {
selectItem(drawerTitle, mCurrentSelectedPosition);
}
}
private void setToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final ActionBar ab = getSupportActionBar();
if (ab != null) {
// Poner ícono del drawer toggle
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true);
}
}
private void setupDrawerContent(final NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Marcar item presionado
menuItem.setChecked(true);
// Crear nuevo fragmento
String title = menuItem.getTitle().toString();
int id = menuItem.getItemId();
selectItem(title, id);
return true;
}
}
);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!drawerLayout.isDrawerOpen(GravityCompat.START)) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
private void selectItem(String title, int id) {
Bundle args = new Bundle();
args.putString(PlaceholderFragment.ARG_SECTION_TITLE, title);
Fragment fragment = PlaceholderFragment.newInstance(title);
fragment.setArguments(args);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
switch (id) {
case R.id.nav_localizacion:
//Snackbar.make(mSnackBarView, R.string.menu_localization, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 0;
LocalizacionFragment fragment_localizacion = new LocalizacionFragment();
// fragmentManager = getSupportFragmentManager();
Snackbar.make(mSnackBarView, R.string.menu_localization, Snackbar.LENGTH_SHORT).show();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment_localizacion)
.commit();
break;
case R.id.nav_productos:
Snackbar.make(mSnackBarView, R.string.menu_productos, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 1;
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
break;
case R.id.nav_consejos:
Snackbar.make(mSnackBarView, R.string.menu_consejos, Snackbar.LENGTH_SHORT).show();
mCurrentSelectedPosition = 3;
ConsejosFragment fragment_consejo = new ConsejosFragment();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, fragment_consejo)
.commit();
break;
default:
break;
}
drawerLayout.closeDrawers(); // Cerrar drawer
setTitle(title); // título actual
}
}
Я не использую значок гамбургера, потому что он скрывается под макетом навигации, но вот в чем дело. Когда вы нажимаете «Recetas» в представлении корзины, он открывает новый фрагмент (заменяет), но теперь я хочу отобразить значок курсора вверх и дать правильную обратную навигацию моему приложению.
Вот код класса фрагмента "Consejos"
Consejos.java
public class ConsejosFragment extends Fragment {
RecyclerView mRecycler;
ConsejosAdapter mAdapter;
FragmentActivity mActivity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mActivity = (FragmentActivity) activity;
setRetainInstance(true);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
List items = new ArrayList();
items.add(new ConsejosInfo("Recetas", R.drawable.icon_recetas));
/* Inflamos el layout */
View v = inflater.inflate(R.layout.consejos_layout_recycler, container, false);
/* Obtenemos el Recycle */
mRecycler = (RecyclerView) v.findViewById(R.id.recycler_consejos);
/* Creamos el adaptador */
mAdapter = new ConsejosAdapter(mActivity, items);
/* Set click en adapter */
return v;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecycler.setHasFixedSize(true);
mRecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecycler.setAdapter(mAdapter);
}
}
И это адаптер, который использует Recyclerview и обрабатывает щелчок по элементу внутри:
Адаптер.java
public class ConsejosAdapter extends RecyclerView.Adapter<ConsejosAdapter.ConsejosViewHolder> {
private List<ConsejosInfo> _items = new ArrayList<ConsejosInfo>();
private final FragmentActivity mActivity;
private Context context;
public ConsejosAdapter(FragmentActivity mActivity, List<ConsejosInfo> items) {
this._items = items;
this.mActivity = mActivity;
}
@Override
public int getItemCount() {
return _items.size();
}
@Override
public ConsejosViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cardview_consejos, viewGroup, false);
return new ConsejosViewHolder(v);
}
@Override
public void onBindViewHolder(ConsejosViewHolder viewHolder, int position) {
viewHolder.imagen.setImageResource(_items.get(position).get_imagen());
viewHolder.nombre.setText(_items.get(position).get_nombre());
}
public class ConsejosViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imagen;
public TextView nombre;
public ConsejosViewHolder(final View itemView) {
super(itemView);
imagen = (ImageView) itemView.findViewById(R.id.consejos_imagen);
nombre = (TextView) itemView.findViewById(R.id.consejos_nombre);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
RecetasFragment recetasFragment = new RecetasFragment();
FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.main_content, recetasFragment)
.addToBackStack(null)
.commit();
}
}
}
В адаптере Consejos я добавил фрагмент обратного стека перед вызовом нового фрагмента (внутри фрагмента), и это меняет поведение кнопки «Назад», поэтому до этого, если вы нажмете кнопку «Назад», приложение закроется, но теперь оно приведет вас к Consejos фрагмент, но теперь я хочу добавить каретку вверх и выполнить точно такую же операцию, как при нажатии кнопки «Назад», но я не знаю, как этого добиться.
Пожалуйста, не стесняйтесь запрашивать больше кода
Большое спасибо