Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 碎片从背面消失_Android_Android Fragments_Android Actionbar_Android Tabs - Fatal编程技术网

Android 碎片从背面消失

Android 碎片从背面消失,android,android-fragments,android-actionbar,android-tabs,Android,Android Fragments,Android Actionbar,Android Tabs,为什么在以下情况下,FragmentTwo会从后台消失: 我的应用程序在活动中有一个名为FragmentOne的片段 FragmentOne持有一个按钮。单击后,它将启动FragmentTwo,并将其添加到Fragmentbackstack中 FragmentTwo有一个按钮,单击该按钮时,会在操作栏中添加两个选项卡,链接到两个片段,FragmentThree和FragmentFour碎片三可见 如果我现在单击后退按钮,我希望看到FragmentTwo。相反,我看到的是FragmentOne。

为什么在以下情况下,
FragmentTwo
会从后台消失:

  • 我的应用程序在
    活动中有一个名为
    FragmentOne
    片段
  • FragmentOne
    持有一个
    按钮
    。单击后,它将启动
    FragmentTwo
    ,并将其添加到
    Fragment
    backstack中
  • FragmentTwo
    有一个
    按钮
    ,单击该按钮时,会在
    操作栏
    中添加两个选项卡,链接到两个
    片段
    FragmentThree
    FragmentFour
    <代码>碎片三
    可见
  • 如果我现在单击后退按钮,我希望看到
    FragmentTwo
    。相反,我看到的是
    FragmentOne
    FragmentTwo
    去了哪里
在我重写
onKeyDown()
并开始为
片段实现我自己的backbackback之前,我想问一下是否有明显的遗漏?注意:测试时没有发生配置更改

详情:

FragmentOne的按钮单击处理程序包含:

    FragmentTransaction ft = getFragmentManager().beginTransaction();
    FragmentTwo fragment = new FragmentTwo();
    ft.addToBackStack(null);
    ft.replace(android.R.id.content, fragment).commit();
碎片两个按钮点击在活动中处理:

    getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    FragmentFour fragmentThree = new FragmentThree();
    FragmentFive fragmentFive = new FragmentFive();

    ActionBar.Tab tab = getActionBar().newTab().setText("Frag 3").setTabListener(new CustomTabListener<FragmentThree>(fragmentThree));
    getActionBar().addTab(tab);
    tab = getActionBar().newTab().setText("Frag 4").setTabListener(new CustomTabListener<FragmentFour>(fragmentFour));
    getActionBar().addTab(tab);
getActionBar().setNavigationMode(ActionBar.NAVIGATION\u MODE\u选项卡);
FragmentFour fragmentThree=新的fragmentThree();
FragmentFive FragmentFive=新的FragmentFive();
ActionBar.Tab Tab=getActionBar().newTab().setText(“Frag3”).setTableListener(新的CustomTableListener(fragmentThree));
getActionBar().addTab(选项卡);
tab=getActionBar().newTab().setText(“碎片4”).setTableListener(新的CustomTableListener(碎片四));
getActionBar().addTab(选项卡);
其中选项卡侦听器是:

public static class CustomTabListener<T extends Fragment> implements TabListener {
    Fragment fragment;

