从另一个 activity 返回后更新片段
Update Fragment after going back from another activity
在我的应用程序中,我有 MainActivity,在这个 activity 中有一个显示以下内容的片段:"Hello, (yourname)"。您可以在首选项 activity 中更改 "yourname"。这是更改片段中名称的代码:
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View rootView = lf.inflate(R.layout.fragment_frontpage, container, false);
SharedPreferences pref= PreferenceManager.getDefaultSharedPreferences(getActivity());
String text = pref.getString("example_text","");
TextView textView = (TextView) rootView.findViewById(R.id.NameView);
textView.setText(text);
return rootView;
}
}
NameView 是名称的 Textview 的 ID,"example_text" 是名称更改器首选项的首选项键的 ID。到目前为止听起来不错,对吧?
那么,现在的问题是:当更改首选项 activity 中的名称并因此更改 "example_text" 的首选项值时,我按返回键,首页(我的 MainActivity)出现。但是,名称不会立即更改,我必须在我的任务管理器中终止该应用程序,或者转到 "about this app" 并终止该进程。之后,只有到那时,如果我再次重新打开应用程序,新名称才会显示在我的片段中。
好吧,我想我需要以某种方式在返回到我的 MainActivity 时更新片段。可能使用 onBackPressed。但问题是,怎么办?
编辑:切换到横向时出错:
4-07 19:51:37.825 7831-7831/com.dandddeveloper.leibnizvp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.dandddeveloper.leibnizvp, PID: 7831
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dandddeveloper.leibnizvp/com.dandddeveloper.leibnizvp.Frontpage}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.dandddeveloper.leibnizvp.Frontpage$PlaceholderFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.dandddeveloper.leibnizvp.Frontpage$PlaceholderFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.support.v4.app.Fragment.instantiate(Fragment.java:431)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:101)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1833)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:264)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:122)
at com.dandddeveloper.leibnizvp.Frontpage.onCreate(Frontpage.java:68)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.InstantiationException: class com.dandddeveloper.leibnizvp.Frontpage$PlaceholderFragment has no zero argument constructor
at java.lang.Class.newInstance(Class.java:1563)
at android.support.v4.app.Fragment.instantiate(Fragment.java:420)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:101)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1833)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:264)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:122)
at com.dandddeveloper.leibnizvp.Frontpage.onCreate(Frontpage.java:68)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor(Class.java:531)
at java.lang.Class.getDeclaredConstructor(Class.java:510)
at java.lang.Class.newInstance(Class.java:1561)
at android.support.v4.app.Fragment.instantiate(Fragment.java:420)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:101)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1833)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:264)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:122)
at com.dandddeveloper.leibnizvp.Frontpage.onCreate(Frontpage.java:68)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
创建这样的界面
public interface NameChangedListener {
void nameChanged(String name);
}
将以下代码添加到您的 MainActvity
private WeakHashMap<NameChangedListener, String> nameChangedListenerHashMap;
public void addNameChangedListener(
NameChangedListener nameChangedListener) {
if (nameChangedListenerHashMap == null) {
nameChangedListenerHashMap = new WeakHashMap<NameChangedListener, String>();
}
nameChangedListenerHashMap.put(nameChangedListener,
"entry");
}
private void fireNameChange() {
if (nameChangedListenerHashMap != null) {
Iterator<NameChangedListener> iterator = nameChangedListenerHashMap
.keySet().iterator();
while (iterator.hasNext()) {
NameChangedListener nameChangedListener = iterator.next();
if (nameChangedListener != null) {
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(this);
String name = pref.getString("example_text", "");
nameChangedListener.nameChanged(name);
}
}
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
fireNameChange();
}
编辑您的片段
public class PlaceholderFragment extends Fragment implements NameChangedListener{
private TextView textView;
private String previousName = null;
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View rootView = lf.inflate(R.layout.fragment_frontpage, container,
false);
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(getActivity());
previousName = pref.getString("example_text", "");
textView = (TextView) rootView.findViewById(R.id.NameView);
textView.setText(previousName);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity)activity).addNameChangedListener(this);
}
@Override
public void nameChanged(String name) {
// TODO Auto-generated method stub
if (!name.equals(previousName)) {
textView.setText(name);
previousName = name;
}
}
}
参考:http://simpledeveloper.com/how-to-communicate-between-fragments-and-activities/
在我的应用程序中,我有 MainActivity,在这个 activity 中有一个显示以下内容的片段:"Hello, (yourname)"。您可以在首选项 activity 中更改 "yourname"。这是更改片段中名称的代码:
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View rootView = lf.inflate(R.layout.fragment_frontpage, container, false);
SharedPreferences pref= PreferenceManager.getDefaultSharedPreferences(getActivity());
String text = pref.getString("example_text","");
TextView textView = (TextView) rootView.findViewById(R.id.NameView);
textView.setText(text);
return rootView;
}
}
NameView 是名称的 Textview 的 ID,"example_text" 是名称更改器首选项的首选项键的 ID。到目前为止听起来不错,对吧?
那么,现在的问题是:当更改首选项 activity 中的名称并因此更改 "example_text" 的首选项值时,我按返回键,首页(我的 MainActivity)出现。但是,名称不会立即更改,我必须在我的任务管理器中终止该应用程序,或者转到 "about this app" 并终止该进程。之后,只有到那时,如果我再次重新打开应用程序,新名称才会显示在我的片段中。
好吧,我想我需要以某种方式在返回到我的 MainActivity 时更新片段。可能使用 onBackPressed。但问题是,怎么办?
编辑:切换到横向时出错:
4-07 19:51:37.825 7831-7831/com.dandddeveloper.leibnizvp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.dandddeveloper.leibnizvp, PID: 7831
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dandddeveloper.leibnizvp/com.dandddeveloper.leibnizvp.Frontpage}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.dandddeveloper.leibnizvp.Frontpage$PlaceholderFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.dandddeveloper.leibnizvp.Frontpage$PlaceholderFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.support.v4.app.Fragment.instantiate(Fragment.java:431)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:101)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1833)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:264)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:122)
at com.dandddeveloper.leibnizvp.Frontpage.onCreate(Frontpage.java:68)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.InstantiationException: class com.dandddeveloper.leibnizvp.Frontpage$PlaceholderFragment has no zero argument constructor
at java.lang.Class.newInstance(Class.java:1563)
at android.support.v4.app.Fragment.instantiate(Fragment.java:420)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:101)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1833)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:264)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:122)
at com.dandddeveloper.leibnizvp.Frontpage.onCreate(Frontpage.java:68)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor(Class.java:531)
at java.lang.Class.getDeclaredConstructor(Class.java:510)
at java.lang.Class.newInstance(Class.java:1561)
at android.support.v4.app.Fragment.instantiate(Fragment.java:420)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:101)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1833)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:264)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:122)
at com.dandddeveloper.leibnizvp.Frontpage.onCreate(Frontpage.java:68)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
创建这样的界面
public interface NameChangedListener {
void nameChanged(String name);
}
将以下代码添加到您的 MainActvity
private WeakHashMap<NameChangedListener, String> nameChangedListenerHashMap;
public void addNameChangedListener(
NameChangedListener nameChangedListener) {
if (nameChangedListenerHashMap == null) {
nameChangedListenerHashMap = new WeakHashMap<NameChangedListener, String>();
}
nameChangedListenerHashMap.put(nameChangedListener,
"entry");
}
private void fireNameChange() {
if (nameChangedListenerHashMap != null) {
Iterator<NameChangedListener> iterator = nameChangedListenerHashMap
.keySet().iterator();
while (iterator.hasNext()) {
NameChangedListener nameChangedListener = iterator.next();
if (nameChangedListener != null) {
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(this);
String name = pref.getString("example_text", "");
nameChangedListener.nameChanged(name);
}
}
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
fireNameChange();
}
编辑您的片段
public class PlaceholderFragment extends Fragment implements NameChangedListener{
private TextView textView;
private String previousName = null;
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View rootView = lf.inflate(R.layout.fragment_frontpage, container,
false);
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(getActivity());
previousName = pref.getString("example_text", "");
textView = (TextView) rootView.findViewById(R.id.NameView);
textView.setText(previousName);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity)activity).addNameChangedListener(this);
}
@Override
public void nameChanged(String name) {
// TODO Auto-generated method stub
if (!name.equals(previousName)) {
textView.setText(name);
previousName = name;
}
}
}
参考:http://simpledeveloper.com/how-to-communicate-between-fragments-and-activities/