LayoutParams分類和作用
LayoutParams是ViewGroup類中的子類,而ViewGroup我們都知道,它是容納組件的容器。比如說:LinearLayout,ListView都是繼承ViewGroup的。LayoutParams主要設置的是子view在父類佈局的參數,有如下兩種方式:
(1)通過XML文件定義
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">
<textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="xiaotang">
</textview></relativelayout>
可以看到,TextView需要設置layout_width和layout_height參數,才能在父佈局中顯示出來。
(2)通過java代碼添加View
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
TextView tv = new TextView(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
new LayoutParams(-1, -1));
tv.setText("xiaotang");
contentView.addView(tv);
}
可以看到在java代碼中添加view,需要設置其在父佈局中的佈局參數,才能順利顯示出來.當然在這裏,你不申明lp佈局參數也可,contentView.addView(tv)會判斷你是否設置view的佈局參數,若沒設置,則默認提供Warp_content類的佈局參數.那麼View的LayoutParams爲什麼要設置成RelativeLayout類型呢?後面我們會詳細討論的.
View的LayoutParams與父類的關係
View的LayoutParams設置在父類裏面才能起到效果.大家應該重視這句話,你真正理解了這句話了嗎?接下來,我們用一個Code來說明:
我們在Layout裏面申明瞭一個textview.xml文件,內容如下:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">
<textview android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/red" android:text="xiaotang">
</textview></linearlayout>
MainActivity代碼如下:
運行截圖如下:
可以看到在textview.xml中申明的LayoutParams爲fill_parent,但是顯示的時候卻還是warp_content,那麼要全屏顯示TextView,我們該如何做呢?
代碼如下:
運行截圖如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
View view = View.inflate(this, R.layout.textview, null);
contentView.addView(view);
}
在這裏,我沒有設置view的LayoutParams,contentView.addView()時會添加warp_content的佈局參數。有朋友就要問了,在textview.xml中不是已經設置View的佈局爲Fill_Parent嗎?爲什麼還要設置呢?還是我說的那句話,view的佈局參數只有在父類中申明(也就是父類.LayoutParams)才能正確顯示,我們看結果就能說明一切了.運行截圖如下:
可以看到在textview.xml中申明的LayoutParams爲fill_parent,但是顯示的時候卻還是warp_content,那麼要全屏顯示TextView,我們該如何做呢?
代碼如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
View view = View.inflate(this, R.layout.textview, null);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
view.setLayoutParams(lp);
contentView.addView(view);
setContentView(contentView);
}
通過將view的佈局參數設置爲FILL_PARENT,那麼TextView組件的背景就全屏顯示了,說明佈局起到了作用!運行截圖如下:
爲什麼view的LayoutParams要是父容器的的LayoutParams
大家看我上面的舉的實例中,細心的你就會發現。爲什麼view放在contentView中,申明的lp(佈局參數)都是RelativeLayout類的?原因就是裝載該View的容器就是RelativeLayout.我們再看看下面這個例子:
Display display = this.getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // 獲取屏幕寬度
int height = display.getHeight(); // 獲取屏幕高度
View head = View.inflate(this, R.layout.head, null);
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, this.getResources()
.getDimensionPixelOffset(R.dimen.top_bg_height));
head.setLayoutParams(layoutParams);
listView.addHeaderView(head);
這是ListView添加View的例子,可以看到view的LayoutParams的類型就是AbsListView(ListView繼承AbsListView並且在ListView中沒有修改該LayoutParams).原因分析:
我們都知道,每一個視圖的繪製過程都必須經歷三個最主要的階段,即onMeasure()、onLayout()和onDraw(),父容器不僅要負責自己的顯示,而且還要遍歷取負責子組件的顯示.我們查看容器的onMeasure()方法就能看到有如下操作:
這裏以RelativeLayout爲例:
這裏以RelativeLayout爲例:
LayoutParams params = (LayoutParams) child.getLayoutParams(); //這裏的LayoutParams是RelativeLayout類型
個人疑惑
大家請看下面代碼:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
View view = View.inflate(this, R.layout.textview, null);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
lp.topMargin=20;
view.setLayoutParams(lp);
contentView.addView(view);
setContentView(contentView);
}