Android fragments 接收活动结果后保留片段状态
我有一个由片段A组成的活动A。在片段A中,我用startActivityForResult()启动活动B。当我从活动B收到结果时,片段A中所有在设置之前已经设置好的视图值都会返回到它们的默认值。如何在片段A中保留所有视图值 实施情况如下: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
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());