Android单Activity下视图切换的返回功能实现问题
单Activity架构下日历应用返回键视图回退解决方案
我在Android Studio中用Java开发一款日历应用,支持事件的保存、展示与编辑,包含月视图、周视图、日视图等界面。最初采用多Activity架构时,返回键可以正常实现页面回退;后来因为需求调整改为单Activity架构,通过setMonthView()、setWeek()、setDaily()等方法切换视图,但点击返回键无法回到上一个视图(比如从周视图返回月视图或日视图)。默认的onBackPressed()仅用于回退Activity,满足不了当前需求,求解决方案。
相关代码片段
导航菜单选择逻辑
@Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.menuSchedule: setAllEvents(); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.daysView: setDaily(); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.weekView: setWeek(); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.monthView: setMonthView(); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.refreshItem: finish(); startActivity(getIntent()); break; case R.id.syncItem: break; default: onNavigationItemSelected(item); } return true; }
视图切换方法示例(以月视图为例)
private void setMonthView() { monthYearText.setText(monthYearFromDate(CalendarUtils.selectedDate)); ArrayList<LocalDate> daysInMonth = daysInMonthArray(); CalendarAdapter calendarAdapter = new CalendarAdapter(daysInMonth, this, getApplicationContext()); RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), 7); calendarRecyclerView.setLayoutManager(layoutManager); calendarRecyclerView.setAdapter(calendarAdapter); ViewGroup.LayoutParams params = calendarRecyclerView.getLayoutParams(); params.height=1500; calendarRecyclerView.setLayoutParams(params); monthListView.setVisibility(View.GONE); monthYearText.setVisibility(View.VISIBLE); daysOfWeekDaily.setVisibility(View.GONE); daysOfWeek.setVisibility(View.VISIBLE); prevMonth.setVisibility(View.VISIBLE); nextMonth.setVisibility(View.VISIBLE); calendarRecyclerView.setVisibility(View.VISIBLE); nestedScrollView.setVisibility(View.VISIBLE); }
解决方案
通过栈结构记录视图切换历史,重写返回键逻辑实现视图回退,具体实现如下:
首先初始化一个栈(建议在Activity的onCreate中声明),在视图切换时将当前视图类型压入栈;重写onBackPressed()方法时,从栈中弹出当前视图,根据栈顶的历史视图类型切换回对应界面,当栈为空时再执行默认的Activity回退逻辑。
修改后的完整代码:
// 初始化栈,记录视图切换历史 private LinkedList<String> stack = new LinkedList<>(); public void onMyBackPressed() { // 弹出当前视图类型 stack.removeFirst(); // 获取上一个视图类型 String previousViewType = stack.peekFirst(); if (previousViewType == null) { // 无历史视图,执行默认Activity回退 super.onBackPressed(); return; } // 根据历史视图类型切换对应界面 if (previousViewType.equals("daily")) { setDaily(); } else if (previousViewType.equals("week")) { setWeek(); } else if (previousViewType.equals("all")) { setAllEvents(); } else if (previousViewType.equals("month")) { setMonthView(); } } @Override public void onBackPressed() { onMyBackPressed(); } @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.menuSchedule: setAllEvents(); stack.addFirst("all"); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.daysView: setDaily(); stack.addFirst("daily"); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.weekView: setWeek(); stack.addFirst("week"); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.monthView: setMonthView(); stack.addFirst("month"); drawerLayout.closeDrawer(GravityCompat.START); break; case R.id.refreshItem: finish(); startActivity(getIntent()); break; case R.id.syncItem: break; default: onNavigationItemSelected(item); } return true; }
内容的提问来源于stack exchange,提问作者Chris Damianidis
相关产品推荐
相关产品推荐

