Android – Как изменить фрагменты в навигационном ящике

Я довольно новичок в программировании на Android, но до сих пор все хорошо. Я прочитал много ответов на этот вопрос, но, похоже, не могу сделать свою работу. В основном, у меня есть MainActivity с ящиком навигации. У меня есть два фрагмента, правильно инициализированные с соответствующим расположением фрагментов xmls. В настоящее время я могу получить свой первый фрагмент, который будет отображаться при запуске приложения, и когда я нажимаю на каждый элемент в ящике, названия изменяются; Однако фрагмент остается прежним. Какие-либо предложения? Я считаю, что соответствующий код приведен ниже (не показан код для NavigationDrawerFragment.java с необходимым кодом, автоматически созданным Eclipse). Заранее спасибо!

public class MainActivity extends Activity implements NavigationDrawerFragment.NavigationDrawerCallbacks { /** * Fragment managing the behaviors, interactions and presentation of the navigation drawer. */ private NavigationDrawerFragment mNavigationDrawerFragment; /** * Used to store the last screen title. For use in {@link #restoreActionBar()}. */ private CharSequence mTitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mNavigationDrawerFragment = (NavigationDrawerFragment) getFragmentManager().findFragmentById(R.id.navigation_drawer); mTitle = getTitle(); // Set up the drawer. mNavigationDrawerFragment.setUp( R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout)); } @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.content_frame, PlaceholderFragment.newInstance(position + 1)) .commit(); } public void onSectionAttached(int number) { switch (number) { case 1: mTitle = getString(R.string.title_home); break; case 2: mTitle = getString(R.string.title_infodirect); break; case 3: mTitle = getString(R.string.title_trailmap); break; case 4: mTitle = getString(R.string.title_poi); break; case 5: mTitle = getString(R.string.title_photomap); break; case 6: mTitle = getString(R.string.title_report); break; case 7: mTitle = getString(R.string.title_rulesreg); } } public void restoreActionBar() { ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setDisplayShowTitleEnabled(true); actionBar.setTitle(mTitle); } @Override public boolean onCreateOptionsMenu(Menu menu) { if (!mNavigationDrawerFragment.isDrawerOpen()) { // Only show items in the action bar relevant to this screen // if the drawer is not showing. Otherwise, let the drawer // decide what to show in the action bar. getMenuInflater().inflate(R.menu.overview, menu); restoreActionBar(); return true; } return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { /** * The fragment argument representing the section number for this * fragment. */ private static final String ARG_SECTION_NUMBER = "section_number"; /** * Returns a new instance of this fragment for the given section * number. */ public static PlaceholderFragment newInstance(int sectionNumber) { PlaceholderFragment fragment = new PlaceholderFragment(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_home, container, false); return rootView; } @Override public void onAttach(Activity activity) { super.onAttach(activity); ((MainActivity) activity).onSectionAttached( getArguments().getInt(ARG_SECTION_NUMBER)); } } public static class InfoDirectFragment extends Fragment { /** * The fragment argument representing the section number for this * fragment. */ private static final String ARG_SECTION_NUMBER = "section_number"; /** * Returns a new instance of this fragment for the given section * number. */ public static InfoDirectFragment newInstance(int sectionNumber) { InfoDirectFragment fragment = new InfoDirectFragment(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } public InfoDirectFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_infodirect, container, false); return rootView; } @Override public void onAttach(Activity activity) { super.onAttach(activity); ((MainActivity) activity).onSectionAttached( getArguments().getInt(ARG_SECTION_NUMBER)); } } } 

Solutions Collecting From Web of "Android – Как изменить фрагменты в навигационном ящике"

Следуйте за этой ссылкой !! Для более подробной информации и использования

 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) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); switch (position) { case 0: ft.replace(R.id.content_frame, new Fragment1, Constants.TAG_FRAGMENT).commit(); break; case 1: ft.replace(R.id.content_frame, new Fragment2, Constants.TAG_FRAGMENT); ft.commit(); break; } mDrawerList.setItemChecked(position, true); setTitle(title[position]); // Close drawer mDrawerLayout.closeDrawer(mDrawerList); } 
 @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); if (position == 0) { fragmentManager.beginTransaction() .replace(R.id.container, FirstFragment.newInstance()) .commit(); } else if (position == 1) { fragmentManager.beginTransaction() .replace(R.id.container, SecondFragment.newInstance()) .commit(); } else if (position == 2) { fragmentManager.beginTransaction() .replace(R.id.container, ThridFragment.newInstance()) .commit(); } } 

И создать фрагмент

 public class FirstFragment extends Fragment { public static FirstFragment newInstance() { FirstFragment fragment = new FirstFragment(); return fragment; } public FirstFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_first, container, false); return rootView; } @Override public void onAttach(Activity activity) { super.onAttach(activity); ((MainActivity) activity).onSectionAttached(1); } } 

