mergeandroid
『壹』 Android開發之合並文件的幾種方式
不同文件的文件頭是不一樣的,所以在合並的時候根據不同文件相應的減去合並文件的文件頭。
步驟一:獲取要合並的文件及創建合並後保存的文件
java">/**用於存放要合並的文件的集合**/
List<File>tempFiles=newArrayList<File>();
/**合並之後的文件**/
FilefinalFile;
/**
*創建用於合並之後的文件
*@paramisTempFile是否為臨時文件
*@returnsoundFileFile
**/
privateFilegetFile(booleanisTempFile){
//TODOAuto-generatedmethodstub
finalFile=null;
if(!Environment.getExternalStorageState().
equals(Environment.MEDIA_MOUNTED)){
Log.w(「Waring」,「檢測到你的手機沒有插入SD卡,請插入SD後再試!」);
}
//獲取系統的24小時制時間作為文件名(HH為24小時制,hh為12小時制)
=newSimpleDateFormat(
「yyyy-MM-dd-HH-mm-ss」,Locale.getDefault());
StringfileName=simpleDateFormat.format(newDate())+」.amr」;
if(isTempFile){//如果是臨時文件
fileName=」temp」+fileName;
}
try{
FileparentFile=newFile(Environment.getExternalStorageDirectory()
.getCanonicalFile()+」/」+」Recorder」);
if(!parentFile.exists()||parentFile==null){//如果目錄不存在
parentFile.mkdirs();//創建parentFile目錄
}
finalFile=newFile(parentFile,fileName);
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returnfinalFile;
}
步驟二:合並文件
方式一:通過FileOutputStream、與FileInputStream方式
/**
*通過FileOutputStream、與FileInputStream方式
*將多個文件進行合並,並刪除原文件
**/
publicvoidmergeFiles1(){
//TODOAuto-generatedmethodstub
if(tempFiles.isEmpty())return;//如果還沒錄制則,不進行合並
FilerealFile=getFile(false);
try{
FileOutputStreamfos=newFileOutputStream(realFile);
for(inti=0;i<tempFiles.size();i++){//遍歷tempFiles集合,合並所有臨時文件
FileInputStreamfis=newFileInputStream(tempFiles.get(i));
byte[]tmpBytes=newbyte[fis.available()];
intlength=tmpBytes.length;//文件長度
//頭文件
if(i==0){
while(fis.read(tmpBytes)!=-1){
fos.write(tmpBytes,0,length);
}
}
//之後的文件,去掉頭文件就可以了.amr格式的文件的頭信息為6位元組
else{
while(fis.read(tmpBytes)!=-1){
fos.write(tmpBytes,6,length-6);
}
}
fos.flush();
fis.close();
}
fos.close();//所有的文件合並結束,關閉輸出流
Log.i(「info」,「此次錄音文件:」+realFile.getName()+」已保存到:」+
realFile.getAbsolutePath()+」目錄下」);
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
//刪除合並過的臨時文件
for(Filefile:tempFiles){
if(file.exists()){
file.delete();
}
}
}
方式二:通過FileChannel方式
/**
*通過FileChannel方式
**/
publicvoidmergeFiles2(){
FilerealFile=getFile(false);
FileChannelmFileChannel;
try{
FileOutputStreamfos=newFileOutputStream(realFile);
mFileChannel=fos.getChannel();
FileChannelinFileChannel;
for(Filefile:tempFiles){
inFileChannel=newFileInputStream(file).getChannel();
//下面應該根據不同文件減去相應的文件頭(這里沒有剪去文件頭,實際應用中應當減去)
inFileChannel.transferTo(0,inFileChannel.size(),mFileChannel);
inFileChannel.close();
}
fos.close();
mFileChannel.close();
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
方式三:通過RandomAccessFile方式
/**
*通過RandomAccessFile方式
**/
publicvoidmergeFiles3(){
try{
FilerealFile=getFile(false);
FileOutputStreamfos=newFileOutputStream(realFile);
RandomAccessFilera=null;
for(inti=0;i<tempFiles.size();i++){
ra=newRandomAccessFile(tempFiles.get(i),「r」);
if(i!=0){
ra.seek(6);//跳過amr文件的文件頭
}
byte[]buffer=newbyte[1024*8];
intlen=0;
while((len=ra.read(buffer))!=-1){
fos.write(buffer,0,len);
}
}
ra.close();
fos.close();
}catch(Exceptione){
e.printStackTrace();
}
}
『貳』 android 除了include還有其他復用布局的方法么
盡管Android通過內置了各種各樣的控制項提供了微小、可復用的交互性元素,也許你需要復用較大的
組件 ---- 某些特定布局文件 。為了更有效率復用的布局文件,你可以使用<include />以及<merge />
標簽將其他的布局文件加入到當前的布局文件中。
復用布局文件是一種特別強大的方法,它允許你創建可復用性的布局文件。例如,一個包含「Yse」or「No」的
Button面版,或者是帶有文字說明的 Progressbar。復用布局文件同樣意味著你應用程序里的任何元素都能從
繁雜的布局文件提取出來進行單獨管理,接著你需要做的只是加入這些獨立的布局文件(因為他們都是可復用地)。
因此,當你通過自定義View創建獨立的UI組件時,你可以復用布局文件讓事情變得更簡單。
1、創建一個可復用性的布局文件
如果你已經知道復用布局的」面貌」,那麼創建、定義布局文件( 命名以」.xml」為後綴)。例如,這里是一個來自
G- Kenya codelab 的布局文件,定義了在每個Activity中都要使用的一個自定義標題 (titlebar.xml):由於這些
可復用性布局被添加至其他布局文件中,因此,它的每個根視圖(root View)最好是精確(exactly)的。
[java] view plainprint?
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width=」match_parent」
android:layout_height="wrap_content"
android:background="@color/titlebar_bg">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/gafricalogo" />
</FrameLayout>
2、使用<include />標簽
在需要添加這些布局的地方,使用<include />標簽 。 例如,下面是一個來自G-Kenya codelab的布局文件,
它復用了上面列出的「title bar」文件, 該布局文件如下:
[java] view plainprint?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width=」match_parent」
android:layout_height=」match_parent」
android:background="@color/app_bg"
android:gravity="center_horizontal">
<include layout="@layout/titlebar"/>
<TextView android:layout_width=」match_parent」
android:layout_height="wrap_content"
android:text="@string/hello"
android:padding="10dp" />
...
</LinearLayout>
你也可以在<include />節點中為被添加的布局文件的root View定義特別標識,重寫所有layout參數即可(任何
以「android:layout_」為前綴的屬性)。例如:
[java] view plainprint?
<include android:id=」@+id/news_title」
android:layout_width=」match_parent」
android:layout_height=」match_parent」
layout=」@layout/title」/>
3、使用<merge />標簽
當在布局文件中復用另外的布局時, <merge />標簽能夠在布局層次消除多餘的視圖元素。例如,如果你的
主布局文件是一個垂直地包含兩個View的LinearLayout,該布局能夠復用在其他布局中,而對任意包含兩個View的
布局文件都需要一個root View(否則, 編譯器會提示錯誤)。然而,在該可復用性布局中添加一個LinearLayout
作為root View,將會導致一個垂直的LinearLayout包含另外的垂直LinearLayout。內嵌地LinearLayout只能減緩
UI效率,其他毫無用處可言。
該復用性布局利用.xml呈現如下:
[java] view plainprint?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width=」match_parent」
android:layout_height=」match_parent」
android:background="@color/app_bg"
android:gravity="horizontal">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/add"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/delete"/>
</LinearLayout>
為了避免冗餘的布局元素,你可以使用<merge />作為復用性布局文件地root View 。例如:
使用<merge />標簽的布局文件:
[java] view plainprint?
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/add"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/delete"/>
</merge>
現在,當你添加該布局文件時(使用<include />標簽),系統忽略< merge />節點並且直接添加兩個Button去
取代<include />節點。
『叄』 Android布局優化的幾種方式
1. include/merge
布局優化中常常用到include/merge標簽,include的含義類似C代碼中的include,意思是直接把指定布局片段包含進當前的布局文件。include適用於多個布局文件中存在相同的xml片段,比如說相同的標題欄、相同的廣告欄、相同的進度欄等等。
2. ViewStub
在一個頁面上根據不同條件展示不同的控制項,我們常常會設置控制項的可視屬性,比如調用指定控制項的setVisibility方法,若需展示則設置View.VISIBLE,若需隱藏則設置View.GONE。不過gone的控制項只是看不到罷了,實際UI渲染時還是會被載入。要想事先不載入,在條件符合時才載入,就得用到標簽ViewStub。
3. style樣式
樣式在res/values/styles.xml中定義,它適用於下面幾種情況:
1、布局文件中存在多個具有相同風格的控制項,比如說統一的文本框TextView,都是白底黑字、中號字體、居中顯示,這時我們便可在styles.xml定義一種文本樣式,然後在各文本框處聲明它的style屬性。好處一個是減少了布局文件的大小,另一個是方便以後統一修改風格。
2、某些控制項在代碼中聲明時需要手工指定style,例如自定義對話框需要在構造函數中指定樣式;另一個例子是彈窗PopupWindow在設置伸縮動畫方法setAnimationStyle時需要指定動畫樣式。
3、定義頁面的主題風格,然後應用到Activity頁面。代碼中設置主題可通過「setTheme(R.style.)」完成,布局中設置可在AndroidManifest.xml的activity節點下添加theme屬性,如「android:theme=」@style/「」。
4. Theme主題
主題是一種特殊的樣式,主題專用於頁面,而樣式一般運用於控制項。主題定義一般放在themes.xml,樣式定義一般放在styles.xml。
Android定義了一些系統主題,完整定義的參見sdk自帶的themes.xml,常用的幾種說明如下:
Theme.NoTitleBar : 不顯示標題欄,即隱藏ActionBar
Theme.Light : 白色背景
Theme.Holo : 淺灰背景
Theme.Black : 黑色背景
Theme.Wallpaper : 壁紙
Theme.Translucent : 透明背景
Theme.Dialog : 對話框
Theme.Panel : 平板
Theme.InputMethod : 輸入法
Theme.SearchBar : 搜索框
『肆』 Ubuntu下編譯Android4.2.1源碼已ok,但是merge上自己的android bsp就編譯不過了
bsp單獨用Android.mk來編譯,別放入系統里,先看看
『伍』 怎樣android的布局優化載入
下面介紹幾種切實有效的方式:
merge
顧名思義,就是合並、融合的意思。使用它可以有效的將某些符合條件的多餘的層級優化掉。使用merge的場合主要有兩處:
(1)自定義View中使用,父元素盡量是FrameLayout,當然如果父元素是其他布局,而且不是太復雜的情況下也是可以使用的
(2)Activity中的整體布局,根元素需要是FrameLayout
ViewStub
(1)ViewStub只能Inflate一次,之後ViewStub對象會被置為空。按句話說,某個被ViewStub指定的布局被Inflate後,就不能夠再通過ViewStub來控制它了。所以它不適用 於需要按需顯示隱藏的情況。
(2)ViewStub只能用來Inflate一個布局文件,而不是某個具體的View,當然也可以把View寫在某個布局文件中。如果想操作一個具體的view,還是使用visibility屬性吧。
(3) VIewStub中不能嵌套merge標簽。(前面好像說過)
不過這些確定都無傷大雅,我們還是能夠用ViewStub來做很多事情。include
製造這個標簽純碎是為了布局重用,在項目中通常會存在一些布局公用的部分,比如自義標題,我們不需要把一份代碼Ctrl C, Ctrl V的到處都是,嚴重違背程序簡潔化、模塊兒化的設計思想
『陸』 android中include和merge標記的區別和使用
include和merge標記的作用主要是為了解決layout的重用問題。
比如我們有三四個Activity但是他們都要用到同一個樣式的標題欄,雖然我們把一樣的代碼個三四遍也沒關系,但實在是太丑了,而且效率太低,如果這個標題欄要改樣式,你豈不是要去三四個地方分別改動。
為了解決這個問題,android中有了include和merge標記
以下為標題欄的layout文件titlebar.xml 我們將使用Include標記重用這個文件
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width=」match_parent」
android:layout_height="wrap_content"
android:background="@color/titlebar_bg">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/gafricalogo" />
</FrameLayout>
那麼在那三四個activity中你可以適用Include標記
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width=」match_parent」
android:layout_height=」match_parent」
android:gravity="center_horizontal">
<include layout="@layout/titlebar"/>
<TextView android:layout_width=」match_parent」
android:layout_height="wrap_content"
android:text="@string/hello" />
...
</LinearLayout>
調用了Include之後,titlebar文件的內容就被完全嵌入到了include所指定的位置。而且你還可以在include中重新更改一些屬性的值,比如
<include android:id=」@+id/news_title」
android:layout_width=」match_parent」
android:layout_height=」match_parent」
layout="@layout/title"/>
原來layout中的wrap_content屬性就被改成了match_parent屬性
再來說一下merge標記
上面的include有一個副作用就是他多套了一層root節點FrameLayout ,使得再構圖的時候會多花費一點時間
如果你不能容忍這個的話那你可以試一下merge標記
titlebar2.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/gafricalogo" />
</merge>
這樣行成的titlebar2文件就少了外層的root節點,merge標記可以直接成為root節點,當titlebar2被include到文件中時,merge標記就會被忽略掉,而直接由裡面的ImageView取代原來include的位置。避免了冗餘的layout。
所以include和merge是配合使用的,不是一個互斥的或者說是平級的關系。
再來說一個在使用這兩個標簽時最容易出現的問題。
經常會有同學在RelativeLayout中使用include標簽
但是卻發現include進來的控制項無法用layout_alignParentBottom="true"之類的標簽來調整。這個真的非常惱火。其實解決方法非常簡單,只要你在include的時候同時重載下layout_width和layout_height這兩個標簽就可以了。如果不重載,任何針對include的layout調整都是無效的!
『柒』 unity 打包報錯:CommandInvokationFailure: Unable to merge android manifests. 怎麼解決
錯誤描述很清楚啊 你配置文件裡面寫的sdk版本用的是25,但是你library使用的是28
修改你配置文件就行了
『捌』 android merge標簽相當於framelayout嗎
1.merge布局 和FrameLayout類似,相同的效果.不同的是 merge布局只能被<include>標簽包含. 或者Activity.setContentView所使用.
當LayoutInflater遇到能被其他layout用<include>包含進去,並不再另外生成ViewGroup容器,本元素也特別有用這個標簽時,它會跳過它,並將<merge />內的元素添加到<merge />的父元素里. Activity能直接使用的原因是Activity的父元素是FrameLayout
2 merge 能被其他layout用<include>包含進去,並不再另外生成ViewGroup容器.就是說,會減少一層layout到達優化layout的目的
限制:
<merge />只能作為XML布局的根標簽使用
· 當Inflate以<merge />開頭的布局文件時,必須指定一個父ViewGroup,並且必須設定attachToRoot為true(參看inflate(int, android.view.ViewGroup, Boolean)方法)。
『玖』 android系統有哪些開發者小技巧
下面是開始Android編程的好方法:
找一些與你想做事情類似的代碼
調整它,嘗試讓它做你像做的事情
經歷問題
使用StackOverflow解決問題
對每個你像添加的特徵重復上述過程。這種方法能夠激勵你,因為你在保持不斷迭代,不經意中你學到了很多。然而,當你發布應用時你還要做一些更深入的事情。
從一些可正常工作的代碼到一個可怕的應用程序是一個巨大的跳躍,相比iOS平台Android更是如此 。當在iOS上發布應用時只是在一個設備上跳躍–你的手機–對很多設備而言都很相似–同樣大小的屏幕,都有很好的硬體,95%上運行相同版本的操作系統。在Android應用中你不會遇到這種情況。
你的程序必須能夠處理一切:從屏幕,處理器,定製的操作系統,API層級以及任何其他的特定設備。
這是我對使Android應用舒服起來的個人建議。
目標屏幕尺寸及解決方法
在Android世界裡目前有超過100種的不同屏幕尺寸,但解決方法也很豐富。為使你的應用適應不同的屏幕配置有兩件事情你需要確定:
你對不同的屏幕尺寸有一個好的布局和結構
你的圖像在不同解析度下工作良好
這些都是獨立的任務,你可能有一個超級的tablet布局,但上面的圖形看起來很糟糕。我們會依次討論他們。
為不同的屏幕而設計
1.通常會用ScrollView 和 ListView 輕松搞定
當我們有一系列不同尺寸的大屏手機時,它們之間最大的不同就是屏幕的高度。因此ScrollView和ListView通常可是有效的工作,雖然有時它們並不能完全覆蓋全部屏幕。在OpenSignal中的Dashboard標簽下我們可以看到所有部件一氣呵成,不存在滑動、對於許多高級類型標簽中,滑動展示並不見得是一件壞事。如果你能夠為你所有的設計匹配到各種屏幕上面去,那麼最好不過。否則,這兩個控制項會讓你用最小的開發代價來保證你的軟體在大多數屏幕上正常展示。
Dashboard style 的設計不需要scroll
2: 使用文件夾. Android 的資源文件夾結構非常強大, 它允許開發者將不同的圖片、字元串、布局文件、外形、顏色這些資源,在api、代碼、屏幕尺寸等部分. 下面是一個例子,展示了在資源文件夾下你可以怎樣做:
在 values-small 文件夾中存放了一個 bools.xml 文件, 文件中有如下幾行代碼:
<resources>
<bool name="small_screen">true</bool>
</resources>
在代碼中我可這樣引用:
if(getResources().getBoolean(R.bool.small_screen)){
getSupportActionBar().hide();
}
在小尺寸設備中boolean值將置為true 我此時將因此ActionBar來節省空間. 這段代碼正是非凡的ActionBarSherlock 擴展庫中的一部分,稍後再詳細介紹. 在values-sw360dp文件夾中,存放對應屏幕寬於360dp的資源文件。與上面相同的位置,有如下代碼
<resources>
<bool name="small_screen">false</bool>
</resources>
對於大屏幕而言,ActionBar就置為了顯示狀態.
我不需要將 bools.xml 文件放入 values-sw400dp文件夾中, 因為操作系統會自動按相應路徑搜索. 例如一個設備寬 600dp (600/160=3.75 英寸, 這就是我們通常所說的7片裝) 操作系統會在values-sw600dp 和其包含的的文件夾中搜索 bools.xml 文件, 若沒有找到則搜索 values-sw400dp 文件夾,在搜索 values-sw360dp 文件夾以此類推.
建議3:160dp = 1英寸。320 dp = 2英寸。dp = dip
建議4:你可以用這些目錄結構技巧來應付所有資源類型,比如你的XML布局用指定的系統目錄名稱
來解決這個問題,如:layout-sw360dp目錄可以匹配目標寬是360dp的機器。如果你也要支持橫豎屏布局切換的話,可以用如下目錄:
layout-sw360dp-land
layout-sw360dp-port
別急,你有一半的用戶是說阿拉伯語的?那就將布局名稱改為下面的樣子吧:
layout-sw360dp-land
layout-sw360dp-port
layout-sw360dp-land-ar
layout-sw360dp-port-ar
前兩個可以適用於所有語言,-ar代表阿拉伯語。
建議5:資源規則簡介:
XXX //例子:沒有添加目錄名:默認-適用於Nexus One,Droid 2,S2
XXX-sw360dp // 比較大的手機 – Galaxy Nexus, S3, S4
XXX-sw600dp // 7〃 平板
XXX-sw720dp // 10” 平板
在Kindle設備有些不同,如下:
XXX-large-mdpi // kindle fire 7〃
XXX-large-hdpi // kindle fire 7〃 HD
建議6:如果你不想裁剪所有的布局文件,你可以用dimens.xml文件。你要是留心我上面的文章,你就會注意到在我的values目錄里有很多dimens.xml,這樣是因為我更喜歡在一個layout.xml里設置值,在每一個布局文件里我喜歡這樣做:
<ImageView
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/small_margin"
android:layout_width="@dimen/dashBoardWidth"
android:layout_height="@dimen/dashBoardHeight"
android:id="@+id/dashboard"/>
small_margin是在dimen.xml文件里定義的:
<resources>
<dimen name="small_margin">4dp</dimen>
</resources>
這個4dp變數在所有dimen文件里。我有個Excel文件,裡面創建了所有不同的基於不同因素所需的尺寸定義。也許你會問:為什麼不讓android OS來處理所有尺寸的問題?為什麼不呢,為什麼不用一個values目錄和一個布局目錄來代替所有寫死的數值呢?那當然是可以的,如果設置得當,都會得到所有的尺寸,但是對於有些元素看起來就不是那麼好計算尺寸了。
建議7:讓空白空間大於圖像空間。讓圖像空間大於按鈕的大小。如果將按鈕,多選框,切換控制項放大後是很醜陋的。一個100dip(0.63")大小的按鈕是不想在平板上顯示為原來兩倍寬度200dip(1.25")的.原因是屏幕變大了,這不是說平板是給巨人用的。我們可以這樣做,在按鈕增加的空間和圖片擴展的空間里添加空白。
建議8:用GraphicalLayout工具快速預覽。GraphicalLayout是WYSIWG XML編輯器。我喜歡直接編寫元素-而不是拖,丟棄的可見編程方式,但在添加一些元素之後,可以在GraphicalLayout的下拉選擇菜單里選擇不同屏幕尺寸進行測試。
這里有很多選項供你選擇。
圖片縮放
建議9:不要把所有的圖片都縮放了。用布局文件來適應不同屏幕尺寸的方法只是成功的一半,布局裡的元素(如:圖片)也要能在高解析度的屏幕下良好工作。在概念上比較簡單的方式就是創建一套完整的圖片目錄並將它們與很多drawable目錄匹配起來。
drawable-sw600dp-ldpi
drawable-sw600dp-mdpi
drawable-sw600dp-hdpi
drawable-sw600dp-xhdpi
drawable-sw600dp-xxhdpi
...其它的類似。
不要這樣做:
你不要太盡信書了。
一般來說有drawble-ldpi, drawable-hdpi等目錄就足夠了,不需要將所有的情況都加上。
建議10:避免使用點陣圖(jpg,png)。對於一些圖標來說,用點陣圖是個不錯的選擇,因為它們使用簡單。但是如果可以避免使用點陣圖,你可以節省很多空間。但用不同的方法也可以達到很好的結果。
建議11:用XML繪圖。點陣圖都可以用XML繪圖來代替的。XML繪圖不是萬能的,但是它的方便性還是使我感到驚訝。Android開發文檔中有詳細的介紹,這里有個簡單的例子:
這里是定義了一個圓角矩形,一個有漸變的邊(深藍)。你可以在布局文件的任何地方來引用,而且它可以適應於任何屏幕。用它可以做出理想的按鈕。
建議12:用更多的XML繪圖。再來介紹一個用XML繪圖製作出能更加讓你興奮的例子,下面的雷達背景看起來是不是更加的復雜:
不用點陣圖對你的UI是沒有壞處的(除過圖標)。
建議13:仍然用更多的XML繪圖(如果必須,就用點陣圖)。那我們怎樣為天氣信號構建一個超酷的圖標-讓燈泡動態的依據光的強度來進行自動填充,以及怎麼點擊指針後讓其旋轉呢?這里我們用點陣圖和XML結合起來做個例子:
燈泡我們用PNG圖:icon_magnitude_min(一個空的燈泡)和icon_magnitude_max(充滿光的燈泡),然後我們動態的裁剪後者。為了實現這個目標我是這樣做的:
在java程序中我將得到回形針的引用,然後可以用它來控制光的強度。
建議14: 為什麼要用9-patch (當你可以用XML drawables的時候)? Android具有使用9-patches 來定義drawables的選擇,有些教程闡述了怎樣用它們來做一個按鈕,這樣可以在伸展的時候保持幾個角不變 (並且避免了像素處理)。如果你已經知道怎樣使用9-patches,可能是從web設計中學會的,那麼它們或許值得一用。如果你對9-patches並不熟悉,我建議你維持原樣。如果你想適應什麼東西——例如拐角的圓弧或者顏色,創建9個小塊要比創建點陣圖更多被涉及,這就像回到了圖像編輯器的時代。許多用9-patches獲得的效果也可以通過XML獲得。
建議15: 通過覆蓋onDraw()創建自定義views. 有些事情XML並不十分在行,我們在OpenSignal和WeatherSignal中畫過許多圖像,為此有許多的庫,但是我們要為自定義圖像自己編寫代碼。這很有趣。或許你永遠也不需要做這個,但為了使圖像高度動態並自定義,這經常是唯一可行的辦法。
建議16:在不能使用XML的地方使用SVG. 有時候覆蓋onDraw()並勤勤懇懇的為自定義view編寫代碼畫出需要的線條與弧線是過於技術化了。畢竟有一種矢量圖像語言,它稱作…Scalable Vector Graphics(可擴展矢量圖形)。它也是史上最酷的Android應用之一—Androidify的動力來源。事實上他們創建這個庫就是為了那款應用,他們將它發布在這里:SVG for Android 。這也就是我們在OpenSignal中畫儀表盤所用到的。
建議17: 對SVG文件GZip壓縮. 將它們變得更小它們就會處理的更快。
建議18: SVG庫並不是支持一切. 在一些特定的alpha通道中似乎不能正常工作,你甚至不得不在代碼中將它們剔除。
達到在android所有版本里表示展現一致的目標
建議19:在一些android系統里(如TouchWhizz/HTC Sense/MotoBlur等等),默認的buttons和其他UI組件會跟原生系統里的看起來差別很大。我希望這不是真的,但事實卻是如此。
建議20:自定義你的UI組件。為了確定你的app在所有的設備里看起來是一致的,你將需要自定義所有的東西。這其實沒有你想像中那麼難,只要你做到了,你將能更加好地把握到你的app的展示外觀。
建議21:Selectors是創建buttons的利器。我們在上面提到了如何在XML里定義button的背景,但是你將如何創建一個當按下去會改變的button呢?很簡單:像下面那樣在xml文件里定義背景。該xml文件將接收到button當前狀態並且在外觀上做出相應的改變。
建議22:在Honeycomb之前的版本里時不存在ActionBar跟很多 animation 樣式的,所以可以使用ActionBarSherlock 跟NineOldAndroids來代替。Jake Wharton寫的Android開源 組件都是往下兼容的精心傑作。更為驚喜的是,ABS 擁有強大的功能用來定義ActionBar。
把速度作為目標
建議23:在運行慢的手機上測試。你將在運行慢的手機上發現很多問題,同時它讓你抓狂,沒人會喜歡運行慢的程序。
建議24:盡量減少XML布局層次。更多的層次意味著系統將為解析你的代碼付出更多的工作,這將會讓圖像渲染的更慢。
建議25:用Android Lint。在工程目錄上右鍵選擇Eclipse>Android Tools>Run Lint。它將會得到程序的一些信息,並能提高程序的運行速度,或者它能讓你得代碼更加清爽。
建議26:Android Lint可以得到錯誤信息。它可以給你的代碼提供很詳細的信息,並在你出錯之前就可以給做出提示。
建議27:用<merge>可以幫助你減少視圖層次結構。這是一種簡單的方式來去除多餘的層次。好的文章都對此有所解釋,而且在 Android Developer中它也顯得與眾不同。
建議28:用HierarchyViewer可以直觀的看到你布局的層次。這個智能的工具可以顯示布局中有多少層次,而且可以提示出那些可以讓程序變慢。
建議29:如果可以盡量用RelativeLayout。AbsoluteLayout已經過期了,就不要用了。你經常會遇到在RelativeLayout和LinearLayout中做出選擇的情況,那就直接用RelativeLayouot吧,因為它可以讓你減少視圖層次。比如,你想實現一個如下視圖:
盒子 A 在屏幕左半邊 |盒子 B在屏幕右半邊
你首先會想到這么做:
<LinearLayout
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:orientation=”horizontal”
>
<TextView
android:text=”Box A takes up left half of the screen”
android:layout_width=”0dip”
android:layout_height=”wrap_content”
android:layout_weight=”1″
/>
<TextView
android:text=”Box B takes up left half of the screen”
android:layout_width=”0dip”
android:layout_height=”wrap_content”
android:layout_weight=”1″
/>
</LinearLayout>
That works just fine, but you could also use:
<RelativeLayout
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:orientation=”horizontal”
>
<TextView
android:text=”Box A takes up left half of the screen”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_toLeftOf=”@+id/mmy_center”
/>
<View
android:id=”@+id/mmy_center”
android:layout_width=”0dip”
android:layout_height=”0dip”
android:layout_gravity=”center”
/>
<TextView
android:text=”Box B takes up left half of the screen”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_toRightOf=”@+id/mmy_center”
/>
</RelativeLayout>
第二個表單比第一個難看的多,事實上是相當的糟糕:我們已經介紹過一個完整的新元素了。但是假如我們要給每個盒子里加入一個圖片,一般的我們將這樣做:
盒子 A 在屏幕左半邊 圖片|盒子 B在屏幕右半邊 圖片
用第一中方法,你得創建一個有兩個層次的LinearLayout,如果用第二種方法,你可以直接在同一個RelativeLayout中加入圖片,比如要指定第一個圖片必須在“mmy_center”的左邊,而且一個TextView A必須也在其左側。那麼你就得用7個元素3個視圖層次了(LinearLayout 方式),而(RelativeLayout方式)只用6個元素2個層次,這樣所有的工作添加完成。
建議30:用一些擴展工具如DDMS。這可以幫助你發現一些不必要的網路調用、查看電池使用量、垃圾回收信息,狀態變化(例子:當回調onStop和onDestroy時)等。LittleEye是我目前比較喜歡的工具。
建議31:用AsyncTasks。Anroid工程團隊受夠了人們經常在UI線程裡面實現網路調用(譯註:耗時操作,容易阻塞UI刷新),所以他們實現了一些可產生編譯級錯誤信息的API。但是仍然在很多app中的一些工作會拖垮UI線程,我們要考慮到UI布局要快以及提高UI的響應性。
目標機器空間小
建議32:一些Aandroid設備有100mb空間大小的限制。現在情況已有變化了,但是仍然有很多用戶還會擔心5Mb大小的app會浪費空間。如果你可以選擇將app裝入SD卡的話,這就不是問題了,但如果你的app需要在onBoot里啟動的話你就不能裝入SD卡了(例子:如一些窗體小部件).甚至對於一些新的設備,如果能很快的下載一個小的APK的話,用戶還是很高興的。
建議33:用XML資源(我發誓上次我已經提醒過了),這將比PNG資源節省很多空間,當你僅僅需要一個可以滿足很多屏幕大小的配置時,一個XML文件會比能實現同樣功能的PNG省空間。
建議34:如果要用PNG,最好優化一下(用PNGCrush或ImageOptim)
目標bugs
建議35:在Android開發者控制台里檢查所有被自動檢測出來的bugs.
建議36: ProGuard現在是默認啟動著的. Proguard太好用了 (提高你app的速度和降低文件大小),但這也讓StackTraces 非常難以處理。你將需要重新追蹤你的StackTraces,因此你將需要繼續保留在每次構建中創建的Proguard的映射文件。我把它們都放到以代碼版本號命名的文件夾里。
建議37: 為了顯示StackTraces里的行數,你需要修改ProGuard的配置。確認你的proguard.cfg擁有下面這句話:
-keepattributes SourceFile,LineNumberTable
建議38:使用staged rollouts。測試5%的基礎用戶,並且觀察bug報告。
建議39:使用真實設備測試平台。Device Anywhere and Perfecto Mobile提供了虛擬測試平台,在那裡,你可以使用真正的移動設備。我發現他們有一些笨拙,加入連續不斷地進行測試的話,會導致有一些糟糕的情況。如果你在聯合辦公的環境里工作,或者有一些Android開發的好友,那麼去啟動一個“設備池”吧。
建議40: 多寫代碼少寫博客。其實不是的, 分享就是關愛, 我只是想不出第40條寫什麼是了。
『拾』 android系統中有哪三種常用的ui設計方式
Android 資源類型
1.字元串資源
>>1.普通字元串
>>2.字元串數組
復制代碼
<resources>
<string-array name="planets_array">
<item>aaa</item>
<item>bbb</item>
</string-array>
</resources>
復制代碼
獲取方式:getResources().getStringArray(R.array.planets_array)
>>3.復數字元串資源
某些自然語言中,不同的數字在使用方法上會有所不同,比如one book,two books。當數量大於1時,會使用不同的名詞或其它復數形式;
復制代碼
<resources>
<plurals name="numberOfp">
<item quantity="one">one person</item>
<item quantity="other">more persons</item>
</plurals>
</resources>
復制代碼
quantity屬性的值除了one和other外,還可以是zero,two,few,many;
引用復數字元串:
// 引用數字為1的復數字元串
getResources().getQuantityString(R.pluarlas.numberOfp,1);
// 引用數字為其它值的復數字元串
getResources().getQuantityString(R.pluarlas.numberOfp,10,10);
>>4.佔位符格式化字元串
常用的格式化字元串三種方法:
>>1.在字元串中使用引號
字元串中的值雖然可以隨意指定,但是當遇到特殊符號時(雙引號,單引號)就需要採取特殊的方法來處理這些符號。
如果是單引號(')可以使用轉義符(\)或用雙引號(")將整個字元串括起來,如果是雙引號,可以在雙引號前使用轉義符(\)。
<resources>
<string name="str1">"This'll work"</string> This'll work
<string name="str2">This\'ll work</string> This'll work
<string name="str3">\"apple\"</string> "apple"
</resources>
>>2.用佔位符格式化字元串
使用String.format(String,Object...)方法可以格式化帶佔位符的字元串,只需要在字元串中插入佔位符,就可以使用String.format方法格式化字元串資源,format方法要求的佔位符用%1,%,...,%n,其實第n個佔位符與format方法的n+1個參數值對應;
<resources>
<!-- $s表示該佔位符被字元串替換,$d表示該佔位符被整數替換 -->
<string name="str1">hello,%1$s!You have %2$d new message</string>
</resources>
String str1 =String.format(getResources().getString(R.string.str1), "ly", 17);
>>3.使用HTML標簽格式化字元串資源
字元串資源支持一些HTML標簽,因此可以直接在字元串資源中使用這些HTML標簽格式化字元串
字元串資源支持如下的HTML標簽
<b>粗體字
<i>斜體定
<u>帶下劃線的字
有時需要同時使用HTML標簽和佔位符格式化字元串,如果使用String.format方法格式化字元串,會忽略字元串中的所有HTML標簽。為了使format方法可以格式化帶
HTML標簽的確字元,需要使用Html.formHTML方法處理字元串;
<resources>
<string name="hello_world">Welcome to <b>android</b></string>
<string name="str2">Hello,%1$s! You have <b> %2d new messages </b></string> <!--同時包含佔位符和html標簽的字元串-->
</resources>
由於需要使用Html.formHTML方法處理字元串,因此HTML標簽中的 "<" 需要使用 "<" 表示 ">" 並不需要處理
獲取字元串:
String text = String.format(getResources().getString(R.string.str2), "ly", 10);
CharSequence styledText = Html.fromHtml(text);
// 如果format的某個參數包含HTML的特殊字元,如"<","&",可以使用如下方式讀取字元串的值;
String escapedUsername = TextUtils.htmlEncode("");
String text1 = String.format(getResources().getString(R.string.str2), "ly", 20);
2.Layout資源
1、如果根節點是View,除了<requestFocus>標簽外,不能添加任何子標簽,<requestFocus>可能被添加到布局文件的任何View中,表示該標簽對應的控制項在顯示時處於焦點狀態,整個布局文件只能有一個<requestFocus>標簽
2、根節點是ViewGroup,常用的布局都是ViewGroup的子類
3、重用布局文件
如果想重用某個布局文件,可以使用<include>標簽
<include layout="@layout/xx_layout" />
如果想讓一個布局文件被另一個布局文件引用(使用<include>標簽),可以使用<merge>作為被引用布局文件的根節點,由於<merge>並不會生成任何標簽(在大量引用布局文件時不至於生成大量無用的標簽),但是xml文件必須要有一個根節點,因此<merge>所起的作用就是作為xml文件的根節點,以使xml文件在編譯時不至於出錯,可以把<merge>當成<FrameLayout>使用;
3.圖像資源
在圖像資源中可以存儲圖像文件,還可以使用xml格式的圖像資源來控制項圖像的狀態和行為;
>>1.普通圖像資源
Drawable da = getResources().getDrawable(R.drawable.xxx);
>>2.xml圖像資源
xml圖像資源其實就是在drawable目錄中指定的xml文件,此種方式可以額外指定圖像的某些屬性,如圖像拉動、排列方式;
<bitmap xmlns:android=""
android:src="@drawable/ic_launcher"
android:tileMode="repeat" >
</bitmap>
>>3.Nine-Patch圖像資源
Nine-Patch圖像資源文件必須以9.png作為文件擴展名,如abc.9.png
該圖像資源的主要作用是:防止圖像的某一部分被拉伸;確定將圖像作為背景圖的控制項中內容顯示的位置;
Android SDK本身提供了一個Draw 9-patch的工具,啟動<sdk目錄>\tools\draw9patch.bat命令啟動該工具;
可以通過此工具在png圖的四周繪制1個像素粗的直線,上邊緣和左邊緣的直線分別表示圖像在水平和垂直方向可位值的范圍。如果水平或垂直方向的某個區域不需要拉伸,則可不繪制相應的直線;右邊緣和下邊緣的直線分別表示圖像所在控制項中內容的顯示範圍,內容只在右邊緣和下邊緣繪制直線的區域顯示,表示內容顯示範圍和拉伸范圍的兩給直線有一個重要區別就是表示內容顯示範圍的直線中間不能斷開,而表示拉伸范圍的直線中間可以斷開;
Nine-Patch圖像資源與普通圖像資源引用方法相同,在引用時只寫文件名,活力.9.png;
>>4.XML Nine-Patch圖像資源
Nine-Patch圖像資源也有與其對應的xml圖像資源,使用<nine-patch>標簽來引用Nine-Patch格式的圖像,有一個設置抖動的android:dither屬性;
>>5.圖層資源
圖層資源類似於<FrameLayout>不同的是<FrameLayout>標簽中可以包含任意的控制項,而圖層資源每一層都只有是圖像,定義圖層資源必須使用<layer-list>作為資源文件的根節點,<layer-list>標簽中包含多個<item>標簽,每一個標簽表示一個圖像,最後一個<item>標簽顯示在最頂層;
默認情況下,圖像會盡量充滿顯示圖像的范圍,圖像可能會有拉伸,為了避免圖像拉伸,可以在<item>標簽中使用<bitmap>標簽引用圖像;
復制代碼
<layer-list xmlns:android="" >
<item
android:bottom="10dip" 底端偏移的像素
android:left="10dip" 左側偏移的像素
android:right="10dip" ...
android:top="10dip"> ...
<bitmap
android:gravity="center"
android:src="@drawable/hell" />
</item>
</layer-list>
復制代碼
某些情況下,可以使用圖層來代替<FrameLayout>
>>6.圖像狀態資源,處理控制項不同狀態下的顯示狀態
復制代碼
<selector xmlns:android="">
<item android:drawable="@drawable/bm" android:state_focused="true"></item>
<item android:drawable="@drawable/bm" android:state_pressed="true"></item>
<item android:drawable="@drawable/bm"></item>
</selector>
// android:state_focused/pressed設置為true表示當前item的drawable屬性為獲取焦點和按下時的drawable樣式
復制代碼
>>7.圖像級別(Level)資源
圖像資源狀態只能指定幾種有限的狀態,可以通過圖像級別指定更多的狀態;圖像級別是一個整數的區間,可以通過ImageView.setImageLevel或Drawable.setLevel方法切換不同狀態的圖像;圖像級別資源是xml文件,必須以<level-list>為根節點,每一個item表示一個級別區間,下面是一個xml文件;通過ImageView.setImageLevel(level),根據level所在的區間設定顯示的圖像資源,如果level不在任一區間內則清空ImageView當前圖像;
<level-list xmlns:android="">
<item android:maxLevel="2" android:minLevel="0" android:drawable="@drawable/hell" />
<item android:maxLevel="4" android:minLevel="3" android:drawable="@drawable/hell" />
</level-list>
>>8.淡入淡出(Cross-fade)資源
也是切換兩個圖像(不支持多於兩個圖像的切換),並且使這兩個圖像以淡入淡出效果進行切換,如電燈在開關時逐漸變亮或逐漸變暗;
<transition xmlns:android="" >
<item android:drawable="@drawable/hell"/>
<item android:drawable="@drawable/hell"/>
</transition>
TransitionDrawable da = ...;
// 從第一張圖片切換到第二張圖片,時間效果為1秒
da.startTransition(1000);
// 從第二張圖片切換到第一張圖片,時間效果為1秒
da.reverseTransition(1000);
>>9.嵌入(insert)圖像資源
使用場景:要顯示的圖像要求要小於裝載圖像的View(圖小於View區域),也是通過xml資源定義,只有一個節點inset。
<inset xmlns:android=""
android:drawable="@drawable/hell"
android:insetLeft="10dip" > <!--圖像距離左邊的距離,延伸-->上/下/右的距離-->
</inset>
>>10.剪切(Clip)圖像資源,使用剪切圖像資源可以只顯示圖像的一部分,如可以通過此來製作進度條;
<clip xmlns:android=""
android:clipOrientation="horizontal" // 指定截取的方向
android:drawable="@drawable/hell" // 指定要截取的圖像
android:gravity="left" > // 指定截取的方式,在此為從左側開始截取
</clip>
ClipDrawable cd = ...;
cd.setLevel(1000);
上面ClipDrawable.setLevel(level)設置截取的圖像寬度,ClipDrawable預設了最大值10000(表示不進行截取),最小值為0(表示不顯示);
>>11. 比例(Scale)圖像資源
<scale xmlns:android=""
android:drawable="@drawable/hell"
android:scaleGravity="center" // 設置圖像顯示的位置
android:scaleHeight="70%" // 設置圖像顯示的高度
android:scaleWidth="80%" > // 設置圖像顯示的寬度
</scale>
>>12.形狀資源
復制代碼
<shape xmlns:android=""
android:shape="rectangle" > shape可以指定就矩形,oval(橢圓),line(直線),ring(圓)
<corners> 定義圓角
</corners>
<gradient
android:angle="45"
android:startColor="#000000"
android:endColor="#FFFFFF" > 定義顏色漸變,從左下角到或上角
</gradient>
<padding> 定義控制項內容到邊框的距離
</padding>
<stroke> 定義邊線
</stroke>
<solid> 定義填充
</solid>
<size> 定義大小
</size>
</shape>
復制代碼
13.菜單資源
菜單不僅可以在onCreateContextMenu或onCreateOptionsMenu方法中通過代碼創建,還可以在res/menu目錄中建立相應的菜單資源文件,並在上面兩個方法中載入菜單資源;
菜單資源文件必須以<menu>標簽作為根節點,每一個菜單項用一個<item>表示,如果要定義子菜單,可以在<item>標簽中包含<menu>標簽;如果想將多個菜單項劃為一組,可以使用<group>包含多個<item>標簽;
復制代碼
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
復制代碼
查看MenuInflater.inflate(int,Menu)
復制代碼
/**
* Inflate a menu hierarchy from the specified XML resource.
*
* @param menuRes Resource ID for an XML layout resource to load (e.g., <code>R.menu.main_activity</code>)
* @param menu The Menu to inflate into. The items and submenus will be added to this Menu.
*/
public void inflate(int menuRes, Menu menu) {
XmlResourceParser parser = null;
try {
parser = mContext.getResources().getLayout(menuRes);
AttributeSet attrs = Xml.asAttributeSet(parser);
parseMenu(parser, attrs, menu);
} catch ...finally {
if (parser != null) parser.close();
}
}
復制代碼
14.樣式與主題(style/theme)
>>1.樣式style
android中樣式和css中樣式作用是一樣的,都是用於為界面元素定義顯示風格,它是一個包含一個或者多個控制項屬性的集合。
定義樣式需要在res/values/styles.xml中進行定義,如下是一個樣式的定義:
<style name="textViewStyle">
<item name="android:textSize">22sp</item>
<item name="android:textColor">#FF0000</item>
</style>
<style name="textViewStyle1" parent="textViewStyle"></style><!-- 此樣式繼承自textViewStyle -->
<style name="textViewStyle.Livingstone"><!-- 樣式繼承的另一種寫法,但不可用此寫法繼承Android自帶的定義樣式? -->
<item name="android:textColor">#00FF00</item>
</style>
所有定義的樣式都會在R文件中自動生成一個資源ID,加一個點表示樣式繼承會生成上圖所示的資源id;
樣式的引用:
<TextView
style="@style/textViewStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="hello" />
>>2.主題Theme
主題應用於整個應用或者activity,樣式應用於具體的控制項上。主題的應用與樣式定義一樣,不同的是主題還可以設置窗口的顯示風格;主題的引用需要在清單文件中進行引用,如引用到整個應用之上就需要在Application節點中進行配置引用,而引用到單個Activity只需要在此Activity中進行配置引用;
復制代碼
<style name="Livingstonetheme"><!--此定義是一個無Title的主題-->
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">?android:windowNoTitle</item>
<!-- 問號表示引用此主題中android:windowNoTitle屬性的值 -->
<item name="android:textSize">18sp</item>
</style>
復制代碼
android系統定義了一些屬性,如android:theme="@android:style/Theme.Dialog",該主題可以讓Activity看起來像一個對話框,更多主題可以在文檔reference->android->R.style中查看。當主題裡面的樣式屬性值與樣式裡面的屬性值發生沖突的時候會顯示樣式裡面的值;
15.其它資源
在資源文件中還可以包括尺寸(dimen)、整數(integer)、布爾(bool) 、整形數組資源(integer-array)、資源數組(array)、顏色(color)
TypedArray ta = getResources().obtainTypedArray(int id); // 獲取數組資源,包括integer-array、array
Final總結:
除了res/values目錄中的資源名,其它目錄的資源都會以文件名在R類的相應子類中生成變數;而res/values中的資源會以name屬性值為變數名在R類的相應子類中生成變數;