FragmentTabHost在popBackStack之后获取空片段

时间:2015-09-11 21:29:01

标签: android android-fragments tabs fragment-tab-host

我已经尝试过StackOverflow中的每一篇帖子并且没有成功,我有一个带有标签的FragmentTabHost活动A B C D E

当我转到标签A然后转到标签B时一切正常,但如果我返回标签A是空白的,那么返回标签B也是空白的!

A - > B - > A =空白 - > B =空白

我按照这篇文章让它工作Dynamically changing the fragments inside a fragment tab host?,但标签之间的转换无效。

我已经尝试将我的BaseContainerFragment更改为使用getSupportFragmentManager而不是getChildFragmentManager但是不成功,此时也删除了addToBackStack(null)我想出任何帮助,谢谢。

这是mainActivity,其中包含使用片段创建标签的代码。

public class ActivityMain extends FragmentActivity {

    public static final String TAB_1_TAG = "tab_1";
    public static final String TAB_2_TAG = "tab_2";
    public static final String TAB_3_TAG = "tab_3";
    public static final String TAB_4_TAG = "tab_4";
    public static final String TAB_5_TAG = "tab_5";
    private FragmentTabHost mTabHost;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
        mTabHost.getTabWidget().setDividerDrawable(null);
        mTabHost.getTabWidget().setStripEnabled(false);

        mTabHost.addTab(mTabHost.newTabSpec(TAB_1_TAG).setIndicator("", getResources().getDrawable(R.drawable.tab_account)), FragmentAccountContainer.class, null);
        mTabHost.addTab(mTabHost.newTabSpec(TAB_2_TAG).setIndicator("", getResources().getDrawable(R.drawable.tab_discounts)), FragmentPromotionsContainer.class, null);
        mTabHost.addTab(mTabHost.newTabSpec(TAB_3_TAG).setIndicator("", getResources().getDrawable(R.drawable.tab_payment)), FragmentAccountContainer.class, null);
        mTabHost.addTab(mTabHost.newTabSpec(TAB_4_TAG).setIndicator("", getResources().getDrawable(R.drawable.tab_gas)), FragmentAccountContainer.class, null);
        mTabHost.addTab(mTabHost.newTabSpec(TAB_5_TAG).setIndicator("", getResources().getDrawable(R.drawable.tab_rest)), FragmentAccountContainer.class, null);
    }

    @Override
    public void onBackPressed() {
        boolean isPopFragment = false;

        String currentTabTag = mTabHost.getCurrentTabTag();
        Log.e("ActivityMain", "currentTabTag: " + currentTabTag);
        if (currentTabTag.equals(TAB_1_TAG)) {
            isPopFragment = ((BaseContainerFragment) getSupportFragmentManager().findFragmentByTag(TAB_1_TAG)).popFragment();
        } else if (currentTabTag.equals(TAB_2_TAG)) {
            isPopFragment = ((BaseContainerFragment) getSupportFragmentManager().findFragmentByTag(TAB_2_TAG)).popFragment();
        } else if (currentTabTag.equals(TAB_3_TAG)) {
            isPopFragment = ((BaseContainerFragment) getSupportFragmentManager().findFragmentByTag(TAB_3_TAG)).popFragment();
        } else if (currentTabTag.equals(TAB_4_TAG)) {
            isPopFragment = ((BaseContainerFragment) getSupportFragmentManager().findFragmentByTag(TAB_4_TAG)).popFragment();
        } else if (currentTabTag.equals(TAB_5_TAG)) {
            isPopFragment = ((BaseContainerFragment) getSupportFragmentManager().findFragmentByTag(TAB_5_TAG)).popFragment();
        }
        Log.e("ActivityMain", "isPopFragment: " + isPopFragment);
        if (!isPopFragment) {
            finish();
        }
    }
}

这是我的BaseContainerFragment,它允许回溯和替换片段

public class BaseContainerFragment extends Fragment {

    public void replaceFragment(Fragment fragment, boolean addToBackStack) {
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        if (addToBackStack) {
            transaction.addToBackStack(null);
        }
        transaction.replace(R.id.container_framelayout, fragment);
        transaction.commit();
        getChildFragmentManager().executePendingTransactions();
    }

