【问题标题】:How to open a new fragment from the navigation drawer?如何从导航抽屉中打开一个新片段?
【发布时间】:2013-12-16 16:28:29
【问题描述】:

我正在使用 developer.android.com 指南来构建应用程序。我在 Android Studio 中创建新项目时选择了“导航:导航抽屉”。我在互联网上搜索了我的问题的答案,但找不到任何有效的答案。抱歉,我是编程新手。

  1. 如何让我的应用在导航抽屉中单击时在主视图中打开一个新片段?
  2. 在导航抽屉中单击时是否可以使用标签打开多个可滑动的片段?
  3. 如何使“标题”可展开/折叠?

http://developer.android.com/design/patterns/navigation-drawer.html http://developer.android.com/training/implementing-navigation/nav-drawer.html

这就是我想要的布局:

title_section* 不是 section_title ;)

【问题讨论】:

  • +1 获得出色的绘画使用技巧...

标签: android android-fragments navigation-drawer


【解决方案1】:

导航抽屉是当今一种新的趋势设计。我们在为导航抽屉活动设计 xml.layout(layout) 时使用两种布局:主要内容布局和抽屉列表布局。我在这里回答你所有愚蠢的问题。

如何让我的应用在主视图中打开一个新片段 点击导航抽屉?

只需在抽屉列表项上添加 clicklistener 并根据单击的列表项的位置替换主要内容中的片段。

示例代码:

    // The click listener for ListView in the navigation drawer
    @SuppressWarnings("unused")
    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {

        Fragment newFragment;
        FragmentTransaction transaction = getFragmentManager().beginTransaction();

        switch (position) {
        case 0:
            newFragment = new f1();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;

        case 1:
            newFragment = new f2();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;

        case 2:
            newFragment = new f3();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;

        case 3:
            newFragment = new f4();
            transaction.replace(R.id.content_frame, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            break;  


        }
        //DrawerList.setItemChecked(position, true);
        setTitle(ListTitles[position]);
        DrawerLayout.closeDrawer(DrawerList);   
    }

这里是 f1,f2。 f3 和 f4 是不同的片段,每个片段都有自己的布局。您必须通过继承片段类为它们创建单独的 java 类。

在导航抽屉中点击时是否可以打开多个带有标签的可滑动片段?

为了在片段中实现选项卡,您可以在该特定片段中使用 tabhost。 假设您要在片段 f_main 中添加选项卡。

F_main.xml 的布局

<TabHost 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

   <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:orientation="horizontal" />

        <FrameLayout
            android:id="@+id/tabFrameLayout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>

</TabHost>

然后用它们对应的布局和java类制作其他片段f_tab1和f_tab2。 两个选项卡片段的布局可以相同或不同。在这里,我将它们采用相同或通用的布局。

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TextView android:id="@+id/google_map"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:text="MAP"/>

    </LinearLayout>

F_tab1.java 片段的代码

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class F_tab1 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view=inflater.inflate(R.layout.friends_list, container,false);


        return view;
    }

}

另一个片段的代码。即 F_tab2.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class F_tab2 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view=inflater.inflate(R.layout.friends_list, container,false);


        return view;
    }

}

现在只需使用前面提到的抽屉列表中的 clicklistener 即可在抽屉列表中的项目单击时加载 F_main,这将进一步加载主内容视图中 F_main 片段中的选项卡。

如何使“标题”可展开/可折叠?

我不知道 NV 抽屉是否提供此功能。但它提供了一个功能,可以根据选择的抽屉项目或加载的主要内容片段来切换操作栏标题。

如导航抽屉设计指南中所述,您应该在抽屉可见时修改操作栏的内容,例如更改标题并删除与主要内容相关的操作项。下面的代码展示了如何使用 ActionBarDrawerToggle 类的实例覆盖 DrawerLayout.DrawerListener 回调方法,如下所示

 public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...

        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    /* Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
    }

【讨论】:

  • 太棒了!这是一个很好的答案!非常感谢! :D
  • 回答的很详细,厉害!
  • 这样,如果你在同一个抽屉式导航项上点击两次,那么你会得到相同的片段被添加到两次返回堆栈(即如果你按下返回按钮,你会看到相同的片段,而不是前一个片段)。
  • @Aman_devy,以及如何通过另一个活动打开抽屉中存在的特定片段?
  • 每次你只是通过“newFragment = new f1();”创建一个新片段,这是一个好习惯吗?你认为将所有片段作为成员变量会更好吗?所以每次用户点击菜单项时,只需使用“transaction.replace(R.id.content_frame, mFragment1);”,无需创建新的片段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多