一些要點
DecorView 是android 界面的頂級View ,當前界面的整個即爲DecorView。DecorView爲FrameLayout,而DecorView 一般會包含一個豎直方向的LinearLayout。這個豎直方向的LinearLayout 一般分爲兩個部分(具體Android版本和主題有所不同),上部分爲標題欄,下部分爲內容欄,而內容欄的id 爲 android.R.id.content, 內容欄也是FrameLayout,我們使用setContentView(),的佈局加入的就是內容欄。
動態添加View 一般是添加在我們自己的佈局文件裏,而setContentView時加入的我們的佈局是內容欄的第一個子View,所以我們需要獲取到我們的佈局對應的View。
如何獲取DecorView?
在Activity 中直接調用 getWindow().getDecorView()
如何獲取ContentView?
在Activity中調用
FrameLayout contentView = (FrameLayout)getWindow().getDecorView().findViewById(android.R.id.content);
或直接:
FrameLayout contentView = (FrameLayout)activity.findViewById(android.R.id.content);
獲取我們填充的佈局
ViewGroup viewGroup = (ViewGroup)contentView.getChildAt(0);
添加View
//view 即爲我們要添加的View
viewGroup.addView(view);
viewGroup.addView(view, lp);
可選的參數如下:
不過如果你需要指定位置,就需要是用到LayoutParams 了,LayoutParams 可以在代碼中指定view 相對於父view的位置,相當於xml 裏的layout_gravity。
代碼中指定位置
相對佈局使用 lp.addRule()
指定位置:
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
其他佈局使用 lp.gravity
指定位置
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.BOTTOM;
一個要點:LayoutParams必須與你要加入的父佈局的類型一樣,否則雖然不會報錯,但是指定的位置將不起作用。
其實添加View 還有一個更簡單的方法,activity 提供了一個函數,
activity.addContentView(view, lp);
可以一步到位的添加view並指定位置。
你一定在埋怨我爲什麼不早點說,但其實學習最重要的是過程而不是結果不是嗎?