当前位置: 首页 > 知识库问答 >
问题:

滑出导航项目并保持突出显示

东门玺
2023-03-14

在我的Android应用程序中,我有一个滑出式导航抽屉。当在导航抽屉中选择一个项目时,它将加载新片段并高亮显示您在导航抽屉中单击的项目。

我的问题是,在加载的新片段中,您可以单击该片段中的一个新项目,该项目将加载一个新片段,并且仍然保留导航抽屉。

在这种情况下,您不再位于导航抽屉中列出的片段上,但最后一个项目仍然高亮显示,然后无法再次单击返回。

当导航抽屉中的项目不是我的主要片段时,如何取消高亮显示,然后在其中一个主要片段上重新高亮显示?

这是我的抽屉菜单代码

public class MainDrawer2 extends FragmentActivity
{
    private static final String EXTRA_NAV_ITEM    = "extraNavItem";
    private static final String STATE_CURRENT_NAV = "stateCurrentNav";

    private ActionBarDrawerToggle mDrawerToggle;
    private DrawerLayout mDrawerLayout;

    private NavDrawerListAdapter mDrawerAdapter;
    private ListView mDrawerList;

    private CharSequence mTitle;
    private CharSequence mDrawerTitle;

    private MainNavItem mCurrentNavItem;




    public static Intent createLaunchFragmentIntent(Context context, MainNavItem navItem)
    {
        return new Intent(context, MainDrawer2.class)
                .putExtra(EXTRA_NAV_ITEM, navItem.ordinal());
    }



    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);

        Crashlytics.start(this);



        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        mDrawerList   = (ListView)findViewById(R.id.drawer);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        enableHomeButtonIfRequired();

        mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext());
        mDrawerList.setAdapter(mDrawerAdapter);
        mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                displayNavFragment((MainNavItem)parent.getItemAtPosition(position));
            }
        });

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.app_name, R.string.app_name)
        {
            public void onDrawerClosed(View view)
            {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView)
            {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu();
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if(getIntent().hasExtra(EXTRA_NAV_ITEM)){
            MainNavItem navItem = MainNavItem.values()
                    [getIntent().getIntExtra(EXTRA_NAV_ITEM,
                    MainNavItem.STATISTICS.ordinal())];
            displayNavFragment(navItem);
        }
        else if(savedInstanceState != null){
            mCurrentNavItem = MainNavItem.values()
                    [savedInstanceState.getInt(STATE_CURRENT_NAV)];
            setCurrentNavItem(mCurrentNavItem);
        }
        else{
            displayNavFragment(MainNavItem.STATISTICS);
        }
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void enableHomeButtonIfRequired()
    {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
            getActionBar().setHomeButtonEnabled(true);
        }
    }
    public void setActionBarTitle(String title) {
        getActionBar().setTitle(title);
    }


    @Override
    public void setTitle(CharSequence title)
    {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_CURRENT_NAV, mCurrentNavItem.ordinal());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    /*
    @Override
    public boolean onPrepareOptionsMenu(Menu menu)
    {
        // if nav drawer is opened, hide the action items
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
    */



    private void displayNavFragment(MainNavItem navItem)
    {
        if(navItem == mCurrentNavItem){
            return;
        }
        Fragment fragment = Fragment.instantiate(this,
                navItem.getFragClass().getName());
        if(fragment != null){

            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.main, fragment)
                    .commit();
            setCurrentNavItem(navItem);
        }
    }

    private void setCurrentNavItem(MainNavItem navItem)
    {
        int position = navItem.ordinal();
        // If navItem is in DrawerAdapter
        if(position >= 0 && position < mDrawerAdapter.getCount()){
            mDrawerList.setItemChecked(position, true);
        }
        else{
            // navItem not in DrawerAdapter, de-select current item
            if(mCurrentNavItem != null){
                mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false);
            }
        }
        mDrawerLayout.closeDrawer(mDrawerList);
        setTitle(navItem.getTitleResId());
        mCurrentNavItem = navItem;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                if(mDrawerLayout.isDrawerOpen(mDrawerList)) {
                    mDrawerLayout.closeDrawer(mDrawerList);
                }
                else {
                    mDrawerLayout.openDrawer(mDrawerList);
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }




    public void goToSearch(MenuItem item){

        //go to search page
        Fragment Fragment_one;
        FragmentManager man= getSupportFragmentManager();
        FragmentTransaction tran = man.beginTransaction();
        Fragment_one = new Search();

        tran.replace(R.id.main, Fragment_one);//tran.
        tran.addToBackStack(null);
        tran.commit();

    }

    public void scanBarcode(MenuItem item){

        //open scanner
        IntentIntegrator scanIntegrator = new IntentIntegrator(this);
        scanIntegrator.initiateScan();



    }

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {

        //retrieve scan result
        IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
        if (scanningResult != null) {
            //we have a result

            String scanContent = scanningResult.getContents();

            //todo: set scan content into setting, load new fragment which calls async task below. New
            //todo: fragment will have same ui as search. :-)
            Fragment Fragment_one;
            FragmentManager man= this.getSupportFragmentManager();
            FragmentTransaction tran = man.beginTransaction();
            Fragment_one = new BarcodeFrag(scanContent);
            tran.replace(R.id.main, Fragment_one);//tran.
            tran.addToBackStack(null);
            //tran.commit();
            tran.commitAllowingStateLoss();


        }

        else{
            Toast toast = Toast.makeText(getApplicationContext(),
                    "No scan data received!", Toast.LENGTH_SHORT);
            toast.show();
        }

    }


}

