現在、Android APPにナビゲーションドロワーを使用しています。最初のフラグメントには、FacebookのGraph APIを使用してデータをロードするフラグメントがあります。したがって、アプリを最初にロードすると、最初に最初のフラグメントに移動します。
次に、ナビゲーションドロワーを使用して、別のフラグメントをクリックして表示します。
そして最後に、ナビゲーションドロワーを再利用して、最初のフラグメントに戻って表示します。
私が直面している問題は、ナビゲーションドロワーアイテムが選択されるたびにフラグメントを再作成するのではなく、一度作成されたフラグメントをどのように利用するかです。フラグメントを切り替えるための私のコードは次のとおりです。
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new SelectionFragment();
break;
case 1:
fragment = new HomeFragment();
break;
case 2:
fragment = new PhotosFragment();
break;
case 3:
fragment = new CommunityFragment();
break;
case 4:
fragment = new PagesFragment();
break;
case 5:
fragment = new SplashFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
オプションが選択されるたびに、フラグメントの「新しい」インスタンスが実際に存在することに気づきました。 Fragmentインスタンスを作成するロジックを実装して[〜#〜] once [〜#〜]で再利用する方法を教えてください。そうすれば、Fragmentを何度も繰り返しロードする必要がなくなります。 。
私と同じ問題に遭遇した人には、私はなんとか解決策を見つけることができました。
コンテナフレームでは、以下に示すように、使用する特定のフラグメントビューを定義する必要があります。
各フラグメントビューで、以下に示すように、"Android:name"属性を介して実際のフラグメント自体に「リンク」する必要があります。パスに注意してください。 =フラグメントに、私の場合の例はcom.example.confesssionsrp.SelectionFragmentです。
<fragment
Android:id="@+id/selectionFragment"
Android:name="com.example.confessionsrp.SelectionFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
MainActivity(またはフラグメントを表示しているアクティビティ)で、以下に示すように各フラグメントの変数を作成します。
その後、MainActivity(または特定のアクティビティ)のOncreateで、以下に示すようにさまざまなフラグメントを初期化します。
以下に示すように、「ShowFragment "」という新しいメソッドの作成に進みます。
private void showFragment(int fragmentIndex, boolean addToBackStack) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
for (int i = 0; i < fragments.length; i++) {
if (i == fragmentIndex) {
transaction.show(fragments[i]);
if (Session.getActiveSession().isClosed()) {
mDrawerLayout
.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
} else {
transaction.hide(fragments[i]);
}
}
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
それ以降、フラグメントの切り替えで、以下に示すように、選択したフラグメントを使用して "ShowFragment"メソッドを手動で呼び出します。
このすべてを全体的に行うと、フラグメントを表示するたびにリセットされることはないため、答えの解決策になります。これまで私を助けてくれた人に感謝します:)!
誰かがこれに対する別のアプローチを望んでいる場合:スタック上でフラグメントを見つけることができます:
// check if this fragment is on the backstack to avoid creating a new one
Fragment foundFragment = fragmentManager.findFragmentByTag("unique_fragment_tag");
if (foundFragment != null) {
fragmentManager.popBackStackImmediate("unique_fragment_tag", 0);
return;
}
2番目のオプションは、Android SDKが提供するnavigationDrawerの例から始めることです。プロジェクトの作成時にアクティビティのテンプレートを選択すると、以前の回答のほとんどすべてのコードが自動的に生成されます。
デバイスのローテーションなどの後でフラグメントを保持する場合は別のことですが、フラグメントを保持する必要があります。そうでない場合は、フラグメントの新しいインスタンスを変数に保存し、それがnullかどうかを確認して、新しいインスタンスを作成するか、古いインスタンスを使用する必要があります。
私は次のコードを使用しています:
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
if(position==0){// selection of tabs content
fragmentManager
.beginTransaction()
.replace(R.id.container,
SimulatorFragment.newInstance(position + 1)).commit();
}else if(position==1){
fragmentManager
.beginTransaction()
.replace(R.id.container,
HudFragment.newInstance(position + 1)).commit();
}else if(position==2){
// Display the fragment as the main content.
fragmentManager
.beginTransaction()
.replace(R.id.container,
SettingsBasicFragment.newInstance(position +1)).commit();
}else{
}
}
初めて新しいインスタンスに置き換えてフラグメントを保存できます。nullでない場合は、保存されているフラグメントに置き換えます。
アクティビティはNavigationDrawerFragment.NavigationDrawerCallbacksを実装する必要があります
フラグメントコンストラクターとnewInstanceメソッドは次のようになります。
public final class HudFragment 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.
* @param simulation
*/
public static HudFragment newInstance(int sectionNumber) {
HudFragment fragment = new HudFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public HudFragment() {
}
コードでフラグメントを切り替えるには、NavigationDrawerFragment内で次のメソッドを使用します。
/**
* Select a different section
* @param position
*/
public void select(int position){
selectItem(position);
}
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);
}
}