简体   繁体   中英

Restore fragment state after ActivityResult

I'm working on a fragment which displays a list of images. It has a button for "add image" that starts an intent for result with these values.

type: "image/*"
action: Intent.ACTION_GET_CONTENT

The problem is: after the user picks an image and returns to the fragment, all the other images in the list (stored in some ArrayList<> on the code) are gone.

I've overridden the method onSaveInstanceState(Bundle) and saved the list inside the bundle. The thing is, there's no way to restore it back.

I thought of overriding onViewStateRestored(Bundle) but it didn't work. When I put some Log.d() on all "onXXX" methods, I found that only these three are executed every time I add a file (actual order):

onPause()
onSaveInstanceState(Bundle)
//now the image picker opens up
//user picks the image
onResume()
//image picker closes and fragment is now on screen

I thought of using some "getXXX" method at onResume() but I can't find one that's useful. What can I do?

EDIT: Here is my code (without irrelevant stuff).

@Override public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    Log.d("debugaff", "oncreate");
    setRetainInstance(true);
    this.attachments = (ArrayList<Attachment>) getActivity().getIntent().getSerializableExtra(ExtraKeys.ATTACHMENTS);
}

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    Log.d("debugaff", "oncreateview");
    rootView = inflater.inflate(R.layout.fragment_attachments_form, container, false);

    //....

    if(savedInstanceState == null){
        getLoaderManager().initLoader(0, null, this);
    } else {
        attachmentsRvAdapter.setItems((List<Attachment>) savedInstanceState.getSerializable(ExtraKeys.TEMP_ATTACHMENTS));
    }

    //....

    return rootView;
}

@Override public void onResume(){
    super.onResume();
    Log.d("debugaff", "onresume");
    hideKeyboard();
}

@Override public void onPause(){
    super.onPause();
    setRetainInstance(true); //called this to make it 100% redundant (already called it at onCreate)
    Log.d("debugaff", "onpause");
}

@Override public void onViewStateRestored(@Nullable Bundle savedInstanceState){
    Log.d("debugaff", "onviewstaterestored");
    if(savedInstanceState == null){
        getLoaderManager().initLoader(0, null, this);
    } else {
        attachments.addAll((List<Attachment>) savedInstanceState.getSerializable(ExtraKeys.TEMP_ATTACHMENTS));
        attachmentsRvAdapter.setItems(attachments);
    }

    super.onViewStateRestored(savedInstanceState);
}

I have just mimic your situation and found no error (list saves the new value with old values in the list). The only problem I can think of is you are not initializing your list correctly. What I did was to initialized the list in the onCreate() method and when I pick another Image it saves that image in the same list with the previous image still in the list. There is no need to save the list separately in the savedInstanceBundle. Here is my Fragment code:

public class SelectListFragment extends Fragment {


private static final int PICK_IMAGE_REQUEST = 11;

public SelectListFragment() {
    // Required empty public constructor
}

List listOfImagesSelected;
Button selectButton;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    listOfImagesSelected=new ArrayList<Bitmap>();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_select_list, container, false);

    selectButton = view.findViewById(R.id.selectButton);
    selectButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
        }
    });
    return view;
}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);


    //I am retrieving the Bitmap from the intent and saving into the list 
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
        Uri uri = data.getData();

        try {
            //making the bitmap from the link of the file selected
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
            listOfImagesSelected.add(bitmap);
        }catch (Exception e){

        }

    }
}
}

I can share the Complete Working Code of my Project if needed. For better understanding of the Fragment LifeCycle please review this Image

To use onViewStateRestored , you need to call 'setRetainInstance(true);'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM