我试图让一个小应用程序练习片段间通信。每次单击左上角片段中的按钮时,基本片段中的计数器都会更新并显示点击次数。
我尝试使用onSaveInstanceState()方法来保存数据,以便在旋转屏幕时,仍然可以正确显示累计的点击次数。通过使用Log,我已经看到在旋转期间保留了数据,但是,我不明白为什么即使我使用保留的数据设置TextView的内容,它也会恢复到状态,好像片段是首先创建。
这是我的代码:
package com.example.fragmenttrial;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends ActionBarActivity implements Communicator {
private static final String DT = "Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(DT, "onCreate()");
HelloFragment fragment1 = new HelloFragment();
TrialFragment fragment2 = new TrialFragment();
BaseFragment fragment3 = new BaseFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.hello_placeholder, fragment1, "myHelloFragment");
transaction.replace(R.id.trial_placeholder, fragment2, "myTrialFragment");
transaction.replace(R.id.base_placeholder, fragment3, "myBaseFragment");
transaction.commit();
}
protected void onStart() {
Log.e(DT,"onStart()");
super.onStart();
}
protected void onPause() {
Log.e(DT, "onPause()");
super.onPause();
}
protected void onResume() {
Log.e(DT, "onResume()");
super.onResume();
}
protected void onRestart() {
Log.e(DT, "onRestart()");
super.onRestart();
}
protected void onStop() {
Log.e(DT, "onStop()");
super.onStop();
}
protected void onDestroy() {
Log.e(DT, "onDestroy()");
super.onDestroy();
}
protected void onSaveInstanceState(Bundle bundle) {
Log.e(DT, "onSaveInstanceState()");
super.onSaveInstanceState(bundle);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.e(DT, "onCreateOptionsMenu()");
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
Log.e(DT, "onOptionsItemSelected");
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void respond(int times) {
// TODO Auto-generated method stub
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().findFragmentById(R.id.base_placeholder);
fragment.changeData(times);
if(times == 10) {
SimpleFragment mFrag = new SimpleFragment();
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.trial_placeholder, mFrag);
trans.commit();
}
}
}
activity_main.xml中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.fragmenttrial.MainActivity"
tools:ignore="MergeRootFrame"
android:background="#0000FF">
<LinearLayout
android:id="@+id/my_linear"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="1"
android:orientation="horizontal">
<RelativeLayout
android:id="@+id/hello_placeholder"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:background="#F2E0F7"
/>
<RelativeLayout
android:id="@+id/trial_placeholder"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:background="#FFFF00"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/base_placeholder"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:background="#DF013A"
/>
</LinearLayout>
左上角片段(HelloFragment.java)
package com.example.fragmenttrial;
import javax.security.auth.login.LoginException;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
public class HelloFragment extends Fragment implements View.OnClickListener {
private int times = 0;
Communicator comm;
public static final String FT = "Fragment";
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(FT, "onCreateView()-hello");
View v = inflater.inflate(R.layout.hello_frag, container, false);
Button b = (Button) v.findViewById(R.id.button);
b.setOnClickListener(this);
return v;
}
public void onCreate(Bundle savedInstanceState) {
Log.i(FT, "onCreate()-hello");
super.onCreate(savedInstanceState);
if(savedInstanceState == null) {
//first time of creation
} else {
times = savedInstanceState.getInt("counter");
}
}
public void onSaveInstanceState(Bundle outState) {
Log.i(FT, "onSaveInstanceState()-hello");
super.onSaveInstanceState(outState);
outState.putInt("counter", times);
}
@Override
public void onClick(View v) {
times++;
comm.respond(times);
}
public void onAttach(Activity activity) {
Log.i(FT, "onAttach()-hello");
super.onAttach(activity);
comm = (Communicator) activity;
}
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(FT, "onActivityCreated()-hello");
super.onActivityCreated(savedInstanceState);
}
public void onViewStateRestored(Bundle savedInstanceState) {
Log.i(FT, "onViewStateRestored()-hello");
super.onViewStateRestored(savedInstanceState);
}
public void onStart() {
Log.i(FT, "onStart()-hello");
super.onStart();
}
public void onResume() {
Log.i(FT, "onResume()-hello");
super.onResume();
}
public void onPause() {
Log.i(FT, "onPause()-hello");
super.onPause();
}
public void onStop() {
Log.i(FT, "onStop()-hello");
super.onStop();
}
public void onDestroy() {
Log.i(FT, "onDestroy()-hello");
super.onDestroy();
}
public void onDestroyView() {
Log.i(FT, "onDestroyView()-hello");
super.onDestroyView();
}
public void onDetach() {
Log.i(FT,"onDetach()-hello");
super.onDetach();
}
}
hello_frag.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#DA81F5"
android:text="Hello world!"
android:textColor="#ffffff"
android:onClick="onClick"/>
</RelativeLayout>
BaseFragment.java
package com.example.fragmenttrial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class BaseFragment extends Fragment {
int counter;
TextView textView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(HelloFragment.FT, "onCreateView()-Base");
View v = inflater.inflate(R.layout.base_frag, container, false);
textView = (TextView) v.findViewById(R.id.text);
if(savedInstanceState == null) {
//first time being created
} else {
counter = savedInstanceState.getInt("counter");
System.out.println(counter);
textView.setText("Button was clicked: " + counter + " times.");
System.out.println(textView.getText().toString());
}
return v;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void changeData(int data) {
counter = data;
textView.setText("Button was clicked: " + data + " times.");
}
public void onSaveInstanceState(Bundle outState) {
Log.i(HelloFragment.FT,"onSaveInstanceState()-Base");
super.onSaveInstanceState(outState);
outState.putInt("counter", counter);
}
}
base_frag.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0B4C5F">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Number of clicks: "
android:textColor="#000000"
android:background="@android:color/transparent"/>
</RelativeLayout>
旋转后的日志猫:
06-20 12:03:10.929: E/Activity(7185): onPause()
06-20 12:03:10.929: I/Fragment(7185): onPause()-hello
06-20 12:03:10.929: E/Activity(7185): onSaveInstanceState()
06-20 12:03:10.976: I/Fragment(7185): onSaveInstanceState()-hello
06-20 12:03:10.980: I/Fragment(7185): onSaveInstanceState()-Base
06-20 12:03:10.984: E/Activity(7185): onStop()
06-20 12:03:10.984: I/Fragment(7185): onStop()-hello
06-20 12:03:10.984: E/Activity(7185): onDestroy()
06-20 12:03:10.984: I/Fragment(7185): onDestroyView()-hello
06-20 12:03:10.988: I/Fragment(7185): onDestroy()-hello
06-20 12:03:10.988: I/Fragment(7185): onDetach()-hello
06-20 12:03:11.113: I/Fragment(7185): onAttach()-hello
06-20 12:03:11.113: I/Fragment(7185): onCreate()-hello
06-20 12:03:11.207: E/Activity(7185): onCreate()
06-20 12:03:11.211: E/Activity(7185): onStart()
06-20 12:03:11.211: I/Fragment(7185): onCreateView()-hello
06-20 12:03:11.218: I/Fragment(7185): onActivityCreated()-hello
06-20 12:03:11.218: I/Fragment(7185): onViewStateRestored()-hello
06-20 12:03:11.242: I/Fragment(7185): onCreateView()-Base
06-20 12:03:11.250: D/dalvikvm(7185): GC_CONCURRENT freed 153K, 3% free 8277K/8519K, paused 30ms+22ms, total 101ms
06-20 12:03:11.254: I/System.out(7185): 3
06-20 12:03:11.254: I/System.out(7185): Button was clicked: 3 times.
06-20 12:03:11.254: I/Fragment(7185): onDestroyView()-hello
06-20 12:03:11.254: I/Fragment(7185): onDestroy()-hello
06-20 12:03:11.254: I/Fragment(7185): onDetach()-hello
06-20 12:03:11.257: I/Fragment(7185): onAttach()-hello
06-20 12:03:11.257: I/Fragment(7185): onCreate()-hello
06-20 12:03:11.257: I/Fragment(7185): onCreateView()-hello
06-20 12:03:11.261: I/Fragment(7185): onActivityCreated()-hello
06-20 12:03:11.261: I/Fragment(7185): onViewStateRestored()-hello
06-20 12:03:11.261: I/Fragment(7185): onCreateView()-Base
06-20 12:03:11.269: I/Fragment(7185): onStart()-hello
06-20 12:03:11.269: E/Activity(7185): onCreateOptionsMenu()
06-20 12:03:11.273: E/Activity(7185): onResume()
06-20 12:03:11.273: I/Fragment(7185): onResume()-hello
可以看到,textview文本字段在中间被更改了。但是,当显示时,它会更改回初始状态“点击次数:”,如XML中所定义。