【问题标题】:Saving Fragment State/Data from Fragment to Fragment将片段状态/数据从片段保存到片段
【发布时间】:2015-07-03 15:22:58
【问题描述】:

我试图弄清楚如果用户离开并返回,如何将用户输入的数据保存在片段上。我有一个活动,几个片段可以解决。我发现的所有示例都是在离开 Fragment 和 Activity 时保存状态。我永远不会离开活动;因此片段中的 onSaveInstanceState 永远不会被调用。 onPause 被调用,但我无法弄清楚如何在那里保存状态。

此应用程序显示门票列表。当用户点击工单时,它会从本地数据库中获取只读字段的初步信息,并允许用户在提交前输入工单信息。我试图让用户在不丢失输入信息的情况下点击工单、输入数据、离开并返回该工单。

在我研究过的所有示例中,在我看来,我可以使用 Fragmenttransaction 来保存 Fragment 的 ID。以下是所有 Fragment 都附加到的主 Activity:

public class Activity_Main extends Activity 
implements  Fragment_OpenTickets.INT_OnOpenTicketSelectedListener,
            Fragment_SubTickets.INT_OnSubTicketSelectedListener,
            Fragment_Ticket.INT_SubmitNewTicket {
DBController dbc;
Fragment fr;
boolean gps_enabled = false;
boolean network_enabled = false;
HashMap<String, String> addInfo;
RadioButton btn_radio_open;
RadioButton btn_radio_submitted;
RadioButton btn_radio_settings;
String ticketDate, ticketTime;
int m, d, y, hr, min;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btn_radio_open = (RadioButton)findViewById(R.id.radio_open);
    btn_radio_submitted = (RadioButton)findViewById(R.id.radio_submitted);
    btn_radio_settings = (RadioButton)findViewById(R.id.radio_settings);
    dbc = new DBController(this);
    if (dbc.checkCredentials() != null) {
        fr = new Fragment_OpenTickets();
    } else {
        fr = new Fragment_Settings();
        btn_radio_open.setChecked(false);
        btn_radio_submitted.setChecked(false);
        btn_radio_settings.setChecked(true);
    }
    FragmentManager fm = getFragmentManager();
    final FragmentTransaction ft = fm.beginTransaction();
    ft.add(R.id.fragment_place, fr);
    ft.addToBackStack(null); // For back button action.
    ft.commit();

    // Start scheduler service.
    this.startService(new Intent(this, Service_Send.class));
    // Start GPS service.
    startGPS();
}

/**
 * Top menu buttons.
 */
public void selectFrag(View view) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    switch (view.getId()) {
        case R.id.radio_open:
            //fr = new Fragment_OpenTickets();
            ft.replace(R.id.fragment_place, new Fragment_OpenTickets());
            ft.addToBackStack(null);
            btn_radio_submitted.setChecked(false);
            btn_radio_settings.setChecked(false);
            ft.commit();
            break;
        case R.id.radio_submitted:
            //fr = new Fragment_SubTickets();
            ft.replace(R.id.fragment_place, new Fragment_SubTickets());
            ft.addToBackStack(null);
            btn_radio_open.setChecked(false);
            btn_radio_settings.setChecked(false);
            ft.commit();
            break;
        case R.id.radio_settings:
            //fr = new Fragment_Settings();
            ft.replace(R.id.fragment_place, new Fragment_Settings());
            ft.addToBackStack(null);
            btn_radio_open.setChecked(false);
            btn_radio_submitted.setChecked(false);
            ft.commit();
            break;
    }
}

/**
 * Open ticket selection action.
 */
public void onOpenTicketSelected(HashMap position) {
    // Create fragment and give it an argument for the selected ticket.
    fr = new Fragment_Ticket();
    Bundle args = new Bundle();
    args.putSerializable("HashMap", position);
    fr.setArguments(args);

    FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.add(R.id.fragment_place, fr);
    ft.addToBackStack(null); // For back button action.
    ft.commit();
}

/**
 * Submitted ticket selection action.
 */
public void onSubTicketSelected(HashMap position) {
    // Create fragment and give it an argument for the selected ticket.
    fr = new Fragment_SubTicket();
    Bundle args = new Bundle();
    args.putSerializable("HashMap", position);
    fr.setArguments(args);

    FragmentManager fm = getFragmentManager();
    FragmentTransaction fragmentTransaction = fm.beginTransaction();
    fragmentTransaction.replace(R.id.fragment_place, fr);
    fragmentTransaction.addToBackStack(null); // For back button action.
    fragmentTransaction.commit();
}

任何帮助将不胜感激。如果我需要发布更多代码,请告诉我。谢谢!

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    我认为您应该在用户离开片段时将票证信息存储在您的 Activity 中,并在您回来时获取信息并显示它。

    在 Activity_Main 类中,您创建了 2 个方法:

    public void saveTicketInfo(TicketInfo info) {
        // save info here
    }
    

    还有:

    public TicketInfo getTicketInfo() {
        // get info here
    }
    

    在您的片段中:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
        ...
        // get ticket info and display it
        Activity_Main mainActivity = (Activity_Main)getActivity();
        TicketInfo info = mainActivity.getTicketInfo();
        if (info != null) {
            // handle display info here
        }
        ...
    }
    
    @Override
    public void onDestroyView() {
        TicketInfo info = new TicketInfo();
        // get info from view and store in the object
        Activity_Main mainActivity = (Activity_Main)getActivity();
        mainActivity.saveTicketInfo(info)
        super.onDestroyView();
    }
    

    【讨论】:

    • 谢谢你,Thanh。这开始给我想要的行为。我现在看到的问题是,如果他们选择了与上一张不同的票证,它认为它已存储了该数据,并且会用错误的数据填充新选择的票证。这就是为什么我知道我必须了解如何使用唯一 ID。所有的票都使用相同的 Fragment,只是数据不同。
    • @Chris C.,发布的答案是合理的,但是当用户点击返回键时可能会出现问题,例如,活动可能无法访问,并且即将被销毁。阅读谷歌网页@developer.android.com/guide/components/fragments.html。有一段说“......但是,只有在片段附加到活动时才小心调用getActivity()......”
    • 是的,这个答案是合理的。能够在每张票上保存输入的数据更深入一点。再次感谢大家!
    【解决方案2】:

    我在 SO@Passing data between fragments contained in an activity 上发布了一个冗长的详细答案。搜索我的答案。这是一种将数据从 Fragment 传递到 Activity 的安全方法。然后您可以轻松地将这些数据从 Activity 传递到 Fragment 的构造函数或公共方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多