    public CustomTabListener(Fragment fragment) {
        this.fragment = fragment;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        ft.replace(android.R.id.content, fragment);
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(fragment);
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {

    }
}
public静态类CustomTabListener实现了TabListener{
片段;
公共CustomTableListener(片段){
this.fragment=片段;
}
已选择的公共事务(选项卡,碎片事务ft){
ft.replace(android.R.id.content,fragment);
}
已选择公共空页(选项卡,碎片事务ft){
ft.去除(碎片);
}
已重新选择公共无效页签(页签,碎片事务){
}
}
如果在显示
FragmentThree
之前向backstack添加更多
FragmentThree
,则始终且仅
FragmentThree
之前的
片段
消失


当我按back键离开选项卡式用户视图并返回到
FragmentOne
时,选项卡仍在显示。我知道我需要将
ActionBar
重置为
NAVIGATION\u MODE\u STANDARD
,但不清楚为什么显示
FragmentOne
而不是
FragmentTwo

,我认为问题在于是否构建了选项卡

public void onTabSelected(Tab tab, FragmentTransaction ft) {
    ft.replace(android.R.id.content, fragment);
}
调用,并且之前的片段未添加到backback

你试过打电话吗

ft.addToBackStack(null);
在片段中有两个按钮处理代码


但无论如何,您都需要实现
onBackPressed()
以摆脱选项卡。我想我应该使用选项卡创建新活动。

始终使用此代码块替换片段:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(android.R.id.content, YOUR_FRAGMENT);
ft.addToBackStack(null);
ft.commit();

我认为您需要删除
onTabUnselected()
函数中的
ft.remove
,因为replace已经这样做了。

根据上面显示的代码,您永远不会将Fragment2添加到后堆栈中

@gabe,@Pierre,您在侦听器中使用
addToBackStack()
获得非法状态异常的原因在API中有说明

在API级别11中添加

当选项卡进入选定状态时调用

“参数”选项卡选定的选项卡

ft一个FragmentTransaction,用于在选项卡切换期间对要执行的片段操作进行排队。上一个选项卡的取消选择和此选项卡的选择将在单个事务中执行

此FragmentTransaction不支持添加到后堆栈

解决这个问题的简单方法是使用FragmentManager在TabListener中获取您自己的FragmentTransaction,并将其添加到后堆栈中。像这样的

    public static class CustomTabListener<T extends Fragment> implements TabListener {
    Fragment fragment;

    public CustomTabListener(Fragment fragment) {
        this.fragment = fragment;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        FragmentManager fm = getFragmentManager();
        FragmentTransaction newFragTrans = fm.beginTransaction();
        newFragTrans.replace(android.R.id.content, fragment);
        newFragTrans.addToBackStack(null);
        newFragTrans.commit()
        
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(fragment);
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {

    }
}
public静态类CustomTabListener实现了TabListener{
片段;
公共CustomTableListener(片段){
this.fragment=片段;
}
已选择的公共事务(选项卡,碎片事务ft){
FragmentManager fm=getFragmentManager();
FragmentTransaction newFragTrans=fm.beginTransaction();
newFragTrans.replace(android.R.id.content,fragment);
newFragTrans.addToBackStack(空);
newFragTrans.commit()
}
已选择公共空页(选项卡,碎片事务ft){
ft.去除(碎片);
}
已重新选择公共无效页签(页签,碎片事务){
}
}
我只是选了,但你明白了。另外,不要忘记提交此事务,因为侦听器只会自动提交提供的
FragmentTransaction ft

最后一件事,确保在执行事务后调用
addToBackStack()
,因为这是要添加到堆栈中的内容,而不是实际的片段。在上面的代码中,这不是为Fragment1的按钮单击而做的


希望这有帮助。

@Pierre Rymiortz,我刚刚解决了这个问题。请参考下面的代码

public class StartActivity extends SherlockFragmentActivity implements
    TabListener, OnBackStackChangedListener {

private Context mContext = null;

private ActionBar mActionBar;

private Tab mTab;

private Fragment mSelectFragment;

private final static int ONE = 0;
private final static int TWO = 1;
private final static int THREE = 2;
private final static int PLAYERS = 3;

private MenuItem mPlayerItem = null;

private FragmentTransaction mFragmentTransaction = null;

/**
 * by default is false - TABS were taken in the starting true - when we are
 * changing back to TABS from STANDARD
 */
private boolean mTabsChanges = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mContext = this;

    mActionBar = getSupportActionBar();

    // hiding the ActionBar icon
    mActionBar.setDisplayShowHomeEnabled(true);

    // for displaying the Arrow button
    mActionBar.setDisplayHomeAsUpEnabled(true);

    // hide Actionbar title
    mActionBar.setDisplayShowTitleEnabled(true);

    // Create Actionbar Tabs
    mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // Create first Tab
    mTab = mActionBar.newTab().setTabListener(this);
    mTab.setText("One");
    mActionBar.addTab(mTab);

    // Create Second Tab

    mTab = mActionBar.newTab().setTabListener(this);
    mTab.setText("Two");
    mActionBar.addTab(mTab);

    // Create Three Tab
    mTab = mActionBar.newTab().setTabListener(this);
    mTab.setText("Three");
    mActionBar.addTab(mTab);

    getSupportFragmentManager().addOnBackStackChangedListener(this);

}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    mFragmentTransaction = ft;
    if (mTabsChanges) {
        // nothing to do here
        mTabsChanges = false;
    } else {
        switch (mActionBar.getSelectedNavigationIndex()) {
        case ONE:
            clearBackStack(mTabsChanges);
            mSelectFragment = new Fragment1();
            ft.replace(R.id.fragment_container, mSelectFragment, ONE + "");
            break;
        case TWO:
            clearBackStack(mTabsChanges);
            mSelectFragment = new Fragment2();
            ft.replace(R.id.fragment_container, mSelectFragment, TWO + "");
            break;
        case THREE:
            clearBackStack(mTabsChanges);
            mSelectFragment = new Fragment3();
            ft.replace(R.id.fragment_container, mSelectFragment, THREE + "");
            break;
        }
    }

}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    Toast.makeText(
            mContext,
            "tab unselected." + mActionBar.getSelectedNavigationIndex()
                    + "", Toast.LENGTH_SHORT).show();
}

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
    Toast.makeText(
            mContext,
            "tab reselected." + mActionBar.getSelectedNavigationIndex()
                    + "", Toast.LENGTH_SHORT).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // TODO Auto-generated method stub
    MenuInflater mInflate = getSupportMenuInflater();
    mInflate.inflate(R.menu.header_menu, menu);

    mPlayerItem = menu.findItem(R.id.men_set_players);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.men_set_players) {
        addFragmentToStack();
        return true;
    }
    return false;
}