然后我有一个名为main nav item的枚举:

public enum MainNavItem
{
    // Displayed in NavDrawerListAdapter
    STATISTICS("Your Statistics",   R.layout.statistics_pagelayout,     StatisticsTab.class),
    DISCOVER  ("Discover",          R.layout.activity_discover,         DiscoverTab.class),
    PORTFOLIO ("Portfolio",         R.layout.activity_portfolio,        Portfolio.class),
    LISTS      ("Your Lists",       R.layout.activity_search,           AllLists.class),
    NEWS      ("News",              R.layout.activity_news,             NewsWeb.class),
    Find      ("Nearby Breweries",  R.layout.beer_location_list,        FindBrewery.class),
    CONTACT   ("Contact",           R.layout.activity_contact,          ContactPage.class),
    // Items NOT displayed in NavDrawerListAdapter
    SEARCH    ("Search",            R.layout.activity_search,           Search.class),
    ;

    private static MainNavItem LAST_NAV_ITEM = CONTACT;

    private String mTitleResId;
    private int mLayoutResId;
    private Class<? extends Fragment> mFragClass;


    private MainNavItem(String titleResId, int layoutResId, Class<? extends Fragment> fragClass)
    {
        mTitleResId  =  titleResId;
        mLayoutResId = layoutResId;
        mFragClass   = fragClass;
    }

    public int getLayoutResId()
    {
        return mLayoutResId;
    }

    public String getTitleResId()
    {
        return mTitleResId;
    }

    public Class<? extends Fragment> getFragClass()
    {
        return mFragClass;
    }

    public static MainNavItem[] getNavAdapterItems()
    {
        int count = LAST_NAV_ITEM.ordinal() + 1;

        MainNavItem[] adapterItems = new MainNavItem[count];
        for(int i = 0; i < count; i++){
            adapterItems[i] = values()[i];
        }

        return adapterItems;
    }
}

更新:

我只是试图注释掉这两行以关闭一般的突出显示,以便用户可以在我的抽屉菜单中重新选择一个项目。

