多重活动(而不是碎片)与NavigationDrawer。如何显示当前选择的活动? [英] Multiple activities (not fragments) with a NavigationDrawer. How to show currently selected Activity?

查看:237
本文介绍了多重活动(而不是碎片)与NavigationDrawer。如何显示当前选择的活动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有不少活动的申请,决定,我们将使用导航抽屉或一个汉堡包菜单之前。我不想重做使用碎片整个应用程序,所以我决定去与这个答案使用的方法:
<一href=\"http://stackoverflow.com/questions/19451715/same-navigation-drawer-on-different-activities\">Same抽屉式导航栏在不同的活动

I had an application with quite a few activities before it was decided that we will be using a Navigation Drawer or a hamburger menu. I did not want to redo the whole app using fragments so I decided to go with the approach used in this answer: Same Navigation Drawer on different Activities

编辑:现在,这个<一个href=\"http://stackoverflow.com/a/23477100/1371585\">http://stackoverflow.com/a/23477100/1371585

和我创建了一个名为基地的活动 NavDrawerBaseActivity 。这里是code:

And I created a base activity called NavDrawerBaseActivity. Here is the code:

    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_width="match_parent"
    android:layout_height="match_parent" 
    >

    <FrameLayout
        android:id="@+id/activity_frame"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <!-- The navigation drawer -->

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        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(位置,真); 启动之前意向或启动它不工作后

My problem: How do I correctly highlight the current activity in the NavDrawer View? The mDrawerList.setItemChecked(position, true); before launching Intent or after launching it is not working.

怪异的部分是:如果我在活动1是当前,打开NavDrawer并选择活性2。我土地活性2,打开NavDrawer,看到活性2没有被选中。我单击后退按钮,在活动1土地,打开NavDrawer,看到活性2被选中。

The weird part is: If I am currently in Activity1, Open the NavDrawer and select Activity2. I land in Activity2, open the NavDrawer and see that "Activity2" is not selected. I click the Back button, land in Activity1, open the NavDrawer and see that "Activity2" is selected.

这意味着 setItemChecked 的作品,但不是在被推出了新的活动。

Which means setItemChecked works, but not in the new activity that gets launched.

目前我传递的位置作为一个额外的意向,具体设置检查位置,就像在 LibraryActivity 的注释部分。
这工作,但似乎周围的工作。请告诉我,如果有这样做,在 NavDrawerBaseActivity 类,而不是在扩展它的每个活动有一个正确的/更好的办法。

Currently I am passing the position as an Intent extra and specifically setting the checked position, like the commented section in LibraryActivity. This works but seems like a work around. Please tell me if there is a correct/better way of doing that in NavDrawerBaseActivity class instead of in each Activity that extends it.

推荐答案

不要把导航抽屉里的每一次活动,这违背扩展NavDrawerBaseActivity类的目的。因为你的所有其他活动扩展这个基类,他们应该自动继承其所有功能。因此,只有放在NavDrawerBaseActivity抽屉。然后,在你的XML的抽屉,您可以指定每一样动作的按钮:

Do not put a nav drawer in every activity, this defeats the purpose of extending the NavDrawerBaseActivity class. Because all your other activities extend this base class they should automatically inherit all its functionality. Hence, only put the drawer in the NavDrawerBaseActivity. Then, in your xml for the drawer you can specify each buttons action like:

<Button
        style="@style/drawerBtn"
        android:id="@+id/activity1Btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick">

或者干脆设置一个onClick监听你的抽屉里,是这样的:

Or simply set an onClick listener on your drawer, something like:

myDrawer.setOnClickListener().........etc

然后在你的onClick处理程序(这是NavDrawerBaseActivity类中),你可以简单地检查哪个按钮是pressed并打开相关的活动,是这样的:

Then in your onClick handler (which is inside the NavDrawerBaseActivity class) you can simply check which button was pressed and open the associated activity, something like:

//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;
    }
}

请记住,活动1,活性2,Activity3将不得不延长NavDrawerBaseActivity然后要么不得不延长活动或扩展另一个类又扩展活动......等等等等。然后,您可以也将此开关设置之类的 mDrawerList.setItemChecked(位置,真)。因此,在短期,使所有抽屉里的事情发生在这个类仅简单地扩展它,记住这个类实现这一类中包含的所有功能,在所有的子类/活动常见的,他们都继承了这种行为

Remember that Activity1, Activity2, Activity3 will have to extend NavDrawerBaseActivity which then either have to extend Activity or extend another class which in turn extends Activity...... and so on and so forth. You can then also set things like mDrawerList.setItemChecked(position, true) in this switch. So in short, make all drawer things happen in this class only and simply "implement" this class by extending it, remember this class contains all functionality that is common across all the "child" classes/activities, they all inherit this behaviour

编辑:

如果你想突出你的抽屉中的项目,并且必须而使用的setSelected(真)在您的项目。您可以通过创建您的可绘制文件夹中选择的风格,如果你想定义自定义选择状态来。然后,设置这个样式列表项的例子的背景:

If you want to highlight the items in your drawer and you must rather use setSelected(true) on your item. You can define custom selection states if you want to by creating a selection style in your drawables folder. You then set this style as the background of your list items example:

<!-- 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_width="match_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/myStyles">

然后在你的交换机/ if-else语句设定你所选择的项目为 myNewSelectedView.setSelected(真)。您可能必须手动取消旧例如 myOldSelectedItem.setSelected(假)

Then in your switch/if-else statement you set the selected item as myNewSelectedView.setSelected(true). You might have to manually deselect the old one like myOldSelectedItem.setSelected(false)

然后点击/选择的听众,你有你切换/ if-else语句:

Then click/selected listener where you have you switch/if-else statement:

 @Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
     view.setSelected(true)  

     //....the rest of your code here
}

最后,我建议你先试试这个,因为这将是最容易的途径,如果你用一个正常的ListView遵循:

Lastly I recommend you try this first as this will be the easiest route to follow if you use a normal listView:

<ListView android:id="@+id/my_list"
    android:choiceMode="singleChoice" 
    android:listSelector="@android:color/blue" />

EDIT2:

现在保留所选项目的状态......如此看来,在抽屉里每个动作重新实例的基类,它心不是理想的。我们需要以某种方式保留实例状态,所以它的行为几乎成了单身。我试着重写在的onSaveInstanceState 并使用 singleInstance 发射状态,但他们没有工作。所以,对于我临时想出来的内存保存当前选择作为一个静态变量的解决方法:

Now to retain the selected items state...So it seems that each action on the drawer reinstantiates the base class which isnt ideal. We need to somehow retain the instance state so it acts almost as a singleton. I've tried overriding the the onSaveInstanceState and using the singleInstance launcher state but they did not work. So, for the interim I've come up with the solution of saving the current selection in memory as a static variable:

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);
}

这篇关于多重活动(而不是碎片)与NavigationDrawer。如何显示当前选择的活动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