private void addFragmentToStack() {

    // Add the fragment to the activity, pushing this transaction
    // on to the back stack.
    mActionBar.setTitle(getResources().getString(R.string.menu_players));
    mSelectFragment = new PlayersFragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, mSelectFragment, "Players");
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.addToBackStack("players");
    ft.commit();
}

@Override
public void onBackStackChanged() {
    FragmentManager fm = getSupportFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        int TOP = fm.getBackStackEntryCount() - 1;
        Log.i("BACKSTACK", TOP + ".."
                + fm.getBackStackEntryAt(TOP).getName());
        if (fm.getBackStackEntryAt(TOP).getName()
                .equalsIgnoreCase("players")) {
            if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
                mTabsChanges = false;
                mActionBar
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            }
        } else {
            if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
                mTabsChanges = true;
                mActionBar
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            }
        }

    } else {
        if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
            mTabsChanges = true;
            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        } else if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
            mTabsChanges = false;
        }
    }

    Toast.makeText(mContext,
            "FM Back count." + fm.getBackStackEntryCount(),
            Toast.LENGTH_SHORT).show();
}

public void clearBackStack(boolean callFromSelection) {
    if (!callFromSelection) {
        FragmentManager fm = getSupportFragmentManager();
        for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
            fm.popBackStackImmediate();
        }
    } else {
        Toast.makeText(mContext, "callfromreapprearence",
                Toast.LENGTH_SHORT).show();
    }
}

}
公共类StartActivity扩展SherlockFragmentActivity实现
TabListener,onbackbackchangedlistener{
私有上下文mContext=null;
私人行动吧;
私人标签mTab;
私有片段;
私有最终静态整数=0;
私有最终静态int 2=1;
私有最终静态int三=2;
私人决赛静态整数玩家=3;
private MenuItem mPlayerItem=null;
私有FragmentTransaction MFFragmentTransaction=null;
/**
*默认情况下为false-制表符在开始时为true-whe
public class StartActivity extends SherlockFragmentActivity implements
    TabListener, OnBackStackChangedListener {

private Context mContext = null;

private ActionBar mActionBar;

private Tab mTab;

private Fragment mSelectFragment;

private final static int ONE = 0;
private final static int TWO = 1;
private final static int THREE = 2;
private final static int PLAYERS = 3;

private MenuItem mPlayerItem = null;

private FragmentTransaction mFragmentTransaction = null;

/**
 * by default is false - TABS were taken in the starting true - when we are
 * changing back to TABS from STANDARD
 */
private boolean mTabsChanges = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mContext = this;

    mActionBar = getSupportActionBar();

    // hiding the ActionBar icon
    mActionBar.setDisplayShowHomeEnabled(true);

    // for displaying the Arrow button
    mActionBar.setDisplayHomeAsUpEnabled(true);

    // hide Actionbar title
    mActionBar.setDisplayShowTitleEnabled(true);

    // Create Actionbar Tabs
    mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // Create first Tab
    mTab = mActionBar.newTab().setTabListener(this);
    mTab.setText("One");
    mActionBar.addTab(mTab);

    // Create Second Tab

    mTab = mActionBar.newTab().setTabListener(this);
    mTab.setText("Two");
    mActionBar.addTab(mTab);

    // Create Three Tab
    mTab = mActionBar.newTab().setTabListener(this);
    mTab.setText("Three");
    mActionBar.addTab(mTab);

    getSupportFragmentManager().addOnBackStackChangedListener(this);

}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    mFragmentTransaction = ft;
    if (mTabsChanges) {
        // nothing to do here
        mTabsChanges = false;
    } else {
        switch (mActionBar.getSelectedNavigationIndex()) {
        case ONE:
            clearBackStack(mTabsChanges);
            mSelectFragment = new Fragment1();
            ft.replace(R.id.fragment_container, mSelectFragment, ONE + "");
            break;
        case TWO:
            clearBackStack(mTabsChanges);
            mSelectFragment = new Fragment2();
            ft.replace(R.id.fragment_container, mSelectFragment, TWO + "");
            break;
        case THREE:
            clearBackStack(mTabsChanges);
            mSelectFragment = new Fragment3();
            ft.replace(R.id.fragment_container, mSelectFragment, THREE + "");
            break;
        }
    }

}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    Toast.makeText(
            mContext,
            "tab unselected." + mActionBar.getSelectedNavigationIndex()
                    + "", Toast.LENGTH_SHORT).show();
}

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
    Toast.makeText(
            mContext,
            "tab reselected." + mActionBar.getSelectedNavigationIndex()
                    + "", Toast.LENGTH_SHORT).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // TODO Auto-generated method stub
    MenuInflater mInflate = getSupportMenuInflater();
    mInflate.inflate(R.menu.header_menu, menu);

    mPlayerItem = menu.findItem(R.id.men_set_players);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.men_set_players) {
        addFragmentToStack();
        return true;
    }
    return false;
}

