Android fragments 接收活动结果后保留片段状态

Android fragments 接收活动结果后保留片段状态,android-fragments,Android Fragments,我有一个由片段A组成的活动A。在片段A中,我用startActivityForResult()启动活动B。当我从活动B收到结果时,片段A中所有在设置之前已经设置好的视图值都会返回到它们的默认值。如何在片段A中保留所有视图值 实施情况如下: public class MainFragment extends Fragment { public MainFragment() { } @Override public View onCreateView(LayoutInflater inflater

我有一个由片段A组成的活动A。在片段A中,我用startActivityForResult()启动活动B。当我从活动B收到结果时,片段A中所有在设置之前已经设置好的视图值都会返回到它们的默认值。如何在片段A中保留所有视图值

实施情况如下:

public class MainFragment extends Fragment {
public MainFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_main, container, false);
}

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


    listView = (ListView) getActivity().findViewById(R.id.xlistview);
    xItemArrayList = new ArrayList<XItem>();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    switch (id){
        case R.id.menu_item_add:
            initialiseList();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

private void initialiseList(){
    xListAdapter = new xListAdapter(getContext(), R.layout.item_list, xItemArrayList);
    xListAdapter.setxListListener(new xListListener() {
        @Override
        public void onClickStart(View view) {
            openAutocompleteActivity(Constant.VIEW_START);
        }

    });
    xListView.setAdapter(xListAdapter);
}

private void openAutocompleteActivity(int selectedView) {
    this.selectedView = selectedView;
    try {
        // The autocomplete activity requires Google Play Services to be available. The intent
        // builder checks this and throws an exception if it is not the case.
        Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN).build(getActivity());
        startActivityForResult(intent, Constant.REQUEST_CODE_AUTOCOMPLETE);
    } catch (GooglePlayServicesRepairableException e) {
        // Indicates that Google Play Services is either not installed or not up to date. Prompt the user to correct the issue.
        GoogleApiAvailability.getInstance().getErrorDialog(getActivity(), e.getConnectionStatusCode(), 0 ).show();
    } catch (GooglePlayServicesNotAvailableException e) {
        // Indicates that Google Play Services is not available and the problem is not easily resolvable.
        String message = "Google Play Services is not available: " + GoogleApiAvailability.getInstance().getErrorString(e.errorCode);
        Log.e(Constant.TAG_ERROR, message);
        Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
    }
}

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

    // Check that the result was from the autocomplete widget.
    if (requestCode == Constant.REQUEST_CODE_AUTOCOMPLETE) {
        if (resultCode == Constant.RESULT_OK) {
            // Get the user's selected place from the Intent.
            Place place = PlaceAutocomplete.getPlace(getActivity(), data); 
            if (selectedView == Constant.VIEW_START){
                start = place;
                ((TextView)xListView.getChildAt(0).findViewById(R.id.textview_start)).setText(start.getName());
            }else if (selectedView == Constant.VIEW_LAST){
                last = place;
                ((TextView)xListView.getChildAt(0).findViewById(R.id.textview_last)).setText(last.getName());
            }

        } else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
            Status status = PlaceAutocomplete.getStatus(getActivity(), data);
            Log.e(Constant.TAG_ERROR, "Error: Status = " + status.toString());
        } else if (resultCode == Constant.RESULT_CANCELED) {
            // Indicates that the activity closed before a selection was made. For example if
            // the user pressed the back button.
        }
    }
}
public类MainFragment扩展片段{
公共MainFragment(){
}
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
返回充气机。充气(右布局图。主容器,假);
}
@凌驾
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
listView=(listView)getActivity().findViewById(R.id.xlistview);
xItemArrayList=新的ArrayList();
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
int id=item.getItemId();
开关(id){
案例R.id.菜单\项目\添加:
initialiseList();
返回true;
违约:
返回super.onOptionsItemSelected(项目);
}
}
私有void initialiseList(){
xListAdapter=新的xListAdapter(getContext(),R.layout.item_list,xItemArrayList);
setxListListener(新的xListListener(){
@凌驾
公共void onClickStart(视图){
OpenAutoCompleteTactivity(常量。视图\启动);
}
});
xListView.setAdapter(xListAdapter);
}
私有void openautocompletetactivity(int-selectedView){
this.selectedView=selectedView;
试一试{
//自动完成活动要求Google Play服务可用
//构建器将对此进行检查,如果不是这样,则抛出异常。
Intent Intent=newplaceautocomplete.IntentBuilder(PlaceAutocomplete.MODE_全屏).build(getActivity());
startActivityForResult(意图、常量、请求、代码、自动完成);
}捕获(谷歌游戏服务可修复例外){
//表示Google Play服务未安装或不是最新的。提示用户更正此问题。
GoogleAppAvailability.getInstance().getErrorDialog(getActivity(),e.getConnectionStatusCode(),0.show();
}捕获(谷歌PlayServicesNotAvailableException){
//表示Google Play服务不可用,且问题不易解决。
String message=“Google Play服务不可用:”+GoogleAppAvailability.getInstance().getErrorString(e.errorCode);
Log.e(Constant.TAG_错误,消息);
Toast.makeText(getActivity(),message,Toast.LENGTH_SHORT).show();
}
}
@凌驾
ActivityResult上的公共void(int请求代码、int结果代码、意图数据){
super.onActivityResult(请求代码、结果代码、数据);
//检查结果是否来自自动完成小部件。
if(requestCode==常量。请求\代码\自动完成){
if(resultCode==常量。结果\u确定){
//从意图中获取用户选择的位置。
Place-Place=PlaceAutocomplete.getPlace(getActivity(),data);
如果(selectedView==常量。视图\u开始){
开始=地点;
((TextView)xListView.getChildAt(0).findViewById(R.id.TextView_start)).setText(start.getName());
}else if(selectedView==常量。查看\u最后一次){
最后=地点;
((TextView)xListView.getChildAt(0).findViewById(R.id.TextView_last)).setText(last.getName());
}
}else if(resultCode==PlaceAutocomplete.RESULT\u错误){
Status Status=PlaceAutocomplete.getStatus(getActivity(),data);
Log.e(Constant.TAG_ERROR,“ERROR:Status=“+Status.toString());
}else if(resultCode==常量。结果\u已取消){
//指示在进行选择之前活动已关闭。例如,如果
//用户按下了后退按钮。
}
}
}
R.layout.item_列表中有两个视图,R.id.textview_start和R.id.textview_last。在选择每个视图时,活动B将启动,在完成活动B时,结果将显示在视图本身上。但是,每次活动B启动和完成时,这两个视图的先前值都会消失并返回默认值。我已尝试SavedInstanceState,但它不工作。似乎当活动B返回到活动A(其中包含片段A)时,系统转到片段A的OnResume(),而不转到片段A的onCreatedView()。

您可以使用2种方法: 第一:使用SharedReferences存储数据。现在下次使用应用程序时也可以访问此数据。因此,显示旧数据后,只需将sharepreferences中的数据重置为空白

第二:使用bundle将数据传输到活动中,然后将相同的数据取回

使用捆绑包将数据从一个活动传输到另一个活动

Bundle bundle = new Bundle();
bundle.putString("KEY_NAME", "Abrakadabra");
Intent i = new Intent(this, MyActivityName.class);
i.putExtras(bundle);
startActivity(i)  <-- new activity started
将数据从活动传递到片段:将此代码放在任意位置

Bundle bundle = new Bundle();
bundle.putString("KEY_NAME", "Abrakadabra");
MyFragment myfragment = new MyFragment();
myfragment.setArguments(bundle);
然后在片段的onCreateView方法中添加以下代码

Bundle args = getArguments();
String stringdata = args.getString("KEY_NAME"); 

由于片段A正在等待活动B的结果,因此活动A(其中片段A)将进入暂停状态。当活动B返回结果时,片段A将继续,而不经过onActivityCreated()。因此,保存实例状态将不起作用。目前,我能想到的唯一解决方案如下

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

// Check that the result was from the autocomplete widget.
if (requestCode == Constant.REQUEST_CODE_AUTOCOMPLETE) {
    if (resultCode == Constant.RESULT_OK) {
        // Get the user's selected place from the Intent.
        Place place = PlaceAutocomplete.getPlace(getActivity(), data); 
        if (selectedView == Constant.VIEW_START){
            start = place;
        }else if (selectedView == Constant.VIEW_LAST){
            last = place;
        }

    } else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
        Status status = PlaceAutocomplete.getStatus(getActivity(), data);
        Log.e(Constant.TAG_ERROR, "Error: Status = " + status.toString());
    } else if (resultCode == Constant.RESULT_CANCELED) {
        // Indicates that the activity closed before a selection was made. For example if
        // the user pressed the back button.
    }
}

