編輯:關於Android編程
...
1)
標簽可以使用單獨的layout屬性,這個也是必須使用的。 2)可以使用其他屬性。
標簽若指定了ID屬性,而你的layout也定義了ID,則你的layout的ID會被覆蓋,解決方案。 3)在include標簽中所有的android:layout_*都是有效的,前提是必須要寫layout_width和layout_height兩個屬性。 4)布局中可以包含兩個相同的include標簽,引用時可以使用如下方法解決(參考):
View bookmarks_container_2 = findViewById(R.id.bookmarks_favourite);
bookmarks_container_2.findViewById(R.id.bookmarks_list);
(1) 自定義View中使用,父元素盡量是FrameLayout,當然如果父元素是其他布局,而且不是太復雜的情況下也是可以使用的
(2) Activity中的整體布局,根元素需要是FrameLayout
下面這個例子將融合這兩種情況,來展示如何縮減布局層次。
總體顯示界面如圖所示:
其中粉紅色圈住的部分為我們的自定義View。
整個界面的布局layout_mergedemo.xml如下:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
<framelayout android:layout_height="fill_parent" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
自定義布局view_item.xml如下:
自定義View中使用下面來解析布局:
public class MyItemView extends LinearLayout {
......
private void initView(Context context) {
mContext = context;
View view = LayoutInflater.from(mContext).inflate(R.layout.view_item, this, true);
mMyItemImg = (ImageView)view.findViewById(R.id.view_item_img);
mMyItemText = (TextView)view.findViewById(R.id.view_item_txt);
}
......
}
整個功能開發完成之後,使用hierarchyviewer來看一下布局層次:
簡化view_item.xml:
因為這裡merge代替的布局元素為LinearLayout,而不是FrameLayout,所以我們需要在自定義布局代碼中將LinearLayout的屬性添加上,比如垂直或者水平布局,比如背景色等,此處設置為水平布局:
private void initView(Context context) {
setOrientation(LinearLayout.HORIZONTAL);
……
}
OK,就是這麼簡單,再來看看布局層次吧:
哈哈,只有四層了,加載速度也明顯加快,特別是如果布局比較復雜,子View較多的情況下,合理使用merge能大大提高程序的速度和流暢性。
但是使用merge標簽還是有一些限制的,具體有以下幾點:
(1)merge只能用在布局XML文件的根元素
(2)使用merge來inflate一個布局時,必須指定一個ViewGroup作為其父元素,並且要設置inflate的attachToRoot參數為true。(參照inflate(int, ViewGroup, boolean))
(3)不能在ViewStub中使用merge標簽。最直觀的一個原因就是ViewStub的inflate方法中根本沒有attachToRoot的設置
說到這兒,merge的使用也就講完了。還想唠叨一下做的演出項目,因為本人水平有限,並且產品提的這個顯示需求確實比較BT,所以整個項目的顯示框架做了很多嵌套,具體點就是ActivityGroup中嵌套ViewFlipper,然後再嵌套TabHost,然後再嵌套自己的Activity,大體數了一下,最多竟然有20幾層,My God!知道Android布局設計的原則是什麼嗎?最好是10層以下,盡量不要超過15層,如果再多性能就會下降,也可能會出現問題,就是我們看到的StackOverFlow,這個項目被證實也確實在某些低端機上發生了這種錯誤,比如HTC的某某機型,OPPO的某某機型,(不要聲討我,沒有惡意貶低的意思<_>),最終我使用merge縮呀縮呀,把大部分的布局都縮減到了15層以下,一測試,通過!
還要說一下,因為Window窗體(比如Activity)加載時會自動添加PhoneWindow$DecorView和FrameLayout(id/content)兩層布局,所以如果我們在Activity的自定義布局根元素中使用merge,而且想設置總體背景什麼的,可以用(id/content)將FrameLayout取出來,再設置屬性,可以這樣實現:
//setContentView(R.layout.layout_showset);
FrameLayout frameLayout = (FrameLayout)this.getWindow().getDecorView().findViewById(android.R.id.content);
frameLayout.setBackgroundResource(R.drawable.bg_repeated_main);
LayoutInflater.from(this).inflate(R.layout.layout_showset, frameLayout, true);
這是什麼玩應兒呢?其實就是一個輕量級的頁面,我們通常使用它來做預加載處理,來改善頁面加載速度和提高流暢性,ViewStub本身不會占用層級,它最終會被它指定的層級取代。
還是說說演出項目吧,還說?對了,實踐才能發現問題嘛,在哪兒發現問題就在那兒改進。由於項目中用到了比較多的動畫,而且嵌套布局比較復雜,所以在Android低端機上進行頁面切換時候經常讓人感覺卡卡的,不怎麼流暢,因為頁面切換動畫和標題旋轉動畫是同時進行的,所以為了達到更好的體驗就需要使用一種方法,在動畫進行時盡量的減少其他操作,特別是頁面加載重繪。趕緊想辦法,起初我想先將要加載的頁面所有的組件都初始為gone顯示狀態,整個頁面只留一下加載滾動條,後來發現這是不行滴,因為在Android的機制裡,即使是將某一個控件的visibility屬性設置為不可見的gone,在整個頁面加載過程中還是會加載此控件的。再後來就用到了ViewStub,在做頁面切換動畫時,只在頁面中放一個loading加載圖標和一個ViewStub標簽,像下面這樣:
> layout_loading.xml布局文件:
這個頁面是相當輕量級的,所以導致動畫加載速度非常快、而且流暢。等頁面切換動畫完成之後,我們再指定ViewStub的資源,來加載實際的頁面,這個資源就是實際要加載的頁面的布局文件。比如要加載MainActivity的布局文件layout_main.xml,onCreate實現如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_loading);
mLoadHandler = new Handler();
mLoadingView = (NetErrAndLoadView)findViewById(R.id.start_loading_lay);
mLoadingView.startLoading();
mViewStub = (ViewStub)findViewById(R.id.viewstub);
mViewStub.setLayoutResource(R.layout.layout_main);
mLoadHandler.postDelayed(new Runnable() {
@Override
public void run() {
mViewStub.inflate();
mLoadingView.hide();
}
},500);
}
上面的500單位是ms,就是延遲加載的時間。上面使用的是動態添加ViewStub指向布局資源的方法(mViewStub.setLayoutResource(R.layout.layout_main)),當然根據需要可以直接在ViewStub的布局塊兒中設置,需要設置ViewStub標簽下的layout屬性(android:layout=”@layout/ layout_main”)。
ViewStub也是有少許缺點的,下面所說:
1、 ViewStub只能Inflate一次,之後ViewStub對象會被置為空。按句話說,某個被ViewStub指定的布局被Inflate後,就不能夠再通過ViewStub來控制它了。所以它不適用 於需要按需顯示隱藏的情況。
2、 ViewStub只能用來Inflate一個布局文件,而不是某個具體的View,當然也可以把View寫在某個布局文件中。如果想操作一個具體的view,還是使用visibility屬性吧。
3、 VIewStub中不能嵌套merge標簽。(前面好像說過)
不過這些確定都無傷大雅,我們還是能夠用ViewStub來做很多事情。
有時候真的不得不佩服google的Android團隊的遠見性和架構性,這種細微的設計都能考慮的到,想用就有。
0) racketX -= 10; break; // 控制擋板右移,D右移 case KeyEvent.KEYCODE_D:
Android中啟動一個Activity如果點擊Home鍵該Activity是不會被銷毀的,但是當進行某些操作時某些數據就會丟失,如下:Java class:packag
模式的定義 適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。 使用場景 用電源接口做例
剛開始打算做一個簡單的截屏程序時,以為很輕松就能搞定。 在Activity上放一個按鈕,點擊完成截屏操作,並將數據以圖片形式保存