private void addFragmentToStack() {

    // Add the fragment to the activity, pushing this transaction
    // on to the back stack.
    mActionBar.setTitle(getResources().getString(R.string.menu_players));
    mSelectFragment = new PlayersFragment();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, mSelectFragment, "Players");
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.addToBackStack("players");
    ft.commit();
}

@Override
public void onBackStackChanged() {
    FragmentManager fm = getSupportFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        int TOP = fm.getBackStackEntryCount() - 1;
        Log.i("BACKSTACK", TOP + ".."
                + fm.getBackStackEntryAt(TOP).getName());
        if (fm.getBackStackEntryAt(TOP).getName()
                .equalsIgnoreCase("players")) {
            if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
                mTabsChanges = false;
                mActionBar
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            }
        } else {
            if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
                mTabsChanges = true;
                mActionBar
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            }
        }

    } else {
        if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
            mTabsChanges = true;
            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        } else if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
            mTabsChanges = false;
        }
    }

    Toast.makeText(mContext,
            "FM Back count." + fm.getBackStackEntryCount(),
            Toast.LENGTH_SHORT).show();
}

public void clearBackStack(boolean callFromSelection) {
    if (!callFromSelection) {
        FragmentManager fm = getSupportFragmentManager();
        for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
            fm.popBackStackImmediate();
        }
    } else {
        Toast.makeText(mContext, "callfromreapprearence",
                Toast.LENGTH_SHORT).show();
    }
}

}