【发布时间】:2015-02-16 16:26:53
【问题描述】:
所以我决定在搜索 1 周后在这里发帖。我发现并尝试了很多方法来解决我的问题,但我认为我的问题有所不同。
我会尽可能清楚地解释我的问题。我有一个有 3 个片段的应用程序,当我旋转我的应用程序时,所有片段都会创建两次。
第二次,当我的片段被重新创建时,类的变量正在重置,当 saveInstanceState 第一次不为空但第二次为空时非常烦人。
我把我的日志贴在下面:
02-10 13:20:22.809: I/onAttach(7729): MenuFragment
02-10 13:20:22.822: I/onAttach(7729): MenuFragment
02-10 13:20:22.822: I/onCreateView(7729): MenuFragment
02-10 13:20:22.843: I/onCreateView(7729): MenuFragment
02-10 13:20:22.844: I/onActivityCreated(7729): MenuFragment
02-10 13:20:22.906: I/onActivityCreated(7729): MenuFragment
02-10 13:20:22.922: I/onResume(7729): MenuFragment
02-10 13:20:22.923: I/onResume(7729): MenuFragment
----------------------------------------------------------------------------
02-10 13:20:22.809: I/onAttach(7729): TabFragment
02-10 13:20:22.908: I/onAttach(7729): TabFragment
02-10 13:20:22.900: I/onCreateView(7729): TabFragment
02-10 13:20:22.908: I/onCreateView(7729): TabFragment
02-10 13:20:22.904: I/onActivityCreated(7729): TabFragment
02-10 13:20:22.911: I/onActivityCreated(7729): TabFragment
----------------------------------------------------------------------------
02-10 13:20:22.809: I/onCreate(7729): MainActivity
----------------------------------------------------------------------------
02-10 13:20:22.904: I/OnCreateView(7729): CarteFragment
02-10 13:20:22.906: I/OnCreateView(7729): CarteFragment
类的解释
- MenuFragment 包含主菜单
- TabFragment 包含主表
- CarteFragment 包含地图
- MainActivity 是一个 FragmentActivity 包含三个片段
在纵向模式下,片段位于 viewPager 中,其中包含三个选项卡,如下图所示
我无法发布图片,因为我需要 10 名声望,所以我发布了网址:http://hpics.li/5abb967
在横向模式下,所有片段都是可见的,并且可以隐藏/显示 TabFragment 和 CarteFragment,因此它会自动调整大小以占用更多空间。
另一张横向显示片段的图片:http://hpics.li/667b232
在发布之前,我阅读了很多内容,例如(对不起 (http://),我不能发布超过 2 个链接,因为我需要超过 10 个声誉:
- (http://) stackoverflow.com/questions/7223166/oncreate-and-oncreateview-invokes-a-lot-more-than-required-fragments
- (http://) developer.android.com/training/basics/fragments/fragment-ui.html#AddAtRuntime
- (http://) stackoverflow.com/questions/12201695/oncreateview-called-multiple-times-working-with-actionbar-and-fragments
- (http://)stackoverflow.com/questions/12536400/android-listfragment-created-twice
- ...等
现在我发布我的部分代码,如果您需要更多信息,请告诉我。
这是纵向模式下的 MainActivity xml:
<?xml version="1.0" encoding="utf-8"?>
<com.appli.harmo.utils.CustomViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/viewpager">
</com.appli.harmo.utils.CustomViewPager>
横向模式下的MainActivity xml:
<?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:baselineAligned="false"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:baselineAligned="false"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/tabFragmentLeftTop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
<FrameLayout
android:id="@+id/carteFragmentLeftBottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/menuDetailsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
onCreate from MainActivity 扩展 FragmentActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("onCreate", "MainActivity");
setContentView(R.layout.activity_main);
backButtonClick();
final ActionBar actionBar = creationAffichageActionBar();
gestionSession();
if(getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
tabFragment = TabFragment.newInstance();
carteFragment = CarteFragment.newInstance();
menuFragment = MenuFragment.newInstance();
buildUIPortrait(actionBar);
}else{
if (findViewById(R.id.tabFragmentLeftTop) != null) {
tabFragment = (TabFragment) getSupportFragmentManager().findFragmentById(R.id.tabFragmentLeftTop);
if (tabFragment == null) {
tabFragment = TabFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.tabFragmentLeftTop, tabFragment);
ft.commit();
}else {
tabFragment = TabFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.tabFragmentLeftTop, tabFragment);
ft.commit();
}
}
if (findViewById(R.id.carteFragmentLeftBottom) != null) {
carteFragment = (CarteFragment) getSupportFragmentManager().findFragmentById(R.id.carteFragmentLeftBottom);
if (carteFragment == null) {
carteFragment = CarteFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.carteFragmentLeftBottom, carteFragment);
ft.commit();
}else {
carteFragment = CarteFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.carteFragmentLeftBottom, carteFragment);
ft.commit();
}
}
if (findViewById(R.id.menuDetailsFragment) != null) {
menuFragment = (MenuFragment) getSupportFragmentManager().findFragmentById(R.id.menuDetailsFragment);
if (menuFragment == null) {
menuFragment = MenuFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.menuDetailsFragment, menuFragment);
ft.commit();
}else {
menuFragment = MenuFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.menuDetailsFragment, menuFragment);
ft.commit();
}
}
}
if(!tabFragment.getListReleveActif().isEmpty())
mNotifCount = tabFragment.getListReleveActif().size();
}
从 MainActivity 调用 onCreate 来构建纵向模式的 UI 的方法:
private void buildUIPortrait(final ActionBar actionBar) {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Création de l'adapter qui s'occupera de l'affichage de la liste de Fragments
this.mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), tabFragment, carteFragment, menuFragment);
pager = (ViewPager)findViewById(R.id.viewpager);
// Affectation de l'adapter au ViewPager
pager.setAdapter(this.mPagerAdapter);
pager.setOffscreenPageLimit(3);
pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
@Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
}
};
for (int i = 0; i < mPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar
.newTab()
.setText(mPagerAdapter.getPageTitle(i))
.setTabListener(tabListener));
}
}
ScreenSlidePagerAdapter 扩展了 FragmentPagerAdapter
public class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
private static final int NUM_PAGES = 3;
private TabFragment tabFragment;
private CarteFragment carteFragment;
private MenuFragment menuFragment;
public ScreenSlidePagerAdapter(FragmentManager fm, TabFragment tabFragment, CarteFragment carteFragment, MenuFragment menuFragment) {
super(fm);
this.tabFragment = tabFragment;
this.carteFragment = carteFragment;
this.menuFragment = menuFragment;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return menuFragment;
case 1:
return tabFragment;
case 2:
return carteFragment;
default:
break;
}
return null;
}
@Override
public int getCount() {
return NUM_PAGES;
}
@Override
public CharSequence getPageTitle(int position) {
String tabLabel = null;
switch (position) {
case 0:
tabLabel = "Menu";
break;
case 1:
tabLabel = "Tableau";
break;
case 2:
tabLabel = "Carte";
break;
}
return tabLabel;
}
来自 MenuFragment 的 OnCreate 和 OnCreateView
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null){
fragmentBuild = savedInstanceState.getBoolean("fragmentBuild");
stopAnimation = savedInstanceState.getBoolean("stopAnimation");
drawPoint = savedInstanceState.getBoolean("drawPoint");
sameReleve = savedInstanceState.getBoolean("sameReleve");
listButtonUI = savedInstanceState.getParcelableArrayList("listButtonUI");
listButtonActif = savedInstanceState.getParcelableArrayList("listButtonActif");
relevesSelectionnes = savedInstanceState.getParcelableArrayList("relevesSelectionnes");
currentPosition = savedInstanceState.getParcelable("currentPosition");
locationActuelle = savedInstanceState.getParcelable("locationActuelle");
}
}
@Override
public View onCreateView(LayoutInflater _inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i("onCreateView", "MenuFragment");
inflater = _inflater;
return inflater.inflate(R.layout.fragment_menu, container, false);
}
来自 TabFragment 的 OnCreate 和 OnCreateView
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null ) {
listReleveActif = savedInstanceState.getParcelableArrayList("listReleveActif");
listReleve = savedInstanceState.getParcelableArrayList("listReleve");
newAdapter = savedInstanceState.getBoolean("newAdapter");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i("onCreateView", "TabFragment");
final View fragmentTab = inflater.inflate(R.layout.fragment_tab, container, false);
fragmentTab.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1));
return fragmentTab;
}
来自 CarteFragment 的 OnCreate 和 OnCreateView
@Override
public void onCreate(Bundle savedInstanceState) {
EventBus.getDefault().registerSticky(this);
if(savedInstanceState != null){
rivieresVisible = savedInstanceState.getBoolean("rivieresVisible");
communesVisible = savedInstanceState.getBoolean("communesVisible");
departementVisible = savedInstanceState.getBoolean("departementVisible");
nomObjetVectoProche = savedInstanceState.getString("nomObjetVectoProche");
}
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i("OnCreateView", "CarteFragment");
View rootView = inflater.inflate(R.layout.fragment_carte, container, false);
LinearLayout layout = (LinearLayout)rootView.findViewById(R.id.mainLayout);
mapView = new MapView(rootView.getContext(), coucheVectoRoute, getActivity());
layout.addView(mapView,LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
return rootView ;
}
结束了,对不起大块头,我会给你所有可能的元素来指导你。
我希望你能帮助我。
再见
PS:如果我的英语不完美,我想道歉。
编辑:------------------------------------------ -------------------------------------------------- -----------------------------
我修改了 MainActivity 的 onCreate 方法。我关注这个链接move Android fragment to a different container Can't change container ID of fragment
解决了生命周期片段方法重复调用导致的生命周期方法第二段重置片段变量等问题。 (我真的不知道为什么)
比如修改前tab片段的onCreate方法第二次调用saveinstanceState为null,变量不能设置。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null ) {
listReleveActif = savedInstanceState.getParcelableArrayList("listReleveActif");
listReleve = savedInstanceState.getParcelableArrayList("listReleve");
newAdapter = savedInstanceState.getBoolean("newAdapter");
}
}
但是我我的片段总是创建两次,我不知道为什么。
下面你可以看到解决问题的MainActivity新版本的onCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("onCreate", "MainActivity");
setContentView(R.layout.activity_main);
backButtonClick();
actionBar = creationAffichageActionBar();
gestionSession();
if(savedInstanceState != null){
tabFragment = (TabFragment) getSupportFragmentManager().getFragment(savedInstanceState, TabFragment.class.getName());
carteFragment = (CarteFragment) getSupportFragmentManager().getFragment(savedInstanceState, CarteFragment.class.getName());
menuFragment = (MenuFragment) getSupportFragmentManager().getFragment(savedInstanceState, MenuFragment.class.getName());
}else{
tabFragment = TabFragment.newInstance();
carteFragment = CarteFragment.newInstance();
menuFragment = MenuFragment.newInstance();
}
if(savedInstanceState != null && getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(menuFragment);
ft.remove(tabFragment);
ft.remove(carteFragment).commit();
}
if(findViewById(R.id.viewpager) != null){
buildUIPortrait(actionBar);
}else{
if (findViewById(R.id.tabFragmentLeftTop) != null) {
if (tabFragment == null) {
tabFragment = TabFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.tabFragmentLeftTop, tabFragment);
ft.commit();
}else {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(tabFragment).commit();
fm.executePendingTransactions();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.tabFragmentLeftTop, tabFragment);
ft.commit();
}
}
if (findViewById(R.id.carteFragmentLeftBottom) != null) {
if (carteFragment == null) {
carteFragment = CarteFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.carteFragmentLeftBottom, carteFragment);
ft.commit();
}else {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(carteFragment).commit();
fm.executePendingTransactions();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.carteFragmentLeftBottom, carteFragment);
ft.commit();
}
}
if (findViewById(R.id.menuDetailsFragment) != null) {
if (menuFragment == null) {
menuFragment = MenuFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.menuDetailsFragment, menuFragment);
ft.commit();
}else {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(menuFragment).commit();
fm.executePendingTransactions();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.menuDetailsFragment, menuFragment);
ft.commit();
}
}
}
if(!tabFragment.getListReleveActif().isEmpty())
mNotifCount = tabFragment.getListReleveActif().size();
}
以及重复调用生命周期片段方法的logcat信息
2-17 16:00:27.289: I/onCreate(10224): MainActivity
02-17 16:00:27.342: I/OnCreateView(10224): CarteFragment
02-17 16:00:27.372: I/OnCreateView(10224): CarteFragment
02-17 16:00:27.289: I/onAttach(10224): TabFragment
02-17 16:00:27.375: I/onAttach(10224): TabFragment
02-17 16:00:27.334: I/onCreateView(10224): TabFragment
02-17 16:00:27.375: I/onCreateView(10224): TabFragment
02-17 16:00:27.381: I/onActivityCreated(10224): TabFragment
02-17 16:00:27.342: I/onActivityCreated(10224): TabFragment
02-17 16:00:27.289: I/onAttach(10224): MenuFragment
02-17 16:00:27.370: I/onAttach(10224): MenuFragment
02-17 16:00:27.289: I/onCreate(10224): MenuFragment
02-17 16:00:27.370: I/onCreate(10224): MenuFragment
02-17 16:00:27.307: I/onCreateView(10224): MenuFragment
02-17 16:00:27.381: I/onCreateView(10224): MenuFragment
02-17 16:00:27.308: I/onActivityCreated(10224): MenuFragment
02-17 16:00:27.382: I/onActivityCreated(10224): MenuFragment
02-17 16:00:27.394: I/onResume(10224): MenuFragment
编辑 2 尝试 KostasMatrix 的答案:------------------------------------ -------------------------------------------------- ----------------------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("onCreate", "MainActivity");
setContentView(R.layout.activity_main);
backButtonClick();
actionBar = creationAffichageActionBar();
tabFragment = TabFragment.newInstance();
carteFragment = CarteFragment.newInstance();
menuFragment = MenuFragment.newInstance();
gestionSession();
if(findViewById(R.id.viewpager) != null){
buildUIPortrait();
}else{
buildUILandscape();
}
if(!tabFragment.getListReleveActif().isEmpty())
mNotifCount = tabFragment.getListReleveActif().size();
}
onConfigurationChange 您可以在 buildUIPortortrait() 和 buildUILanscape After 下方找到
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i("RotationChange", "*************************************************");
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.activity_main_land);
buildUILandscape();
}
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
setContentView(R.layout.activity_main);
buildUIPortrait();
}
}
构建UILandscape
private void buildUILandscape() {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
if (findViewById(R.id.tabFragmentLeftTop) != null) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(tabFragment).commit();
fm.executePendingTransactions();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.tabFragmentLeftTop, tabFragment);
ft.commit();
}
if (findViewById(R.id.carteFragmentLeftBottom) != null) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(carteFragment).commit();
fm.executePendingTransactions();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.carteFragmentLeftBottom, carteFragment);
ft.commit();
}
if (findViewById(R.id.menuDetailsFragment) != null) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().remove(menuFragment).commit();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.menuDetailsFragment, menuFragment);
ft.commit();
}
}
【问题讨论】:
-
我更新了我的第一篇文章以提供新信息,希望对您有所帮助。 ps:我不理解没有解释的否决票我无法为我的未来职位取得进展。我认为我的问题很清楚,我在发布之前进行了研究。我真的不明白为什么我投了两个反对票。
-
你找到解决办法了吗?!
标签: android android-activity android-fragments android-actionbar fragment