十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
http:://developer.android.com/design/index.html //design guideline
xmlns:android = "http://schema.android.com/apk/res/android"
0、時(shí)刻記得維護(hù)好你的AndroidManifest.xml,很多錯(cuò)誤就是它搞的...
所有擁有id的View都能在橫豎屏切換等變換之后保留其狀態(tài)。
Refactor->Extract->Method能將代碼提取為方法。
1、將所有的String放到values/string.xml文件中
2、public static Toast makeText ( Context context, int resId, int duration )
其中第一個(gè),如果是在監(jiān)聽(tīng)器的匿名類中,記住不能直接this,而是activity.this,因?yàn)榇藭r(shí)的this是指該匿名類
3、MVC
M:modle 此層封裝、管理數(shù)據(jù)對(duì)象,一般用class(p.s. UUID可以產(chǎn)生不重復(fù)的id)
C :controller 此層連接二者,是應(yīng)用的邏輯層。處理view發(fā)送來(lái)的用戶行為,再在modle中做相應(yīng)的操作,包括數(shù)據(jù)的更改以及傳輸。一般是Activity啥的Java文件
V : view 此層處理視圖界面,以及對(duì)用戶行為的反應(yīng)(比如點(diǎn)擊事件),一般是從layout.xml 布局文件中加載來(lái)的
4、在變量的命名傳統(tǒng)中,我們一般加上前綴m,對(duì)于static變量,一般加上前綴s
5、圖片、xml文件資源名字必須小寫(xiě)
6、在生命周期的方法里邊,注意先super.XXX()再做其他事情
7、Activity生命周期
由OS掌控,在paused(仍然可見(jiàn))或者stopped的狀態(tài)下有可能被回收掉,這時(shí)候onSaveInstanceState(...)就會(huì)被調(diào)用,這個(gè)Bundle是被OS記錄下來(lái)的(activity record),這個(gè)activity record會(huì)存留在OS中,即使整個(gè)應(yīng)用都已經(jīng)被kill掉了。只有在用戶按下Back(用戶自己想關(guān)閉)、手機(jī)Reboot或者說(shuō)隔了很長(zhǎng)很長(zhǎng)時(shí)間時(shí),這個(gè)activity record也會(huì)被扔掉。
8、調(diào)試
1. 直接看報(bào)錯(cuò),調(diào)到錯(cuò)誤處
2. 在你覺(jué)得有問(wèn)題的函數(shù)里邊,使用Log.d(String tag, String message, Throwable) , 第三個(gè)參數(shù)直接new Exception(),這樣的話在logcat中能顯示你是在哪里調(diào)用這個(gè)函數(shù)的(但要注意不要在太多地方用,否則logcat會(huì)爆炸)
3. 使用斷點(diǎn)
4. 使用Lint,這個(gè)很厲害的
5. 當(dāng)R文件出錯(cuò)冒紅時(shí),嘗試一下方法
1. 檢查xml文件中有沒(méi)有打錯(cuò)字啥的
2. Build -> Clean Project 或者 Sync Project
3. 好好看看Lint的警告
4. 棄療.......
9、 開(kāi)啟新的Activity時(shí)使用被開(kāi)啟的Activity的public static 函數(shù)
e.g.
public static Intent newIntent(Context fromContext, Bundle data)
{
Intnet intent = new Intent(fromContext, selfActivity.class);
intent.putExtras(data);//如果沒(méi)用到bundle,需要傳入key,也是在被打開(kāi)的Activity處聲明private static final的String key,記得在Activity的開(kāi)頭處寫(xiě)明需要什么參數(shù)及其用途
return intent;
}
有返回值的也是類似
10、在橫豎屏切換的時(shí)候,若橫豎屏的控件啥的不一樣,記住在代碼中要進(jìn)行判斷(該控件是否為空,etc)
11、ActivityManager管理一個(gè)Activity的棧,存在于OS中,在它看來(lái)任何應(yīng)用中的Activity都是一樣的
12、版本兼容控制
在app/build.gradle,更改后需要Sync一下gradle(一般似乎也是會(huì)自動(dòng)Sync的)
Minimum SDK version:設(shè)備的版本低于它時(shí),拒絕安裝(當(dāng)使用高于此版本的功能時(shí),一般Lint是會(huì)提醒的)
Target SDK version:顧名思義
Compile SDK version:這個(gè)決定了Compiler用的是什么版本的SDK
判斷版本是否滿足要求:
if(Build.VERSION.SDK_INT >= bUILD.VERSION_CODES.LOLLIPOP)
{...}//前者為設(shè)備的版本,第二個(gè)為用到的功能的版本,具體要看是哪個(gè)功能(目前最新為L(zhǎng)OLLIPOP
13、關(guān)于Fragment
1. 所有界面(包括M與V的連接)都用Fragment來(lái)寫(xiě),不要用Activity(繼承自FragmentActivity,它只用于把Fragment召喚出來(lái),而Fragment的生命周期也是由Activity掌控的,一般用FrameLayout來(lái)做container),原因:不這樣強(qiáng)迫自己,你永遠(yuǎn)不會(huì)想要去用Fragment的,因?yàn)樗_實(shí)很蛋疼——一個(gè)Activity不要使用超過(guò)3個(gè)Fragment,否則你的代碼會(huì)亂得讓你分分鐘想自行了斷(小的組成部分直接用控件就好了)
2. 用android.support.v4.app.Fragment而不是內(nèi)置的那個(gè)(android.app.Fragment),因?yàn)閟upport庫(kù)更新更快。注意要用support library的話,需要在Project Structure哪里添加dependency。(v4的4說(shuō)明支持的最低版本是4,而Fragment本身是到API 11才出來(lái)的,這也說(shuō)明用support library的話向前兼容性更強(qiáng))
3. 一個(gè)Fragment同樣包含一個(gè)layout文件和一個(gè)Java文件(繼承自Fragment,有倆版本,別選錯(cuò)),跟Activity很像,而且Fragment也是有onSaveInstanceState(Bundle)的。FragmentManager用getSupportFragmentManager()。
4. 其生命周期基本上是與Activity的一樣的
public View onCreatView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
第二個(gè)參數(shù)是放置該Fragment的容器。
LayoutInflater.inflate(...)
第一個(gè)參數(shù)是布局文件的id,第二個(gè)是container,第三個(gè)是選擇是否在此時(shí)就把這個(gè)Fragment給放上去(一般選false,因?yàn)槲覀兪莿?dòng)態(tài)地放上去的)
5. 可以用fragmentManager.findFragmentById(container)來(lái)找出這個(gè)容器里放置的Fragment。
6. 當(dāng)重復(fù)性的創(chuàng)建開(kāi)啟fragment(或者其他事情)的時(shí)候,考慮創(chuàng)建一個(gè)abstract class,這樣簡(jiǎn)潔很多
7. 兩個(gè)Activity之間的Fragment的傳值可以:
1. 直接借助其寄居的Activity來(lái)實(shí)現(xiàn),用getActivity(),但是這樣的話,接受值的Fragment必須要使用其寄居的Activity的key才能獲取,這樣破壞了Fragment的encapsulation;
2. 這種方法適用于任意兩個(gè)Fragment(一個(gè)或兩個(gè)Activity中皆可),我們將使用Fragment的argument。在接受參數(shù)的Fragment的構(gòu)造函數(shù)中,就規(guī)定好要傳入一個(gè)bundle,調(diào)用Fragment.setArguments(Bundle),然后返回該Fragment實(shí)例。取出時(shí)則用getArguments()。
8. 同一個(gè)Activity之間的Fragment的傳值可以:
1. 仍然是使用Intent,以及Fragment.onActivityResult(...)。
2. 在第一個(gè)Fragment中就掉用第二個(gè)Fragment的setTargetFragment(第一個(gè).this,requestCode),將第二個(gè)目標(biāo)制定為自己,這個(gè)很像startActivityForResult(...)。而在第二個(gè)Fragment中將結(jié)果發(fā)送回來(lái)時(shí)要自己手動(dòng)調(diào)用getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);
14、dp是density-independent pixel,即大小是一定的;
sp是scale-independent pixel,多考慮了user的字體大小,所以一般用它來(lái)描述text的size
15、先把同一級(jí)控件都分配好空間,剩下的控件再用于layout_weight的分配
16、使用單例模式是很好的。將類的constructor設(shè)為private,只在類的public static的獲取單例的函數(shù)中調(diào)用。當(dāng)然啦,這個(gè)單例就是我們的類,要設(shè)為private static的。但是不要濫用單例來(lái)存儲(chǔ)全局變量,什么都放進(jìn)去會(huì)讓你的代碼跟shi一樣,讓人搞不懂你那變量是用在哪里干什么的,也就是說(shuō)破壞了封裝性。
17、RecyclerView:一個(gè)很棒的呈現(xiàn)列表的東西。它能回收利用資源,比如說(shuō),我們要展示100個(gè)item,那我們其實(shí)沒(méi)必要為100個(gè)item都創(chuàng)建View,只需要屏幕上呈現(xiàn)的那些有View就好了——RecyclerView就給我們做到了這點(diǎn),它回收利用那些已經(jīng)跑出屏幕的那些item的View (實(shí)際上ListView也可以回收,但是太老了,而且不靈活,無(wú)動(dòng)畫(huà),修改數(shù)據(jù)很麻煩)
ViewHolder:作為item的View的存放者
e.g.
public class ListItemHolder extends RecyclerView.ViewHolder
{
public ImageView mPicture;
public ListItemHolder(View itemView)//這里這個(gè)View就是由Adapter給的,布局文件
{
super(view);
mPicture = (ImageView)itemView.findViewById(R.id.xxx);
}
}
Adapter:作為RecyclerView與其所展示的data之間的Controller,它做了兩點(diǎn):一是create the necessary ViewHolders,二是將ViewHolder與modle層的數(shù)據(jù)相連接。類的定義是:private class xxxAdapter extends RecycleView.Adapter
當(dāng)數(shù)據(jù)被改動(dòng)需要重新加載時(shí),使用Adapter.notifyDataSetChanged(),但這個(gè)是全部加載;使用notigyItemChanged(int position)就只更新一個(gè)。
首先,RecyclerView向Adapter詢問(wèn)一共多少項(xiàng),getItemCount();接著,它調(diào)用Adapter的createViewHolder(ViewGroup parent,int)創(chuàng)建一個(gè)ViewHolder以及一個(gè)要展示的view(如果要自定義View的話就在這里把布局文件傳進(jìn)去,
return new xxxViewHolder( LayoutInflater.from( getActivity() ).inflater(布局,parent ,false);
此時(shí)view中尚未有數(shù)據(jù)),當(dāng)create出來(lái)的ViewHolder足夠用時(shí),就不再create了,回收即可;最后,它調(diào)用了onBindViewHolder(ViewHolder,int position),然后Adapter根據(jù)這個(gè)position找到數(shù)據(jù)將其填充到剛剛那個(gè)view中去。
注意,RecyclerView在使用前必須先調(diào)用setLayoutManager(...),否則崩潰。這個(gè)LayoutManager就是被叫來(lái)把item放到合適位置上的。
18、ViewPager
不使用FrameLayout了,轉(zhuǎn)用ViewPager來(lái)承載Fragment。ViewPager也是需要配置Adapter的,一般使用PagerAdapter的子類FragmentStatePagerAdapter(其構(gòu)造函數(shù)需要傳入一個(gè)FragmentManager作為參數(shù)...),并重寫(xiě)getCount()和getItem(int)——返回一個(gè)Fragment 這兩個(gè)方法。
找到你要展示的那一項(xiàng),然后調(diào)用ViewPager.setCurrentItem(int index),否則每次都從頭開(kāi)始。
當(dāng)你想要讓ViewPager顯示非Fragment的時(shí)候,你就需要自己實(shí)現(xiàn)PagerAdapter了。主要是3個(gè)方法:
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的一個(gè)子類)
最好是將這個(gè)AlertDialog作為一個(gè)DialogFragment來(lái)實(shí)現(xiàn)(這樣的話能將這個(gè)Dialog交給FragmentManager去管理,切換屏幕方向什么的之后它也能被重新create)——重寫(xiě)其onCreateDialog(Bundle)方法。再顯現(xiàn)這個(gè)DialogFragment的時(shí)候,要調(diào)用其實(shí)例的show(FragmentManager,String tag)方法。如果使用onCreateView(Bundle),則需要自己實(shí)現(xiàn)全部布局,但是可以使用startActivityForResult(...)來(lái)傳參。
在Dialog中調(diào)用setView(View),可以設(shè)置Dialog中間部分的視圖。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。