Saving information from one fragment and dialog if the user navigates to another fragment

后端 未结 1 362
终归单人心
终归单人心 2020-12-21 23:42

I have a screen where the user presses a button to bring up a DialogFragment with an EditText. They enter their information, and press Ok

相关标签:
1条回答
  • 2020-12-22 00:33

    It sounds as if the boolean isTextButtonFirstClick simply is mistakenly set to false.

    This would make sense of a new instance of Advice Fragment is created during the navigation.

    Try

    • Setting setRetainInstance(true) in onCreate of Advice Fragment in order to keep the boolean.

    • If R.id.fragmentContainer is a fragment tag in XML, then change it to a LinearLayout or RelativeLayout (you are adding a fragment on top anyways, and I suspect the findFragmentById to always return null)

    • Change the code in your Activity to:

      FragmentManager fm = getSupportFragmentManager();
      Fragment fragment = fm.findFragmentByTag("singleFragment");
      
      if (fragment == null)
      {
          fragment = createFragment();
      }
      
         fm.beginTransaction()
              .replace(R.id.fragmentContainer, fragment,  "singleFragment" )
              .commit();
      

    Generally when programmatically adding fragments, you use tags, whereas when defining the fragment in XML letting the Android framework handle the lifecycle, you can find it by id.

    Looks to me as if you are in a in-between solution, trying to do both, which will not work as intended.

    Hope this can help and sorry in advance if there are formatting issues. The answer has been written from a phone :-)

    Edit:

    If you only wanted to save simple types of info (such as the boolean), I would point you to one of my old answers here: Saving textview in a fragment when rotating screen

    Your last comment revealed that you have some complex information (text, photos, videos etc) that you want to persist.

    Making all that Parcelable will be a huge pain, so here goes my second advice:

    1. Add EventBus to your project https://github.com/greenrobot/EventBus
    2. Create a holder class for the information, such as

      public class AdviceHolder {
          private boolean isTextButtonFirstClick;
          private String text;
          private BitMap image;
          ... 
      
         // setter and getter methods (if using eclipse alt+shit+s 'create setter and getters from fields') 
      }
      
    3. Now when starting AdviceActivity, you prepare a new AdviceHolder

      public class AdviceActivity extends SingleFragmentActivity
      {
          @Override
          public void onCreate(Bundle savedInstanceState) {
              // make a new AdviceHolder if none existed
              AdviceHolder holder = new AdviceHolder();
              AdviceHolder existingHolder = EventBus.getDefault().getStickyEvent(AdviceHolder.class);
              if (existingHolder == null) {        
                   EventBus.getDefault().postSticky(holder);
              }
      
              super.onCreate(savedInstanceState);
          }
      
          @Override
          protected Fragment createFragment()
          {
              return new AdviceFragment();
          }
      }
      

    This step will make a AdviceHolder object available anywhere in your code. Think of it as a global repository.

    This means that no matter how you move between Activites or Fragments, they all have access to AdviceHolder and can edit it.

    So for example in you AdviceFragment:

    private AdviceHolder holder;
    
    ...
    @Override
    public void onCreate (Bundle savedInstanceState) {
        AdviceHolder holder = (AdviceHolder)EventBus.getDefault().getStickyEvent(AdviceHolder.class);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
    {
        // read isTextButtonFirstClick from holder
        boolean isTextButtonFirstClick = holder.isTextButtonFirstClick();
    
        mTextButton = (Button) v.findViewById(R.id.textButton);
        mTextButton.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                if (isTextButtonFirstClick)
                {
                    FragmentManager fm = getActivity().getSupportFragmentManager();
                    InputTextFragment dialog = InputTextFragment.newInstance("", isTextButtonFirstClick);
                    dialog.setTargetFragment(AdviceFragment.this, REQUEST_TEXT);
                    dialog.show(fm, DIALOG_TEXT);
    
                    // update isTextButtonFirstClick in holder
                    holder.setTextButtonFirstClick(false);
                    EventBus.getDefault().postStickyEvent(holder);
                }
                else
                {
                    FragmentManager fm = getActivity().getSupportFragmentManager();
                    InputTextFragment dialog = InputTextFragment.newInstance(mAdvice.getText(), isTextButtonFirstClick);
                    dialog.setTargetFragment(AdviceFragment.this, REQUEST_TEXT);
                    dialog.show(fm, DIALOG_TEXT);
                }
            }
        });
    ...
    }
    

    When you at some point are done filling the AdviceHolder (and sent it to a server or whatever the plan is), remove it from EventBus to enable the creation of a new holder in AdviceActivity.

    EventBus.getDefault().removeStickyEvent(AdviceHolder.class);
    

    For other examples about EventBus have a look at http://www.stevenmarkford.com/passing-objects-between-android-activities/

    This is all a lot of information, hope it is not too confusing.

    0 讨论(0)
提交回复
热议问题