    public boolean popFragment() {
        Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
        boolean isPop = false;
        if (getChildFragmentManager().getBackStackEntryCount() > 0) {
            isPop = true;
            getChildFragmentManager().popBackStack();
        }
        return isPop;
    }
}

这是第一个Tab的容器(此选项卡包含2个活动,一个是main,另一个是在listview上调用Click)

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myPrefs = this.getActivity().getSharedPreferences("getLogin", Context.MODE_PRIVATE);
    idUser = myPrefs.getInt("idUser", 0);

    d(TAG, "idUser: " + idUser);
    /*
    Map<String,?> keys = myPrefs.getAll();

    for(Map.Entry<String,?> entry : keys.entrySet()){
        Log.d("map values",entry.getKey() + ": " +
                entry.getValue().toString());
    }
    */
    context = getActivity();
    pDialog = new SweetAlertDialog(context, PROGRESS_TYPE);


    // Check if Internet present
    if (!isOnline(context)) {
        // Internet Connection is not present
        makeText(context, "Error en la conexion de Internet",
                LENGTH_LONG).show();
        // stop executing code by return
        return;
    }

    new asyncGetFeedClass(context).execute();

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.activity_cardholder, container, false);

    toolbar = (Toolbar) v.findViewById(R.id.toolbar);
    TextView mTitle = (TextView) toolbar.findViewById(toolbar_title);
    mTitle.setText("TARJETAS");

    list = (ListView) v.findViewById(R.id.list);

    // Click event for single list row
    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {

            FragmentAccount fragment = new FragmentAccount();
            // if U need to pass some data
            Bundle bundle = new Bundle();

            if (listBalance.get(position).get(TAG_ACCOUNT_BANKACCOUNTS_ID) != null) {
                bundle.putString("idBankAccount", listBalance.get(position).get(TAG_ACCOUNT_BANKACCOUNTS_ID));
                bundle.putString("idGiftCard", "0");
            } else if (listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_ID) != null) {
                bundle.putString("idGiftCard", listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_ID));
                bundle.putString("idBankAccount", "0");
            } else {
                bundle.putString("idBankAccount", "0");
                bundle.putString("idGiftCard", "0");
            }

            fragment.setArguments(bundle);
            ((BaseContainerFragment) getParentFragment()).replaceFragment(fragment, false);
        }
    });

    return v;
}

标签#1的主要类

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myPrefs = this.getActivity().getSharedPreferences("getLogin", Context.MODE_PRIVATE);
    idUser = myPrefs.getInt("idUser", 0);

    d(TAG, "idUser: " + idUser);
    /*
    Map<String,?> keys = myPrefs.getAll();

    for(Map.Entry<String,?> entry : keys.entrySet()){
        Log.d("map values",entry.getKey() + ": " +
                entry.getValue().toString());
    }
    */
    context = getActivity();
    pDialog = new SweetAlertDialog(context, PROGRESS_TYPE);

    // Check if Internet present
    if (!isOnline(context)) {
        // Internet Connection is not present
        makeText(context, "Error en la conexion de Internet",
                LENGTH_LONG).show();
        // stop executing code by return
        return;
    }

    Bundle bundle = this.getArguments();
    idBankAccount = Integer.parseInt(bundle.getString(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_ID, "0"));
    idGiftCard = Integer.parseInt(bundle.getString(FragmentCardHolder.TAG_ACCOUNT_GIFTCARDS_ID, "0"));

    if(idBankAccount > 0){
        new asyncGetBankTransactions(context).execute();
    } else if(idGiftCard > 0) {
        new asyncGetGiftCardTransactions(context).execute();
    } else {
        new asyncGetX111Transactions(context).execute();
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.activity_account, container, false);

    toolbar = (Toolbar) v.findViewById(id.toolbar);
    TextView mTitle = (TextView) toolbar.findViewById(toolbar_title);
    mTitle.setText("MI CUENTA");
    toolbar.setNavigationIcon(R.drawable.icon_user);
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            goToCards();
        }
    });

    layoutAccount = (LinearLayout) v.findViewById(id.layoutAccount);
    layoutGetCredit = (LinearLayout) v.findViewById(id.layoutGetCredit);
    layoutTransactions = (LinearLayout) v.findViewById(id.layoutTransactions);

    btnAccount = (Button) v.findViewById(id.btnMyBalance);
    btnGetCredit = (Button) v.findViewById(id.btnGetCredit);
    btnSendCredit = (Button) v.findViewById(id.btnSendCredit);
    btnTransactions = (Button) v.findViewById(id.btnTransactions);

    list = (ListView) v.findViewById(id.list);

    btnTransactions.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            layoutAccount.setVisibility(View.GONE);
            layoutGetCredit.setVisibility(View.GONE);
            layoutTransactions.setVisibility(View.VISIBLE);
        }
    });

    btnGetCredit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            layoutAccount.setVisibility(View.GONE);
            layoutGetCredit.setVisibility(View.VISIBLE);
            layoutTransactions.setVisibility(View.GONE);
        }
    });

    btnAccount.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            layoutAccount.setVisibility(View.VISIBLE);
            layoutGetCredit.setVisibility(View.GONE);
            layoutTransactions.setVisibility(View.GONE);
        }
    });

    return v;
}