private void setCurrentNavItem(MainNavItem navItem)
    {
        int position = navItem.ordinal();
        // If navItem is in DrawerAdapter
        if(position >= 0 && position < mDrawerAdapter.getCount()){
            //mDrawerList.setItemChecked(position, true);
        }
        else{
            // navItem not in DrawerAdapter, de-select current item
            if(mCurrentNavItem != null){
                //mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false);
            }
        }
        mDrawerLayout.closeDrawer(mDrawerList);
        setTitle(navItem.getTitleResId());
        mCurrentNavItem = navItem;
    }

当应用程序第一次启动时,没有突出显示任何内容,但当我单击某个内容时,它会突出显示,我无法再次单击它以重新加载该片段。还有其他想法吗?

共有3个答案

墨翔宇
2023-03-14

您可以通过调用菜单项来取消选择导航抽屉菜单项。setChecked(假)

申屠涛
2023-03-14

明白了。不突出显示抽奖中的项目的最简单方法是在抽奖行的xml中,选择模式应该为无:

<FrameLayout
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</FrameLayout>

<ListView
    android:id="@+id/drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:divider="@android:color/white"
    android:background="@android:color/black"
    android:choiceMode="none"/>
安高义
2023-03-14

我只是将我的项目分组如下,android:checkableBehavior=“none”这一行非常重要,确保它应该是none。

<group android:checkableBehavior="none">
    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/left_menu_home"
        android:title="@string/home" />
    <item
        android:id="@+id/nav_account_settings"
        android:icon="@drawable/left_menu_account_settings"
        android:title="@string/accountSettings" />

</group>
 类似资料:
  • 问题内容: 我有两个,一个包含一个由选择查询()填充的客户端列表,另一个包含选定的客户端的详细信息()。我想在显示细节的同时让客户保持选中状态。 XML: Java: 问题答案: 若要在按下时保持列表视图项目的颜色,请在列表视图项目布局中包括以下行: 然后在这样的文件夹中定义: 最后,将此包含在你的中: 这样,在任何时候都只能选择一项。你可以使用以下方式定义颜色值res/values/colors

  • 我在我的应用程序中使用了可以在android工作室添加的抽屉菜单,我在导航抽屉中添加了一些菜单条目(参见代码块)。如果我按下第一个项目(nav_home)或第二个,导航抽屉会突出显示当前按下的项目。 如果我按下项目“nav_information”按钮或其他项目,则会打开新的(单击的)片段,并且看不到突出显示(主页或第二个项目仍突出显示) 很快,只有第一个项目在选定的项目上显示突出显示。 这是我处

  • 问题内容: 我正在构建一个包含几个主要部分的webapp。每个部分都有几个子部分。我有一个保存导航栏的文件。HTML使用模板中的命令将其添加到基于文件。此外,我有几个小节nav文件,每个文件都使用同一命令添加到任何给定页面。 所有的导航栏都非常简单,只是带有标签的文本。 我想突出显示当前主要部分和当前子部分的链接。由于此Web应用程序很大,因此我希望以某种方式完成此操作而不添加特定于页面的信息。另

  • 问题内容: 我有一个为工作而创建的程序。该程序获取上载的文件,读取该文件,然后将数据放入GUI中的JList中。GUI实际上有两个列表,用户可以像往常一样使用JList突出显示它们,然后单击箭头以移动项目,从而可以在左右列表之间移动项目。列表是多间隔选择。 我要添加的一个小添加项是某种类型的计数器,该计数器向用户显示在实际在列表之间移动它们之前已选择了多少个项目。这将是动态的,因此如果用户按住控件

  • 我想使用swipe手势(即gmail应用程序)实现recyclerview项目之间的导航。这样,用户就不必返回列表,只需单击下一个项目就可以获得其详细信息视图。我找不到如何实现这一点的教程。

  • 我正在处理一个react项目,我想在滚动时看到相应部分时突出显示边栏导航列表,我使用useEffect和IntersectionObserver,并使用下面的代码向边栏导航项添加一个活动类。 问题是一些部分不是视口的100%高度,导致多个侧边栏导航列表项同时突出显示,我不希望这样。我希望只有一个单一的导航项目有活动类。