http:://developer.android.com/design/index.html  //design guideline

xmlns:android = "http://schema.android.com/apk/res/android"

0、时刻记得维护好你的AndroidManifest.xml,很多错误就是它搞的...

     所有拥有id的View都能在横竖屏切换等变换之后保留其状态。

    Refactor->Extract->Method能将代码提取为方法。

1、将所有的String放到values/string.xml文件中

2、public static Toast makeText ( Context context, int resId, int duration )

    其中第一个,如果是在监听器的匿名类中,记住不能直接this,而是activity.this,因为此时的this是指该匿名类

3、MVC

M:modle  此层封装、管理数据对象,一般用class(p.s. UUID可以产生不重复的id)

C :controller 此层连接二者,是应用的逻辑层。处理view发送来的用户行为,再在modle中做相应的操作,包括数据的更改以及传输。一般是Activity啥的Java文件

V : view  此层处理视图界面,以及对用户行为的反应(比如点击事件),一般是从layout.xml 布局文件中加载来的

4、在变量的命名传统中,我们一般加上前缀m,对于static变量,一般加上前缀s

5、图片、xml文件资源名字必须小写

6、在生命周期的方法里边,注意先super.XXX()再做其他事情

7、Activity生命周期

    由OS掌控,在paused(仍然可见)或者stopped的状态下有可能被回收掉,这时候onSaveInstanceState(...)就会被调用,这个Bundle是被OS记录下来的(activity record),这个activity record会存留在OS中,即使整个应用都已经被kill掉了。只有在用户按下Back(用户自己想关闭)、手机Reboot或者说隔了很长很长时间时,这个activity record也会被扔掉。

8、调试

    1. 直接看报错,调到错误处

    2. 在你觉得有问题的函数里边,使用Log.d(String tag, String message, Throwable) , 第三个参数直接new Exception(),这样的话在logcat中能显示你是在哪里调用这个函数的(但要注意不要在太多地方用,否则logcat会爆炸)

    3. 使用断点

    4. 使用Lint,这个很厉害的

    5. 当R文件出错冒红时,尝试一下方法

        1. 检查xml文件中有没有打错字啥的

        2. Build -> Clean Project 或者 Sync Project

        3. 好好看看Lint的警告

        4. 弃疗.......

9、 开启新的Activity时使用被开启的Activity的public static 函数

    e.g.    

        public static Intent newIntent(Context fromContext, Bundle data)

        {

            Intnet intent = new Intent(fromContext, selfActivity.class);

            intent.putExtras(data);//如果没用到bundle,需要传入key,也是在被打开的Activity处声明private static final的String key,记得在Activity的开头处写明需要什么参数及其用途

            return intent;

        }

        有返回值的也是类似

10、在横竖屏切换的时候,若横竖屏的控件啥的不一样,记住在代码中要进行判断(该控件是否为空,etc)

11、ActivityManager管理一个Activity的栈,存在于OS中,在它看来任何应用中的Activity都是一样的

12、版本兼容控制

在app/build.gradle,更改后需要Sync一下gradle(一般似乎也是会自动Sync的)

    Minimum SDK version:设备的版本低于它时,拒绝安装(当使用高于此版本的功能时,一般Lint是会提醒的)

    Target SDK version:顾名思义

    Compile SDK version:这个决定了Compiler用的是什么版本的SDK

判断版本是否满足要求:

    if(Build.VERSION.SDK_INT >= bUILD.VERSION_CODES.LOLLIPOP)

    {...}//前者为设备的版本,第二个为用到的功能的版本,具体要看是哪个功能(目前最新为LOLLIPOP


13、关于Fragment

    1. 所有界面(包括M与V的连接)都用Fragment来写,不要用Activity(继承自FragmentActivity,它只用于把Fragment召唤出来,而Fragment的生命周期也是由Activity掌控的,一般用FrameLayout来做container),原因:不这样强迫自己,你永远不会想要去用Fragment的,因为它确实很蛋疼——一个Activity不要使用超过3个Fragment,否则你的代码会乱得让你分分钟想自行了断(小的组成部分直接用控件就好了)


    2. 用android.support.v4.app.Fragment而不是内置的那个(android.app.Fragment),因为support库更新更快。注意要用support library的话,需要在Project Structure哪里添加dependency。(v4的4说明支持的最低版本是4,而Fragment本身是到API 11才出来的,这也说明用support library的话向前兼容性更强)


    3. 一个Fragment同样包含一个layout文件和一个Java文件(继承自Fragment,有俩版本,别选错),跟Activity很像,而且Fragment也是有onSaveInstanceState(Bundle)的。FragmentManager用getSupportFragmentManager()。


    4. 其生命周期基本上是与Activity的一样的

        public View onCreatView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

            第二个参数是放置该Fragment的容器。

        LayoutInflater.inflate(...)

            第一个参数是布局文件的id,第二个是container,第三个是选择是否在此时就把这个Fragment给放上去(一般选false,因为我们是动态地放上去的)


    5. 可以用fragmentManager.findFragmentById(container)来找出这个容器里放置的Fragment。


    6. 当重复性的创建开启fragment(或者其他事情)的时候,考虑创建一个abstract class,这样简洁很多


    7. 两个Activity之间的Fragment的传值可以:

        1. 直接借助其寄居的Activity来实现,用getActivity(),但是这样的话,接受值的Fragment必须要使用其寄居的Activity的key才能获取,这样破坏了Fragment的encapsulation;

        2. 这种方法适用于任意两个Fragment(一个或两个Activity中皆可),我们将使用Fragment的argument。在接受参数的Fragment的构造函数中,就规定好要传入一个bundle,调用Fragment.setArguments(Bundle),然后返回该Fragment实例。取出时则用getArguments()。


    8. 同一个Activity之间的Fragment的传值可以:

        1. 仍然是使用Intent,以及Fragment.onActivityResult(...)。

        2. 在第一个Fragment中就掉用第二个Fragment的setTargetFragment(第一个.this,requestCode),将第二个目标制定为自己,这个很像startActivityForResult(...)。而在第二个Fragment中将结果发送回来时要自己手动调用getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);


