在新添加一个页面的时候,需要全局性考虑,并不仅仅是写一个Activity重写7个生命周期的回调方法。其实要考虑的还有很多,下面我整理以下新增加一个页面需要注意的几点。
1.新增页面建议采用一个空白的Activity贴上一个Fragment,因为Fragment自带状态的保存和恢复功能,我们可以非常方便的还原数据。Fragment缺点是生命周期比较复杂,但是还是建议使用Fragment。
2.避免没有必要绘制的背景,Activity默认自带了一个背景,一般情况下我们写的layout已经完全将其遮挡了,所以这个背景是没有必要绘制的,以防引起过度绘制的问题。一般onCreate调用下面代码去掉背景。
getWindow().setBackgroundDrawable(null);
3.为页面写布局的时候一般为其套一个ScrollView,防止在屏幕比较小的设备上显示不全,或者横屏情况下显示不下,因为ScrollView显示不下会滚动。并且要给其加上属性:android:fillViewPort=true,这个属性的作用在于,如果屏幕不够显示,则分配给ScroillView需要显示的大小,显示不下的地方可滚动,如果屏幕足够显示ScrollView所有内容,则会将整个屏幕空间的大小分配给ScrollView,而不是ScrollView控件实际需要的大小。这个属性真的很有用。
4.能用LinearLayout实现的就不要用RelativeLayout,原因如下:
1)RelativeLayout的测量和布局工作远比LinearLayout复杂,所以LinearLayout效率更高。
2)LinearLayout的weight属性在不同尺寸的设备下,适配效果是非常好的。而且LinearLayout要么就是横着排,要么就是竖着排,不会出现两个子控件重叠的情况(当然这要看需求)
3)RelaiveLayout经常出现一个问题就是,在这个设备上好好的,在另一个设备上重叠了。这种情况至少在LinearLayout下不会出现,显示不下大不了滚动。
4)有些布局用RelaiveLayout的子控件的底部的padding、margin无效(听到同事给的一个解释说:layout_marginBottom和layout_alignParentBottom一起使用的时候layout_alignParentBottom的优先级高于layout_marginBottom所以layout_alignParentBottom属性覆盖了layout_marginBottom的效果。我试了一些,确实是的,但是应该不少人不知道这个冷门的小知识点吧)
当然咯,RelaiveLayout还有更强的灵活性,大家看着用吧。
5.使用静态的Handler,并且使用弱引用,防止内存泄露,并且要考虑Activity被回收的情况,下面写一段代码片段以弊之。
public class MainActivity extends FragmentActivity {
static class MyHandler extends Handler {
private WeakReference<MainActivity> wrfActivity;
public MyHandler(MainActivity wrfActivity) {
super();
this.wrfActivity = new WeakReference<MainActivity>(wrfActivity);
}
@Override
public void handleMessage(Message msg) {
MainActivity mainActivity = wrfActivity.get();
/** 为null说明activity被回收了或者异常重启了,则不处理消息 */
if (null == mainActivity) {
removeCallbacksAndMessages(null);
return;
}
mainActivity.handleMessage(msg);
}
}
public void handleMessage(Message msg) {
/**
* 消息处理块,可以将这中写法封装起来,Activity只重写该函数即可
*/
}
private MyHandler myHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setBackgroundDrawable(null);
setContentView(R.layout.activity_main);
myHandler = new MyHandler(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
/** Activity被销毁的时候,清空消息 */
if (null != myHandler) {
myHandler.removeCallbacksAndMessages(null);
}
}
}
6.务必考虑Activity被回收的情况,重写onSaveInstanceState和onRestoreInstanceState进行数据的保存与恢复工作,如果有数据是在onCreate里面要使用到的,就在onCreate里面恢复。
7.考虑到不同尺寸设备的显示效果,并不是在你手机上显示OK就没问题了,可能其他设备上显示效果很烂,所以务必考虑不同设备上的适配效果。
8.如果布局里面有Listview、Gridview这样的控件,它们的android:layout_width属性应当用match_parent而不是wrap_content。如果是wrap_content的话,会不断的调用适配器的getView()方法去计算高度,如果是match_parent的话,它的测量模式是EXACTLY,不会动态的计算。这是一个小的提高效率的点。并且尝试开启硬件加速使Listview更加流畅。
9.如果涉及到布局之间的包含关系则用merge标签减少布局层级。
上面是一个考虑到以上场景的一个模板
package com.example.androidreview;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MyFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** 设置为true,Activity重启的时候,Fragment不会走onCreate,但是会走onCreateView方法 */
setRetainInstance(true);
}
private View mRootView = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//不为null,则页面是重启
if (null != mRootView) {
/** 做点什么 */
return mRootView;
}
mRootView = getRootView();
return mRootView;
}
private View getRootView() {
TextView tView = new TextView(getContext());
tView.setText("Hello World!");
return tView;
}
}
package com.example.androidreview;
import java.lang.ref.WeakReference;
import java.util.Random;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.widget.TextView;
@SuppressLint("NewApi")
public class MainActivity extends FragmentActivity {
static class MyHandler extends Handler {
private WeakReference<MainActivity> wrfActivity;
public MyHandler(MainActivity wrfActivity) {
super();
this.wrfActivity = new WeakReference<MainActivity>(wrfActivity);
}
@Override
public void handleMessage(Message msg) {
MainActivity mainActivity = wrfActivity.get();
/** 为null说明activity被回收了或者异常重启了,则不处理消息 */
if (null == mainActivity) {
removeCallbacksAndMessages(null);
return;
}
mainActivity.handleMessage(msg);
}
}
public void handleMessage(Message msg) {
/**
* 消息处理块,可以将这中写法封装起来,Activity只重写该函数即可
*/
}
private MyHandler myHandler;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setBackgroundDrawable(null);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
Fragment fragment = getAttachFragment(savedInstanceState);
if (!fragment.isAdded()) {
ft.add(R.id.fl_fragmentlayout, fragment, MyFragment.class.getSimpleName());
ft.commit();
}
myHandler = new MyHandler(this);
mTextView = new TextView(this);
mTextView.setTag("mText");
Random random = new Random();
int show = random.nextInt();
mTextView.setText(show+"");
}
/**
* 如果是异常重启,则恢复原来的Fragment
*
* @param savedInstanceState
* @return
*/
private Fragment getAttachFragment(Bundle savedInstanceState) {
Fragment fragment = null;
if (savedInstanceState != null) {
fragment = getSupportFragmentManager().findFragmentByTag(MyFragment.class.getName());
}
return fragment != null ? fragment : new MyFragment();
}
/**
* 异常重启的时候保存数据
* @param arg0
*/
@Override
protected void onSaveInstanceState(Bundle arg0) {
super.onSaveInstanceState(arg0);
arg0.putString((String) mTextView.getTag(), mTextView.getText().toString().trim());
}
/**
* 恢复的时候还原数据
* @param savedInstanceState
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if(mTextView != null)
{
mTextView.setText(savedInstanceState.getString((String) mTextView.getTag(),""));
}
}
@Override
protected void onDestroy() {
super.onDestroy();
/** Activity被销毁的时候,清空消息 */
if (null != myHandler) {
myHandler.removeCallbacksAndMessages(null);
}
}
}
仅供参考。