Android Fragment,无需重新创建/重新加载Fragment即可返回

Sal*_*ana 13 android android-fragments

我已经看到了很多关于片段的问题,我似乎仍然无法弄清楚我想做的事情是否可行,如果我的设计模式有缺陷,我需要重新完成整个工作.处理.基本上,就像大多数问题一样,我有一个带有NavigationTabs的ActionBar(使用ActionBarSherlock),然后在每个Tab中有一个FragementActivity,然后FragmentActivities在选择一行时推送新的Fragments(我正在尝试重新创建) Android中的iOS项目,它只是一个基于导航的基本应用程序,其中包含一些可以深入查看特定信息的选项卡.当我单击手机上的后退按钮时,前一个片段已加载,但片段重新创建(因此每个视图再次调用WebServices),因为在以前的视图中信息不会改变,所以不需要这样做.倒退.所以基本上我想弄清楚的是如何设置我的片段,这样当我按下手机上的后退按钮时,之前的片段就会被拉上前面已经创建的项目.以下是我目前的代码:

    //This is from my FragmentActivity Class that contains the ActionBar and Tab Selection Control
    @Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub
    int selectedTab = tab.getPosition();

    if (selectedTab == 0) {
        SalesMainScreen salesScreen = new SalesMainScreen();
        ft.replace(R.id.content, salesScreen);
    }
    else if (selectedTab == 1) {
        ClientMainScreen clientScreen = new ClientMainScreen();
        ft.replace(R.id.content, clientScreen);
    }.....

   //This is within the ClientMainScreen Fragment Class, which handles moving to the Detail Fragment
   row.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            //Do something if Row is clicked
                            try{
                                String selectedClientName = clientObject.getString("ClientName");
                                String selectedClientID = clientObject.getString("ClientID");
                                String selectedValue = clientObject.getString("ClientValue");
                                transaction = getFragmentManager().beginTransaction();
                                ClientDetailScreen detailScreen = new ClientDetailScreen();
                                detailScreen.clientID = selectedClientID;
                                detailScreen.clientName = selectedClientName;
                                detailScreen.clientValue = selectedValue;
                                int currentID = ((ViewGroup)getView().getParent()).getId();
                                transaction.replace(currentID,detailScreen);
                                transaction.addToBackStack(null);
                                transaction.commit();

                            }
                            catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });....

     //And then this is the Client Detail Fragment, with the method being called to Call the Web Service and create thew (since what is displayed on this screen is dependent on what is found in the Web Service
          @Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) {
    return inflater.inflate(R.layout.clientdetailscreen, group, false);
}

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    //Setup Preferences File Link
    this.preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());

    //initialize the table object
    mainTable = (TableLayout)getActivity().findViewById(R.id.mainTable);

    //setup the detail table
    setupRelatedClientSection();

}
Run Code Online (Sandbox Code Playgroud)

然后,客户端详细信息屏幕可以再次向下钻取,使用与客户端主屏幕相同的方法,但是当我从新屏幕返回到详细信息屏幕时,再次调用seuptRelatedClientSection()方法,因此在重建时会重建整个片段.我只是想拉出该屏幕的保存版本.这可能与我目前的设置有关,还是我以错误的方式接近这个?

voy*_*tez 12

尝试使用fragementTransaction.add而不是replace


dou*_*leA 7

我相信你在寻找show()hide().

我想你仍然可以将它们添加到backstack中.

 transaction.hide(currentFragment);
 transaction.show(detailScreen);
 transaction.addToBackStack(null);
 transaction.commit();
Run Code Online (Sandbox Code Playgroud)

我没有看到我的代码,但我相信这是怎么回事......尝试一下,除非别人有更好的方法.我没有尝试使用show()hide()的backstack,但我相信它会在事务提交之前进行更改,如果按下后退按钮则会撤消它们.我有兴趣知道这个原因请回复我.

您还必须确保在调用之前创建了详细信息片段.由于它基于someitem的点击,因此您应该在每次单击时创建详细信息片段以确保创建正确的详细信息片段.

  • 我使用.add()而不是.show().从第二个片段,当我按下后退按钮时,它转到第一个片段并且没有刷新. (5认同)

Mil*_*ane 5

我正在为将来可能会提及此问题的人发布此答案。

以下代码将演示如何通过按返回按钮从 FragmentA 打开 FragmentB 并从 FragmentB 返回到 FragmentA(不刷新 FragmentA)。

public class FragmentA extends Fragment{

   ...

   void openFragmentB(){

       FragmentManager fragmentManager = 
           getActivity().getSupportFragmentManager();
       FragmentB fragmentB = FragmentB.newInstance();

       if (fragmentB.isAdded()) {

           return;
       } else {

           fragmentManager.
               beginTransaction().
               add(R.id.mainContainer,fragmentB).
               addToBackStack(FragmentB.TAG).
               commit();
      }
   }
}

public class FragmentB extends Fragment{

    public static final String TAG = 
        FragmentB.class.getSimpleName();

    ...

    public static FragmentB newInstance(){

        FragmentB fragmentB = new FragmentB();
        return fragmentB;
    }

    @Override
    public void onResume() {

        super.onResume();
        // add this piece of code in onResume method
        this.getView().setFocusableInTouchMode(true);
        this.getView().requestFocus();
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的 MainActivity 覆盖 onBackPressed()

class MainActivity extends Activity{
    ...

    @Override
    public void onBackPressed() {

        if (getFragmentManager().getBackStackEntryCount() > 0) {

            getFragmentManager().popBackStack();
        } else {

            super.onBackPressed();
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)