使用 Navigation Drawer 显示片段
Display fragments with Navigation Drawer
我很困惑如何通过单击导航抽屉中的一个项目来打开我的不同片段。
在 MainActivity 中,我使用以下代码:
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment;
int id = item.getItemId();
if (id == R.id.nav_listview) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment, new ListFragment());
ft.commit();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
首先我想尝试打开我的 ListFragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ListFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
}
在我的内容 main.xml 中,我创建了以下片段,当单击导航抽屉中的特定项目时应将其替换。
<fragment
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fragment" />
但是没用...
谁能帮帮我?
拉斯塔曼
试试这个代码
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment=null;
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
int id = item.getItemId();
if (id == R.id.nav_listview) {
fragment= new ListFragment();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/container" />
嗯,我找到了答案。但我很困惑。
如果我使用:
if (id == R.id.nav_listview) {
fragment= new com.thomas.testapp.ListFragment();
有效。但是如果我想打开我的 ListFragment,我只需要使用包名。为什么?
请更改您的片段名称 class ListFragment 因为 ListFragment 已经是 android.app [=13= 中片段的子 Class ]包 android OS
我建议创建更动态的代码
首先,如果您自定义 class 来创建导航抽屉,请使用侦听器从您的 activity 调用方法
有 class 调用 HomeFragment extends Fragment,所以我们有:
if(condition){
fragment = new HomeFragment();
// if there is Listener
if(mListener != null){
mListener.someMethod
}
// Other Settings And Codes
}
为了得到你想要的,试试这个,我也被这个看起来有点复杂的代码所困扰,但它更容易使用
下面是对这个问题的详细解释和演练:
(它看起来很长,但你可以尽快轻松地关联你的工作)
当您第一次创建导航抽屉时 Activity,我们将查看 5 个文件:
- MainActivity.java - 这是我们应用程序中所有内容的背后代码。
- activity_main.xml - 这是应用程序的布局,包括导航抽屉和 app_bar_main.
的包含
- app_bar_main.xml - 这是带有工具栏(在顶部)、浮动操作按钮(在右下角)和 content_main.
- content_main.xml - 这是主页内容的布局。
- nav_header_main.xml - 这是导航抽屉顶部的 UI。
第 1 步:
打开 app_bar_main.xml,注释掉 include 并添加一个新的 FrameLayout:
<!--<include layout="@layout/content_main" />-->
<FrameLayout
android:id="@+id/Fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
这个 FrameLayout 是我们用来加载片段的地方。
第 2 步:
接下来,您需要添加一些片段
为此,请右键单击您的项目,或转到“文件”->“新建”,然后从“片段”列表中选择“片段(空白)”或其他
第 3 步:
下一步是在应用首次启动时加载片段。转到 MainActivity 的 onCreate 方法并在调用 setSupportActionBar 之后放入以下内容:
Fragment fragment = null;
Class fragmentClass = null;
fragmentClass = FragmentOne.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.Fragment_container, fragment).commit();
第 4 步:
然后您需要将 OnFragmentInteractionListener 添加到您的 MainActivity 实现的接口中并实现 onFragmentInteractionmethod.Like这个
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, FragmentOne.OnFragmentInteractionListener ,FragmentTwo.OnFragmentInteractionListener,FragmentThree.OnFragmentInteractionListener {
第 5 步:
最后,在onNavigationItemSelected方法中,可以添加点击菜单项时加载不同片段的能力:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
Class fragmentClass = null;
if (id == R.id.nav_camera) {
fragmentClass = FragmentOne.class;
} else if (id == R.id.nav_gallery) {
fragmentClass = FragmentTwo.class;
} else if (id == R.id.nav_slideshow) {
fragmentClass = FragmentThree.class;
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
这里我只是加载我添加到我的应用程序中的两个片段之一。请注意,因为我有两个不同的片段,所以我必须为 FragmentOne.OnFragmentInteractionListener 和 FragmentTwo.OnFragmentInteractionListener.
实现接口
这就是在导航抽屉中实现片段加载所需要做的全部工作。
用户点击菜单项,抽屉会顺利滑回,新片段已经开始/完成加载。这也可以防止您在启动新 activity.
时看到的任何可能的卡顿
额外
最后要注意的是,如果您切换到不同的片段然后旋转设备或引起 activity 的另一次重新创建,上面的代码将导致重新加载第一个片段。一种简单的处理方法是将片段块包装在 onCreate 方法中,检查 savedInstanceState 是否不为空,如下所示:
protected void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState == null) {
//Fragment load code
}
...
}
public class MainActivity extends AppCompatActivity {
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...From section above...
// Find our drawer view
nvDrawer = (NavigationView) findViewById(R.id.nvView);
// Setup drawer view
setupDrawerContent(nvDrawer);
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
selectDrawerItem(menuItem);
return true;
}
});
}
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass;
switch(menuItem.getItemId()) {
case R.id.nav_first_fragment:
fragmentClass = FirstFragment.class;
break;
case R.id.nav_second_fragment:
fragmentClass = SecondFragment.class;
break;
case R.id.nav_third_fragment:
fragmentClass = ThirdFragment.class;
break;
default:
fragmentClass = FirstFragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
mDrawer.closeDrawers();
}
// ...
}
我很困惑如何通过单击导航抽屉中的一个项目来打开我的不同片段。
在 MainActivity 中,我使用以下代码:
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment;
int id = item.getItemId();
if (id == R.id.nav_listview) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment, new ListFragment());
ft.commit();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
首先我想尝试打开我的 ListFragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ListFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
}
在我的内容 main.xml 中,我创建了以下片段,当单击导航抽屉中的特定项目时应将其替换。
<fragment
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fragment" />
但是没用...
谁能帮帮我?
拉斯塔曼
试试这个代码
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment=null;
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
int id = item.getItemId();
if (id == R.id.nav_listview) {
fragment= new ListFragment();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/container" />
嗯,我找到了答案。但我很困惑。 如果我使用:
if (id == R.id.nav_listview) {
fragment= new com.thomas.testapp.ListFragment();
有效。但是如果我想打开我的 ListFragment,我只需要使用包名。为什么?
请更改您的片段名称 class ListFragment 因为 ListFragment 已经是 android.app [=13= 中片段的子 Class ]包 android OS
我建议创建更动态的代码
首先,如果您自定义 class 来创建导航抽屉,请使用侦听器从您的 activity 调用方法 有 class 调用 HomeFragment extends Fragment,所以我们有:
if(condition){
fragment = new HomeFragment();
// if there is Listener
if(mListener != null){
mListener.someMethod
}
// Other Settings And Codes
}
为了得到你想要的,试试这个,我也被这个看起来有点复杂的代码所困扰,但它更容易使用
下面是对这个问题的详细解释和演练: (它看起来很长,但你可以尽快轻松地关联你的工作)
当您第一次创建导航抽屉时 Activity,我们将查看 5 个文件:
- MainActivity.java - 这是我们应用程序中所有内容的背后代码。
- activity_main.xml - 这是应用程序的布局,包括导航抽屉和 app_bar_main. 的包含
- app_bar_main.xml - 这是带有工具栏(在顶部)、浮动操作按钮(在右下角)和 content_main.
- content_main.xml - 这是主页内容的布局。
- nav_header_main.xml - 这是导航抽屉顶部的 UI。
第 1 步: 打开 app_bar_main.xml,注释掉 include 并添加一个新的 FrameLayout:
<!--<include layout="@layout/content_main" />-->
<FrameLayout
android:id="@+id/Fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
这个 FrameLayout 是我们用来加载片段的地方。
第 2 步: 接下来,您需要添加一些片段 为此,请右键单击您的项目,或转到“文件”->“新建”,然后从“片段”列表中选择“片段(空白)”或其他
第 3 步: 下一步是在应用首次启动时加载片段。转到 MainActivity 的 onCreate 方法并在调用 setSupportActionBar 之后放入以下内容:
Fragment fragment = null;
Class fragmentClass = null;
fragmentClass = FragmentOne.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.Fragment_container, fragment).commit();
第 4 步:
然后您需要将 OnFragmentInteractionListener 添加到您的 MainActivity 实现的接口中并实现 onFragmentInteractionmethod.Like这个
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, FragmentOne.OnFragmentInteractionListener ,FragmentTwo.OnFragmentInteractionListener,FragmentThree.OnFragmentInteractionListener {
第 5 步: 最后,在onNavigationItemSelected方法中,可以添加点击菜单项时加载不同片段的能力:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
Class fragmentClass = null;
if (id == R.id.nav_camera) {
fragmentClass = FragmentOne.class;
} else if (id == R.id.nav_gallery) {
fragmentClass = FragmentTwo.class;
} else if (id == R.id.nav_slideshow) {
fragmentClass = FragmentThree.class;
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
这里我只是加载我添加到我的应用程序中的两个片段之一。请注意,因为我有两个不同的片段,所以我必须为 FragmentOne.OnFragmentInteractionListener 和 FragmentTwo.OnFragmentInteractionListener.
实现接口这就是在导航抽屉中实现片段加载所需要做的全部工作。 用户点击菜单项,抽屉会顺利滑回,新片段已经开始/完成加载。这也可以防止您在启动新 activity.
时看到的任何可能的卡顿额外 最后要注意的是,如果您切换到不同的片段然后旋转设备或引起 activity 的另一次重新创建,上面的代码将导致重新加载第一个片段。一种简单的处理方法是将片段块包装在 onCreate 方法中,检查 savedInstanceState 是否不为空,如下所示:
protected void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState == null) {
//Fragment load code
}
...
}
public class MainActivity extends AppCompatActivity {
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...From section above...
// Find our drawer view
nvDrawer = (NavigationView) findViewById(R.id.nvView);
// Setup drawer view
setupDrawerContent(nvDrawer);
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
selectDrawerItem(menuItem);
return true;
}
});
}
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass;
switch(menuItem.getItemId()) {
case R.id.nav_first_fragment:
fragmentClass = FirstFragment.class;
break;
case R.id.nav_second_fragment:
fragmentClass = SecondFragment.class;
break;
case R.id.nav_third_fragment:
fragmentClass = ThirdFragment.class;
break;
default:
fragmentClass = FirstFragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
mDrawer.closeDrawers();
}
// ...
}