Android 新增一个页面注意事项

在新添加一个页面的时候,需要全局性考虑,并不仅仅是写一个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);
        }
    }
}

仅供参考。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值