【问题标题】:Restore fragment state after ActivityResultActivityResult 后恢复片段状态
【发布时间】:2019-09-20 14:38:47
【问题描述】:

我正在处理一个显示图像列表的片段。它有一个用于“添加图像”的按钮,用于启动具有这些值的结果意图。

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

问题是:用户选择一张图片返回到fragment后,列表中的所有其他图片(存储在代码上的某个ArrayList中)都不见了。

我已经覆盖了onSaveInstanceState(Bundle) 方法并将列表保存在包中。问题是,没有办法恢复它。

我曾想过覆盖onViewStateRestored(Bundle),但没有奏效。当我在所有“onXXX”方法上放一些Log.d()时,发现每次添加文件时只执行这三个(实际顺序):

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

我想过在onResume() 使用一些“getXXX”方法,但我找不到有用的方法。我能做什么?

编辑:这是我的代码(没有不相关的东西)。

@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);
}

【问题讨论】:

  • 如何收到使用 onSaveInstanceState() 保存的包?
  • @zain 没错,这是我的问题
  • 您是否尝试过覆盖 onActivityCreated()?
  • 您的片段是如何添加到您的活动中的?我怀疑您不小心将片段替换为同一类的新实例,而不是重新使用现有的。

标签: android android-fragments android-lifecycle fragment-lifecycle


【解决方案1】:

我刚刚模仿了您的情况,没有发现错误(列表将新值与列表中的旧值一起保存)。我能想到的唯一问题是您没有正确初始化列表。我所做的是在 onCreate() 方法中初始化列表,当我选择另一个图像时,它将该图像保存在同一个列表中,而前一个图像仍在列表中。 无需将列表单独保存在savedInstanceBundle中。这是我的Fragment代码:

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){

        }

    }
}
}

如果需要,我可以分享我的项目的完整工作代码。为了更好地理解片段生命周期,请查看此图片

【讨论】:

    【解决方案2】:

    要使用onViewStateRestored,你需要调用'setRetainInstance(true);'

    【讨论】:

    • 我在某处发现并尝试了。没有真正奏效。也许它适用于其他类型的恢复,比如从片段完全关闭时开始......
    猜你喜欢
    • 1970-01-01
    • 2013-04-04
    • 2014-04-25
    • 2019-09-13
    • 1970-01-01
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多