private void goToCards() {
    FragmentCardHolder fragment = new FragmentCardHolder();
    ((BaseContainerFragment) getParentFragment()).replaceFragment(fragment, true);
}

2 个答案:

答案 0 :(得分:2)

我认为问题出现在代码的隐藏部分,您将第一个片段添加到容器(FragmentAccountContainer和FragmentPromotionsContainer类)。我建议你在BaseContainerFragment.class中创建带有签名的抽象方法 protected abstract Fragment getFirstFragment(); 因此具体的容器类将覆盖此方法并将第一个片段的新实例返回到超类,然后在父类中使用add transaction将其添加到片段容器中。

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState == null) {
        addFragment(getFirstFragment(), false);
    }
}

请注意,在添加片段之前,应检查savedInstanceState是否为null,以避免在系统活动重新创建时进行重新发布。 在嵌套片段中,您可以像使用((BaseContainerFragment) getParentFragment()).replaceFragment(___, true);

一样使用替换

我也有一些建议给你代码。由于known bug with default back logic and child fragment manager,你无法在@NecipAllef建议的活动中避免覆盖onBackPressed,但你可以简化对popFragment的调用,如

@Override
public void onBackPressed() {
    String currentTabTag = mTabHost.getCurrentTabTag();
    boolean isPopFragment = ((BaseContainerFragment) getSupportFragmentManager().findFragmentByTag(currentTabTag)).popFragment();
    if (!isPopFragment) {
        super.onBackPressed();
    }
}

并且为了将bundle设置为片段,我建议使用fabric方法模式,比如

public class TestFragment extends Fragment {
    public static Fragment newInstance(String text){
        Fragment fragment = new TestFragment();
        Bundle args = new Bundle();
        args.putString("text", text);
        fragment.setArguments(args);
        return fragment;
    }
}

Ps:我为你创建了一个带有描述逻辑的simple project

答案 1 :(得分:1)

为什么要跟踪碎片并自行弹出?你不需要这样做,你不应该覆盖onBackPressed()。让FragmentManager处理片段事务。

如果活动中有片段,请使用

FragmentManager fManager = getSupportFragmentManager();

或者如果您想在Android 3.0之前支持设备,请使用

FragmentManager fManager = getChildFragmentManager();

如果片段在另一个片段内,则使用

fManager.beginTransaction().add(R.id.fragment_parent, new FirstTabFragment()).commit();

使用fManager后,要显示片段,请使用

fManager.beginTransaction().replace(R.id.fragment_parent, new SecondTabFragment())
                           .addToBackStack(null)
                           .commit();

其中fragment_parent是您要放置片段的父视图。

如果要切换到下一个片段,请使用

long

由于您将其添加到后台堆栈,当您按下后,您将看到第一个片段。就是这样。

此外,您可以轻松地意识到这将导致您的片段每次都从头开始创建,您可以通过初始化它们并重复使用它们来防止这种情况。

HTH