14、dp是density-independent pixel,即大小是一定的;

        sp是scale-independent pixel,多考虑了user的字体大小,所以一般用它来描述text的size

        

15、先把同一级控件都分配好空间,剩下的控件再用于layout_weight的分配


16、使用单例模式是很好的。将类的constructor设为private,只在类的public static的获取单例的函数中调用。当然啦,这个单例就是我们的类,要设为private static的。但是不要滥用单例来存储全局变量,什么都放进去会让你的代码跟shi一样,让人搞不懂你那变量是用在哪里干什么的,也就是说破坏了封装性。


17、RecyclerView:一个很棒的呈现列表的东西。它能回收利用资源,比如说,我们要展示100个item,那我们其实没必要为100个item都创建View,只需要屏幕上呈现的那些有View就好了——RecyclerView就给我们做到了这点,它回收利用那些已经跑出屏幕的那些item的View (实际上ListView也可以回收,但是太老了,而且不灵活,无动画,修改数据很麻烦)

    ViewHolder:作为item的View的存放者

        e.g.

            public class ListItemHolder extends RecyclerView.ViewHolder

            {

                public ImageView mPicture;


                public ListItemHolder(View itemView)//这里这个View就是由Adapter给的,布局文件

                {

                    super(view);

                    mPicture = (ImageView)itemView.findViewById(R.id.xxx);

                }

            }

    

    Adapter:作为RecyclerView与其所展示的data之间的Controller,它做了两点:一是create the necessary ViewHolders,二是将ViewHolder与modle层的数据相连接。类的定义是:private class xxxAdapter extends RecycleView.Adapter{...}作为RecycleView的内部类.

    当数据被改动需要重新加载时,使用Adapter.notifyDataSetChanged(),但这个是全部加载;使用notigyItemChanged(int position)就只更新一个。


    首先,RecyclerView向Adapter询问一共多少项,getItemCount();接着,它调用Adapter的createViewHolder(ViewGroup parent,int)创建一个ViewHolder以及一个要展示的view(如果要自定义View的话就在这里把布局文件传进去,

    return new xxxViewHolder( LayoutInflater.from( getActivity() ).inflater(布局,parent ,false);

此时view中尚未有数据),当create出来的ViewHolder足够用时,就不再create了,回收即可;最后,它调用了onBindViewHolder(ViewHolder,int position),然后Adapter根据这个position找到数据将其填充到刚刚那个view中去。

    注意,RecyclerView在使用前必须先调用setLayoutManager(...),否则崩溃。这个LayoutManager就是被叫来把item放到合适位置上的。


18、ViewPager

    不使用FrameLayout了,转用ViewPager来承载Fragment。ViewPager也是需要配置Adapter的,一般使用PagerAdapter的子类FragmentStatePagerAdapter(其构造函数需要传入一个FragmentManager作为参数...),并重写getCount()和getItem(int)——返回一个Fragment  这两个方法。

    找到你要展示的那一项,然后调用ViewPager.setCurrentItem(int index),否则每次都从头开始。


    当你想要让ViewPager显示非Fragment的时候,你就需要自己实现PagerAdapter了。主要是3个方法:

        1、public Object instantiateItem(ViewGroup container, int position)

        2、public void destroyItem(ViewGroup container, int position, Object object)

        3、public abstract boolean isViewFromObject(View view, Object object)


19、AlertDialog(Dialog.AlertDialog的一个子类)

    最好是将这个AlertDialog作为一个DialogFragment来实现(这样的话能将这个Dialog交给FragmentManager去管理,切换屏幕方向什么的之后它也能被重新create)——重写其onCreateDialog(Bundle)方法。再显现这个DialogFragment的时候,要调用其实例的show(FragmentManager,String tag)方法。如果使用onCreateView(Bundle),则需要自己实现全部布局,但是可以使用startActivityForResult(...)来传参。

    在Dialog中调用setView(View),可以设置Dialog中间部分的视图。