代碼中設置View的LayoutParams

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代碼如下:
  
	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組件的背景就全屏顯示了,說明佈局起到了作用!
運行截圖如下:
1476866430_2407.png

爲什麼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爲例:
  
   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);
	}
此處我將view的lp設置爲LinearLayout類型,加入到了RelativeLayout的容器中去了,竟然能正常顯示出來了,就是lp.topMargin沒有起到作用。程序沒有報錯,讓我很是不解,實在解釋不通,希望有大神指點一二,不勝感激。最後歡迎大家一起學習討論,一起提高!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章