关键词:
【中文标题】带有 NavigationDrawer 的多个活动(不是片段)。如何显示当前选择的活动?【英文标题】:Multiple activities (not fragments) with a NavigationDrawer. How to show currently selected Activity? 【发布时间】:2015-02-03 10:35:54 【问题描述】:在决定我们将使用导航抽屉或汉堡菜单之前,我有一个包含很多活动的应用程序。我不想使用片段重做整个应用程序,所以我决定采用此答案中使用的方法: Same Navigation Drawer in different Activities
编辑:现在,这个https://***.com/a/23477100/1371585
我创建了一个名为NavDrawerBaseActivity
的基础活动。代码如下:
public class NavDrawerBaseActivity extends MyBaseActivity
public DrawerLayout mNavDrawerLayout;
public ListView mDrawerList;
public String[] mMenuItems;
@Override
protected void onCreate(Bundle savedInstanceState)
setContentView(R.layout.navdrawer_activity);
mNavDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mMenuItems = getResources().getStringArray(R.array.optionsmenu_array);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mMenuItems);
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener(this));
super.onCreate(savedInstanceState);
private class DrawerItemClickListener implements
ListView.OnItemClickListener
private DrawerItemClickListener(Context context)
mContext = context;
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id)
String textClicked = ((TextView) view).getText().toString();
view.setSelected(true);
if (textClicked.equalsIgnoreCase(mContext
.getString(R.string.optionsmenu_library)))
Intent libraryIntent = new Intent(mContext,
LibraryActivity.class);
libraryIntent.putExtra("navdrawerposition", position);
startActivity(libraryIntent);
mNavDrawerLayout.closeDrawers();
mDrawerList.setItemChecked(position, true); //Not working
else if (textClicked.equalsIgnoreCase(mContext
.getString(R.string.optionsmenu_settings)))
// TODO: open activity and close the drawer
else if (textClicked.equalsIgnoreCase(mContext
.getString(R.string.optionsmenu_logout)))
// TODO: open activity and close the drawer
private Context mContext;
这里是布局文件navdrawer_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_
android:layout_
>
<FrameLayout
android:id="@+id/activity_frame"
android:layout_
android:layout_ />
<!-- The navigation drawer -->
<ListView
android:id="@+id/left_drawer"
android:layout_
android:layout_
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
/>
</android.support.v4.widget.DrawerLayout>
每个活动都扩展了NavDrawerBaseActivity
,并且不使用setContentView
,如下所示:
public class LibraryActivity extends NavDrawerBaseActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// Not setting content view here, since its already set in
// NavDrawerBaseActivity
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.activity_frame);
// Inflating the Camera activity layout
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = layoutInflater
.inflate(R.layout.library_page, null, false);
// Adding the custom layout of this activity to frame layout set in
// NavDrawerBaseActivity.
frameLayout.addView(activityView);
// Only this part of the code is doing what I want.
// int drawerSelectedPosition = getIntent().getIntExtra(mNavDrawerPosExtraName, -1);
// if(drawerSelectedPosition > -1)
// mDrawerList.setItemChecked(drawerSelectedPosition, true);
//
我的问题:如何在 NavDrawer 视图中正确突出显示当前活动?
mDrawerList.setItemChecked(position, true);
在 Intent 启动前或启动后不起作用。
奇怪的是:如果我当前在 Activity1,打开 NavDrawer 并选择 Activity2。我登陆Activity2,打开NavDrawer,看到“Activity2”没有被选中。我单击返回按钮,进入 Activity1,打开 NavDrawer 并看到“Activity2”被选中。
这意味着setItemChecked
有效,但在启动的新活动中无效。
目前我将该位置作为 Intent extra 传递,并专门设置选中的位置,如 LibraryActivity
中的注释部分。
这可行,但似乎可以解决。请告诉我在 NavDrawerBaseActivity
类而不是在扩展它的每个 Activity 中是否有正确/更好的方法。
【问题讨论】:
【参考方案1】:不要在每个活动中放置导航抽屉,这违背了扩展 NavDrawerBaseActivity 类的目的。因为您的所有其他活动都扩展了这个基类,所以它们应该自动继承它的所有功能。因此,只将抽屉放在 NavDrawerBaseActivity 中。然后,在抽屉的 xml 中,您可以指定每个按钮的操作,例如:
<Button
style="@style/drawerBtn"
android:id="@+id/activity1Btn"
android:layout_
android:layout_
android:onClick="onClick">
或者简单地在你的抽屉上设置一个 onClick 监听器,比如:
myDrawer.setOnClickListener().........etc
然后在您的 onClick 处理程序(位于 NavDrawerBaseActivity 类中)中,您可以简单地检查按下了哪个按钮并打开相关的活动,例如:
//remember, if you used the onClickListener you have to use @Override at the top of this function
public void onClick(View item)
//lets see which button on the drawer was pressed....item is the item that triggered the click
switch (item.getId())
case R.id.activity1Btn:
Intent intent1 = new Intent(this, Activity1.class);
startActivity(intent1);
break;
case R.id.activity2Btn:
Intent intent2 = new Intent(this, Activity2.class);
startActivity(intent2);
break;
case R.id.activity3Btn:
Intent intent3 = new Intent(this, Activity3.class);
startActivity(intent3);
break;
请记住,Activity1、Activity2、Activity3 必须扩展 NavDrawerBaseActivity,然后它们要么必须扩展 Activity,要么扩展另一个类,而后者又扩展 Activity……等等。然后,您还可以在此开关中设置 mDrawerList.setItemChecked(position, true) 之类的内容。所以简而言之,让所有抽屉的事情只发生在这个类中,并通过扩展它来简单地“实现”这个类,记住这个类包含所有“子”类/活动共有的所有功能,它们都继承了这种行为
编辑:
如果您想突出显示抽屉中的项目,您必须在项目上使用 setSelected(true)。如果您愿意,可以通过在您的 drawables 文件夹中创建选择样式来定义自定义选择状态。然后将此样式设置为列表项示例的背景:
<!-- drawable/myStyles.xml-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true" android:drawable="@color/blue"/> <!--item selected state-->
<item android:state_enabled="true" android:state_focused="true" android:drawable="@color/blue"/> <!--item selected state-->
<item android:state_enabled="true" android:state_selected="true" android:drawable="@color/blue"/> <!--item selected state-->
<item android:state_focused="false" android:state_pressed="false" android:drawable="@color/gray"/> <!--item NOT selected state-->
</selector>
还有你的抽屉物品:
<LinearLayout
android:id="@+id/my_drawer_item"
android:orientation="vertical"
android:layout_
android:layout_
android:background="@drawable/myStyles">
然后在您的 switch/if-else 语句中,您将所选项目设置为 myNewSelectedView.setSelected(true)。您可能必须手动取消选择旧的,例如 myOldSelectedItem.setSelected(false)
然后单击/选择您有 switch/if-else 语句的侦听器:
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id)
view.setSelected(true)
//....the rest of your code here
最后,我建议您先尝试一下,因为如果您使用普通的 listView,这将是最简单的方法:
<ListView android:id="@+id/my_list"
android:choiceMode="singleChoice"
android:listSelector="@android:color/blue" />
EDIT2:
现在要保留所选项目的状态...因此,抽屉上的每个操作似乎都会重新实例化不理想的基类。我们需要以某种方式保留实例状态,使其几乎充当单例。我尝试覆盖 onSaveInstanceState 并使用 singleInstance 启动器状态,但它们不起作用。因此,暂时我想出了将内存中的当前选择保存为静态变量的解决方案:
private static int mCurrentSelectionIndex = 0; //this is defined at the top of your class with your default selected screen ie the first item in the list.
//then in setContentView after assigning the drawer layout you set the currentSelection
@Override
public void setContentView(final int layoutResID)
//...... first assign the layouts ie mDrawerList = findViewByLayout(R.id.myDrawerList) etc
mDrawerList.setSelection(mCurrentSelectionIndex);
// OR:
mDrawerList.setItemChecked(mCurrentSelectionIndex, true);
//then in onClick()
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
mCurrentSelection = position;
item.setSelected(true);
【讨论】:
哪个 XML 有抽屉?用户永远不会看到 NavDrawerBaseActivity,因此没有布局。所以(比如说)扩展 NavDrawerBaseActivity 的 Activity1 应该有<android.support.v4.widget.DrawerLayout...> <ListView android:id="@+id/left_drawer".../> </android.support.v4.widget.DrawerLayout>
对吗?
啊,你错了……用户确实看到了 NavDrawerBaseActivity……因为它是你的导航抽屉! :) 所以基本上你的 Activity1、Actvity2 等必须只扩展 NavDrawerBaseActivity 等等。它应该与 xml 或 android 代码中的任何形式的 Drawer 代码完全没有关系,所有这些都应该在 NavDrawerBaseActivity 内部,所以如果 NavDrawerBaseActivity 没有布局,你必须在其中创建一个带有抽屉的布局,就像您目前在 Activity1 等中执行...请记住,与抽屉相关的所有代码都必须仅在 NavDrawerBaseActivity
如果您不明白,请告诉我,以便我尝试更清楚地解释或编辑我的答案。请尝试理解继承会发生什么以及扩展类时会发生什么。任何扩展基类的类都会获得基类的行为/外观等以及它自己的......
好的,所以你说我需要一个用于 NavDrawerBaseActivity 的 layout.xml 以及另一个用于 Activity1 的 layout.xml。所以我应该在两者的onCreate
方法中调用setContentView
吗?最新的setContentView
电话不会决定最终的布局吗?继承,AFAIK,不结合 NavDrawerBaseActivity 和 Activity1 的 layout xmls。
请再看一下我发布的代码。 NavDrawerBaseActivity
已经实现了您在回答中建议的内容。方法NavDrawerBaseActivity.DrawerItemClickListener.onItemClick
有一个类似switch 的if-else 构造,我试图在启动新活动之前执行mDrawerList.setItemChecked(position, true);
。它不起作用(因此被注释掉了)。新活动中的 NavDrawer 没有选择任何内容。带有片段的 NavigationDrawer 内的 Android TabLayout
】带有片段的NavigationDrawer内的AndroidTabLayout【英文标题】:AndroidTabLayoutinsideNavigationDrawerwithFragments【发布时间】:2021-02-2811:18:28【问题描述】:我正在使用带有片段的NavigationDrawer。现在我的导航抽屉中有8个菜单,但我只想在两... 查看详情
多个活动上的 Android 导航抽屉
】多个活动上的Android导航抽屉【英文标题】:AndroidNavigationDraweronmultipleActivities【发布时间】:2013-09-1222:13:54【问题描述】:有没有办法只配置一次NavigationDrawer,并在多个Activity上显示?【问题讨论】:Here是一个不错的教程。见... 查看详情
带有建议的多个可搜索活动
】带有建议的多个可搜索活动【英文标题】:Multiplesearchableactivitieswithsuggestions【发布时间】:2013-10-3008:15:10【问题描述】:我有2个活动的应用程序-2个不同的列表视图具有不同的数据,我希望在两者中都通过操作栏进行搜索。... 查看详情
带有多个片段的活动中的 FloatingActionButton?
】带有多个片段的活动中的FloatingActionButton?【英文标题】:FloatingActionButtoninActivitywithmultipleFragments?【发布时间】:2017-06-0814:10:16【问题描述】:我有一个似乎无法解决的问题。我有一个包含列表片段(横向和纵向)和addItem片... 查看详情
如何在 Bloc Login Flutter 中使用带有身份验证的 NavigationDrawer 路由
】如何在BlocLoginFlutter中使用带有身份验证的NavigationDrawer路由【英文标题】:HowtouseroutesinBlocLoginFlutterforNavigationDrawerwithauthentication【发布时间】:2020-05-2210:24:13【问题描述】:我实现了FlutterBlocLogin示例,与指南页面here完全一样... 查看详情
使用带有活动记录的连接表时如何连接模型的多个实例?
】使用带有活动记录的连接表时如何连接模型的多个实例?【英文标题】:Howtojoinwithmultipleinstancesofamodelwhenusingajointablewithactiverecord?【发布时间】:2020-09-0119:16:24【问题描述】:这适用于使用PostgreSQL的Rails5/ActiveRecord5。假设我有... 查看详情
KivyMD NavigationDrawer 在多个屏幕上滑动
】KivyMDNavigationDrawer在多个屏幕上滑动【英文标题】:KivyMDNavigationDrawerslidesovermultiplescreens【发布时间】:2021-11-1712:51:11【问题描述】:使用KivyMDMDNavigationLayout,我正在尝试为应用程序制作导航抽屉!我是这样做的,但是我的导航... 查看详情
带有嵌套片段的导航抽屉 (ViewPager)
】带有嵌套片段的导航抽屉(ViewPager)【英文标题】:NavigationDrawerwithnestedfragments(ViewPager)【发布时间】:2013-09-1415:42:58【问题描述】:我正在编写一个具有NavigationDrawer并使用嵌套片段的应用程序。导航抽屉几乎是根据Android文档创... 查看详情
带有多个 if 语句的意图
】带有多个if语句的意图【英文标题】:Intentwithmultipleifstatements【发布时间】:2021-12-1609:13:09【问题描述】:我正在学习Intent的概念,当我尝试从不是“Arabica”意图的任何其他意图中去时,我正在处理的应用程序崩溃,意图对象... 查看详情
从片段中隐藏 NavigationDrawer 和 ActionBar
】从片段中隐藏NavigationDrawer和ActionBar【英文标题】:HideNavigationDrawerandActionBarFromFragment【发布时间】:2019-10-1014:38:56【问题描述】:我试图。我已经创建了以下接口并在活动中实现了相同的接口publicinterfaceCommonMethodsListenervoidhideA... 查看详情
NavigationDrawer 上的自定义字体
】NavigationDrawer上的自定义字体【英文标题】:CustomfontonNavigationDrawer【发布时间】:2015-10-2615:46:46【问题描述】:我正在尝试更改我的导航抽屉上的字体,我正在使用带有适配器的自定义xml文件,因此我可以成功更改ListView中每... 查看详情
android状态栏隐藏navigationdrawer
】android状态栏隐藏navigationdrawer【英文标题】:androidstatusbarhidingnavigationdrawer【发布时间】:2016-05-1004:22:58【问题描述】:我有一个带有此代码的导航抽屉:<?xmlversion="1.0"encoding="utf-8"?><android.support.v4.widget.DrawerLayoutxmlns:andro... 查看详情
每个 Activity 中的 NavigationDrawer
】每个Activity中的NavigationDrawer【英文标题】:NavigationDrawerineveryActivity【发布时间】:2021-07-2610:32:44【问题描述】:我为我的HomeScreen创建了NavigationDrawer,现在想将它添加到每个Activity中。如果不将代码复制/粘贴到每个活动中,我... 查看详情
片段和后台有时会搞砸
...:2015-08-1713:17:37【问题描述】:我有一个带有片段容器和NavigationDrawer的活动。如果我在抽屉中选择一个项目,我会调用updatePage(index)。如果我创建活动,我也会调用updatePage(0),并调用savedInstanceState==null来初始化我的活动 查看详情
具有多个活动的导航抽屉。 - 空指针异常
...移动应用程序。我的应用程序的启动器活动是SplashScreen。带有Intent的SplashScreen导航到我的HomeActivity。我尝试了this 查看详情
带有多个按钮和字体的多行 UILabel
】带有多个按钮和字体的多行UILabel【英文标题】:MultiplelinesUILabelwithmultiplebuttonsandfonts【发布时间】:2016-04-3009:42:00【问题描述】:我正在为一些活动提要对象创建一个UITableViewCell,让您知道它们将像Facebook帖子一样,您在一个... 查看详情
Android:导航抽屉标题文本视图未以编程方式设置
...屉标题文本视图未以编程方式设置【英文标题】:Android:NavigationDrawerHeaderTextViewisnotsettingprogrammatically【发布时间】:2016-04-2019:30:48【问题描述】:在我的活动中,我有片段,所以我使用NavigationDrawer,在NavigationDrawer中我有一个带... 查看详情
带有多个 AVPlayer 实例的 AirPlay
】带有多个AVPlayer实例的AirPlay【英文标题】:AirPlaywithmultipleinstancesofAVPlayer【发布时间】:2013-11-0519:50:26【问题描述】:在我的应用程序中,我有多个选项卡,每个选项卡上都有一个AVPlayer实例。但是,当我激活AirPlay时,“第一... 查看详情