本節(jié)引言:
1.LayoutInflater的相關(guān)介紹1)Layout是什么鬼?
2)LayoutInflater的用法①獲取LayoutInflater實例的三種方法: LayoutInflater inflater1 = LayoutInflater.from(this); LayoutInflater inflater2 = getLayoutInflater(); LayoutInflater inflater3 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); PS:后面兩個其實底層走的都是第一種方法~ ②加載布局的方法:
③通過LayoutInflater.LayoutParams來設(shè)置相關(guān)的屬性:
2.純Java代碼加載布局
純Java代碼加載布局的流程:——Step 1: ①創(chuàng)建容器:LinearLayout ly = new LinearLayout(this); ②創(chuàng)建組件:Button btnOne = new Button(this); ——Step 2: 可以為容器或者組件設(shè)置相關(guān)屬性: 比如:LinearLayout,我們可以設(shè)置組件的排列方向:ly.setOrientation(LinearLayout.VERTICAL); 而組件也可以:比如Button:btnOne.setText("按鈕1"); 關(guān)于設(shè)置屬性的方法可參見Android 的API,通常xml設(shè)置的屬性只需在前面添加:set即可,比如 setPadding(左,上,右,下); ——Step 3: 將組件或容器添加到容器中,這個時候我們可能需要設(shè)置下組件的添加位置,或者設(shè)置他的大?。?我們需要用到一個類:LayoutParams,我們可以把它看成布局容器的一個信息包!封裝位置與大小 等信息的一個類!先演示下設(shè)置大小的方法:(前面的LinearLayout可以根據(jù)不同容器進行更改) LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
很簡單,接著就到這個設(shè)置位置了,設(shè)置位置的話,通常我們考慮的只是RelativeLayout! 這個時候用到LayoutParams的addRule( )方法!可以添加多個addRule( )哦! 設(shè)置組件在父容器中的位置, 比如設(shè)置組件的對其方式: RelativeLayout rly = new RelativeLayout(this);
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
Button btnOne = new Button(this);
rly.addView(btnOne, lp2);
參照其他組件的對其方式: (有個缺點,就是要為參考組件手動設(shè)置一個id,是手動!!!!) 比如:設(shè)置btnOne居中后,讓BtnTwo位于btnOne的下方以及父容器的右邊! public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout rly = new RelativeLayout(this);
Button btnOne = new Button(this);
btnOne.setText("按鈕1");
Button btnTwo = new Button(this);
btnTwo.setText("按鈕2");
// 為按鈕1設(shè)置一個id值
btnOne.setId(123);
// 設(shè)置按鈕1的位置,在父容器中居中
RelativeLayout.LayoutParams rlp1 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rlp1.addRule(RelativeLayout.CENTER_IN_PARENT);
// 設(shè)置按鈕2的位置,在按鈕1的下方,并且對齊父容器右面
RelativeLayout.LayoutParams rlp2 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rlp2.addRule(RelativeLayout.BELOW, 123);
rlp2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
// 將組件添加到外部容器中
rly.addView(btnTwo, rlp2);
rly.addView(btnOne, rlp1);
// 設(shè)置當前視圖加載的View即rly
setContentView(rly);
}
}
——step 4: 調(diào)用setContentView( )方法加載布局對象即可! 另外,如果你想移除某個容器中的View,可以調(diào)用容器.removeView(要移除的組件); 運行截圖:
3.Java代碼動態(tài)添加控件或xml布局
1)Java代碼動態(tài)增加View動態(tài)添加組件的寫法有兩種,區(qū)別在于是否需要先setContentView(R.layout.activity_main); 下面演示下兩種不同寫法添加一個Button的例子: 先寫個布局文件先:activity_main.xml: <RelativeLayout xmlns:android="http://schemas./apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="我是xml文件加載的布局"/>
</RelativeLayout>
第一種不需要setContentView()加載布局文件先: public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btnOne = new Button(this);
btnOne.setText("我是動態(tài)添加的按鈕");
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp2.addRule(RelativeLayout.CENTER_IN_PARENT);
LayoutInflater inflater = LayoutInflater.from(this);
RelativeLayout rly = (RelativeLayout) inflater.inflate(
R.layout.activity_main, null)
.findViewById(R.id.RelativeLayout1);
rly.addView(btnOne,lp2);
setContentView(rly);
}
}
第二種不需要setContentView()加載布局文件先: public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnOne = new Button(this);
btnOne.setText("我是動態(tài)添加的按鈕");
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp2.addRule(RelativeLayout.CENTER_IN_PARENT);
RelativeLayout rly = (RelativeLayout) findViewById(R.id.RelativeLayout1);
rly.addView(btnOne,lp2);
}
}
分析總結(jié):
2)Java代碼動態(tài)加載xml布局接下來的話,我們換一個,這次加載的是xml文件!動態(tài)地添加xml文件! 先寫下主布局文件和動態(tài)加載的布局文件: activity_main.xml: <RelativeLayout xmlns:android="http://schemas./apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/btnLoad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="動態(tài)加載布局"/>
</RelativeLayout>
inflate.xml: <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas./apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/ly_inflate" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是Java代碼加載的布局" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是布局里的一個小按鈕" />
</LinearLayout>
接著到我們的MainActivity.java在這里動態(tài)加載xml布局: public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲得LayoutInflater對象;
final LayoutInflater inflater = LayoutInflater.from(this);
//獲得外部容器對象
final RelativeLayout rly = (RelativeLayout) findViewById(R.id.RelativeLayout1);
Button btnLoad = (Button) findViewById(R.id.btnLoad);
btnLoad.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//加載要添加的布局對象
LinearLayout ly = (LinearLayout) inflater.inflate(
R.layout.inflate, null, false).findViewById(
R.id.ly_inflate);
//設(shè)置加載布局的大小與位置
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
rly.addView(ly,lp);
}
});
}
}
運行截圖:
代碼分析:
4.LayoutInflater的inflate()方法源碼
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
final AttributeSet attrs = Xml.asAttributeSet(parser);
mConstructorArgs[0] = mContext;
View result = root;
try {
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
}
if (type != XmlPullParser.START_TAG) {
throw new InflateException(parser.getPositionDescription()
+ ": No start tag found!");
}
final String name = parser.getName();
if (TAG_MERGE.equals(name)) {
if (root == null || !attachToRoot) {
throw new InflateException("merge can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
rInflate(parser, root, attrs);
} else {
View temp = createViewFromTag(name, attrs);
ViewGroup.LayoutParams params = null;
if (root != null) {
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
temp.setLayoutParams(params);
}
}
rInflate(parser, temp, attrs);
if (root != null && attachToRoot) {
root.addView(temp, params);
}
if (root == null || !attachToRoot) {
result = temp;
}
}
} catch (XmlPullParserException e) {
InflateException ex = new InflateException(e.getMessage());
ex.initCause(e);
throw ex;
} catch (IOException e) {
InflateException ex = new InflateException(
parser.getPositionDescription()
+ ": " + e.getMessage());
ex.initCause(e);
throw ex;
}
return result;
}
}
本節(jié)小結(jié):
|
|
|
來自: 小飛苑 > 《android基礎(chǔ)》