导读
1.用屏幕变更来说明一下现场保护
2.现场保护Activity方式
3.保持Fragment对象
用屏幕变更来说明一下现场保护
当屏幕由竖屏切换成横屏时
这时如果有专门的横屏UI,会调用这个UI,所谓现场保护就是不能因为屏幕或其他变更就把我们刚刚操作的数据丢失了
现场保护Activity方式
应对配置变更-限定方向
应对配置变更-自己处理变更
应对配置变更-让系统处理变更
前边讲了,我们可以针对横竖屏写两个UI布局,这样在切换时就需要让系统处理变更
布局文件 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hala.state.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create time:" />
<TextView
android:id="@+id/tvCreateTime"
android:layout_marginTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter feedback:"
android:layout_marginTop="16dp" />
<EditText
android:id="@+id/etFeedback"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/submit"
android:layout_marginTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"/>
</LinearLayout>
MainActivity.java
package com.hala.state;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
public class MainActivity extends AppCompatActivity {
public static final String CREATE_TIME = "createTime";
private long createTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//如果之前保存了就直接读取不用新建了
if(savedInstanceState!=null){
createTime=savedInstanceState.getLong(CREATE_TIME);
}else {
//真实的项目中这个值应当从服务器获取
createTime = System.currentTimeMillis();
}
String formatTime=new SimpleDateFormat("yyyy-MM--dd hh:mm:ss").format(new Date(this.createTime));
TextView tvCreatTime=(TextView)findViewById(R.id.tvCreateTime);
tvCreatTime.setText(formatTime);
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outState.putLong(CREATE_TIME,this.createTime);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
}
显示结果
保持Fragment对象
方法一:借用setRetainInstance
布局文件fragment_score.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hala.state.ScoreFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/tvScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="50sp"/>
<Button
android:id="@+id/btnAdd"
android:text="Add"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
ScoreFragment.java
package com.hala.state;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
/**
* A simple {@link Fragment} subclass.
*/
public class ScoreFragment extends Fragment {
private int score;
public ScoreFragment() {
// Required empty public constructor
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//要保持Fragment,这个方法是必需的
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_score, container, false);
final TextView tvScore=(TextView)view.findViewById(R.id.tvScore);
tvScore.setText(String.valueOf(this.score));
final Button add=(Button)view.findViewById(R.id.btnAdd);
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tvScore.setText(String.valueOf(++ScoreFragment.this.score));
}
});
return view;
}
}
MainActivity.java
package com.hala.state;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private ScoreFragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm=getSupportFragmentManager();
fragment= (ScoreFragment) fm.findFragmentByTag("ScoreFragment");
//先判断fragment是否为空,然后才创建
if(fragment==null){
fragment=new ScoreFragment();
fm.beginTransaction().replace(android.R.id.content,fragment,"ScoreFragment").commit();
}
}
}
显示结果
方法二:自己DIY
其他文件同方法一
ScoreFragment.java
package com.hala.state;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
/**
* A simple {@link Fragment} subclass.
*/
public class ScoreFragment extends Fragment {
public static final String SCORE = "score";
private int score;
public ScoreFragment() {
// Required empty public constructor
}
//这里与Activity一样,用Bundle保存
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SCORE,this.score);
}
//在onActivityCreated中恢复也可以,这里用onCreate演示
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState!=null){
this.score=savedInstanceState.getInt(SCORE);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_score, container, false);
final TextView tvScore=(TextView)view.findViewById(R.id.tvScore);
tvScore.setText(String.valueOf(this.score));
final Button add=(Button)view.findViewById(R.id.btnAdd);
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tvScore.setText(String.valueOf(++ScoreFragment.this.score));
}
});
return view;
}
}
显示结果也同上边