Я работал с навигационным ящиком на основе того, что сгенерировал Eclipse (похоже, что он был сделан и с ним), и я немного обрезал его, так что это не совсем глупо. В некоторых случаях я также делал черную магию, потому что у меня возникали глупые ошибки, которые я исправлял по временам (например, не удалось обновить заголовок панели действий в режиме «Назад») или что если вы поворачиваете экран, тогда элемент по индексу 0 воссоздается по активности):

NavigationDrawerActivity:

 public class NavigationDrawerActivity extends ActionBarActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks { /** * Fragment managing the behaviors, interactions and presentation of the navigation drawer. */ private NavigationDrawerFragment mNavigationDrawerFragment; /** * Used to store the last screen title. For use in {@link #restoreActionBar()}. */ private CharSequence mTitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager() .findFragmentById(R.id.navigation_drawer); mTitle = getString(R.string.drawer_0); // Set up the drawer. mNavigationDrawerFragment.setUp(R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout)); getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() { public void onBackStackChanged() { int backCount = getSupportFragmentManager().getBackStackEntryCount(); if (backCount == 0) { finish(); } else { Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.container); mTitle = getString(((GetActionBarTitle) fragment).getActionBarTitleId()); restoreActionBar(); } } }); if (savedInstanceState != null) { this.onBackPressed(); } } public void restoreActionBar() { ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setDisplayShowTitleEnabled(true); actionBar.setTitle(mTitle); } @Override public boolean onCreateOptionsMenu(Menu menu) { if (!mNavigationDrawerFragment.isDrawerOpen()) { // Only show items in the action bar relevant to this screen // if the drawer is not showing. Otherwise, let the drawer // decide what to show in the action bar. getMenuInflater().inflate(R.menu.main, menu); restoreActionBar(); return true; } return super.onCreateOptionsMenu(menu); } @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); boolean addToBackStack = true; Fragment fragment = null; switch (position) { case 0: fragment = new Fragment0(); break; case 1: fragment = new Fragment1(); break; case 2: fragment = new Fragment2(); break; case 3: fragment = new Fragment3(); break; case 4: fragment = new Fragment4(); break; case 5: logout(); default: Log.w(this.getClass().getSimpleName(), "Reached Default in onNavigationDrawerItemSelected!"); break; } if (fragment != null) { FragmentTransaction ft = fragmentManager.beginTransaction(); ft.replace(R.id.container, fragment); if (addToBackStack == true) { ft.addToBackStack(null); } ft.commit(); mTitle = getString(((GetActionBarTitle) fragment).getActionBarTitleId()); restoreActionBar(); } } public void logout() { this.finish(); } } 

Коварный «GetActionBarTitle»:

  public interface GetActionBarTitle { public int getActionBarTitleId(); } 

Сгенерированный файл NavigationDrawerFragment (я не думаю, что я вообще изменил это):

 public class NavigationDrawerFragment extends Fragment { /** * Remember the position of the selected item. */ private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position"; /** * Per the design guidelines, you should show the drawer on launch until the user manually expands * it. This shared * preference tracks this. */ private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned"; /** * A pointer to the current callbacks instance (the Activity). */ private NavigationDrawerCallbacks mCallbacks; /** * Helper component that ties the action bar to the navigation drawer. */ private ActionBarDrawerToggle mDrawerToggle; private DrawerLayout mDrawerLayout; private ListView mDrawerListView; private View mFragmentContainerView; private int mCurrentSelectedPosition = 0; private boolean mFromSavedInstanceState; private boolean mUserLearnedDrawer; public NavigationDrawerFragment() { } /** * Callbacks interface that all activities using this fragment must implement. */ public static interface NavigationDrawerCallbacks { /** * Called when an item in the navigation drawer is selected. */ void onNavigationDrawerItemSelected(int position); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Read in the flag indicating whether or not the user has demonstrated awareness of the // drawer. See PREF_USER_LEARNED_DRAWER for details. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false); if (savedInstanceState != null) { mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION); mFromSavedInstanceState = true; } // Select either the default item (0) or the last selected item. selectItem(mCurrentSelectedPosition); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Indicate that this fragment would like to influence the set of actions in the action bar. setHasOptionsMenu(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mDrawerListView = (ListView) inflater.inflate(R.layout.fragment_navigation_drawer, container, false); mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectItem(position); } }); String[] drawerTitles = new String[] { getString(R.string.drawer_0), getString(R.string.drawer_1), getString(R.string.drawer_2), getString(R.string.drawer_3), getString(R.string.drawer_4), getString(R.string.drawer_5) }; mDrawerListView.setAdapter(new ArrayAdapter<String>(getActionBar().getThemedContext(), android.R.layout.simple_list_item_1, android.R.id.text1, drawerTitles)); mDrawerListView.setItemChecked(mCurrentSelectedPosition, true); return mDrawerListView; } public boolean isDrawerOpen() { return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView); } /** * Users of this fragment must call this method to set up the navigation drawer interactions. * * @param fragmentId * The android:id of this fragment in its activity's layout. * @param drawerLayout * The DrawerLayout containing this fragment's UI. */ public void setUp(int fragmentId, DrawerLayout drawerLayout) { mFragmentContainerView = getActivity().findViewById(fragmentId); mDrawerLayout = drawerLayout; // set a custom shadow that overlays the main content when the drawer opens mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); // set up the drawer's list view with items and click listener ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); // ActionBarDrawerToggle ties together the the proper interactions // between the navigation drawer and the action bar app icon. mDrawerToggle = new ActionBarDrawerToggle(getActivity(), /* host Activity */ mDrawerLayout, /* DrawerLayout object */ R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */ R.string.navigation_drawer_open, /* "open drawer" description for accessibility */ R.string.navigation_drawer_close /* "close drawer" description for accessibility */ ) { @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); if (!isAdded()) { return; } getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu() } @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); if (!isAdded()) { return; } if (!mUserLearnedDrawer) { // The user manually opened the drawer; store this flag to prevent auto-showing // the navigation drawer automatically in the future. mUserLearnedDrawer = true; SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply(); } getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu() } }; // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer, // per the navigation drawer design guidelines. if (!mUserLearnedDrawer && !mFromSavedInstanceState) { mDrawerLayout.openDrawer(mFragmentContainerView); } // Defer code dependent on restoration of previous instance state. mDrawerLayout.post(new Runnable() { @Override public void run() { mDrawerToggle.syncState(); } }); mDrawerLayout.setDrawerListener(mDrawerToggle); } private void selectItem(int position) { mCurrentSelectedPosition = position; if (mDrawerListView != null) { mDrawerListView.setItemChecked(position, true); } if (mDrawerLayout != null) { mDrawerLayout.closeDrawer(mFragmentContainerView); } if (mCallbacks != null) { mCallbacks.onNavigationDrawerItemSelected(position); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mCallbacks = (NavigationDrawerCallbacks) activity; } catch (ClassCastException e) { throw new ClassCastException("Activity must implement NavigationDrawerCallbacks."); } } @Override public void onDetach() { super.onDetach(); mCallbacks = null; } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Forward the new configuration the drawer toggle component. mDrawerToggle.onConfigurationChanged(newConfig); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { // If the drawer is open, show the global app actions in the action bar. See also // showGlobalContextActionBar, which controls the top-left area of the action bar. if (mDrawerLayout != null && isDrawerOpen()) { inflater.inflate(R.menu.global, menu); showGlobalContextActionBar(); } super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } /* * if (item.getItemId() == R.id.action_example) * { * Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show(); * return true; * } */ return super.onOptionsItemSelected(item); } /** * Per the navigation drawer design guidelines, updates the action bar to show the global app * 'context', rather than * just what's in the current screen. */ private void showGlobalContextActionBar() { ActionBar actionBar = getActionBar(); actionBar.setDisplayShowTitleEnabled(true); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setTitle(R.string.app_name); } private ActionBar getActionBar() { return ((ActionBarActivity) getActivity()).getSupportActionBar(); } } 

Пример фрагмента, созданного этим навигационным ящиком:

  public class MyFragment extends Fragment implements GetActionBarTitle, OnClickListener { private int titleId; private Button btn0; private Button btn1; private Button btn2; public MyFragment() { super(); titleId = R.string.drawer_myfragment_title; } @Override public int getActionBarTitleId() { return titleId; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_myfragment, container, false); return rootView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); btn0 = (Button) view.findViewById(R.id.btn0); btn1 = (Button) view.findViewById(R.id.btn1); btn2 = (Button) view.findViewById(R.id.btn2); btn0.setOnClickListener(this); btn1.setOnClickListener(this); btn2.setOnClickListener(this); } @Override public void onClick(View v) { if (btn0 == v) { } else if (btn1 == v) { } else if (btn2 == v) { } } } 

Надеюсь, это работает так, как вы планировали. Мне приходилось делать магию с помощью BackStackListener и работать над тем, чтобы работать правильно.

Я знаю, что это довольно старый, но я хотел бы поделиться некоторыми статьями, которые я написал о навигации в приложении Drawer и Fragment. Они обновлены с последними образцами (как минимум на 2017 год). Не стесняйтесь взглянуть на:

https://aarcoraci.wordpress.com/2017/02/13/android-tutorial-drawer-and-fragment-navigation-made-easyier/

https://aarcoraci.wordpress.com/2017/02/14/android-drawer-and-fragment-navigation-a-more-real-life-scenario/