if(start!=null)((TextView)xListView.getChildAt(0).findViewById(R.id.textview_start)).setText(start.getName());    
if(last!=null)((TextView)xListView.getChildAt(0).findViewById(R.id.textview_last)).setText(last.getName());
}


所有视图值都在onActivityResult()中重新设置。当活动A/片段A进入暂停状态时,它保留全局变量值。因此,为了使这个实现能够工作,必须在片段A中将start和last声明为全局变量。如果有更好的解决方案,请提出建议

谢谢suku的回答。如果我试图保留的值是基元类型,那么方法1是可行的。若从活动B到片段A的转换是手动编码的,那个么方法2是可行的,系统将转到onCreateV
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

// Check that the result was from the autocomplete widget.
if (requestCode == Constant.REQUEST_CODE_AUTOCOMPLETE) {
    if (resultCode == Constant.RESULT_OK) {
        // Get the user's selected place from the Intent.
        Place place = PlaceAutocomplete.getPlace(getActivity(), data); 
        if (selectedView == Constant.VIEW_START){
            start = place;
        }else if (selectedView == Constant.VIEW_LAST){
            last = place;
        }

    } else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
        Status status = PlaceAutocomplete.getStatus(getActivity(), data);
        Log.e(Constant.TAG_ERROR, "Error: Status = " + status.toString());
    } else if (resultCode == Constant.RESULT_CANCELED) {
        // Indicates that the activity closed before a selection was made. For example if
        // the user pressed the back button.
    }
}

if(start!=null)((TextView)xListView.getChildAt(0).findViewById(R.id.textview_start)).setText(start.getName());    
if(last!=null)((TextView)xListView.getChildAt(0).findViewById(R.id.textview_last)).setText(last.getName());