一缭嫡、前言
在日常的開(kāi)發(fā)中經(jīng)常遇到需要?jiǎng)討B(tài)添加子view的情況缔御,addview是ViewGroup的特有方法,可以在布局中動(dòng)態(tài)添加view妇蛀,而view是不存在這個(gè)方法的耕突。
二、介紹
1评架、方法介紹
addview有以下幾種方式
addView(View child) // child 被添加的View
addView(View child, int index) // index 被添加的View的索引
addView(View child, int width, int height) // width,height被添加的View指定的寬高
addView(View view, ViewGroup.LayoutParams params) // params被添加的View指定的布局參數(shù)
addView(View child, int index, LayoutParams params)
2眷茁、使用方式
addview的使用在LinearLayout和RelativeLayout的效果不相同,首先介紹在LinearLayout中的使用古程。
2.1蔼卡、LinearLayout中的使用
首先創(chuàng)建一個(gè)xml文件,以ConstraintLayout作為根布局文件挣磨,其中包裹一個(gè)LinearLayout和兩個(gè)測(cè)試的按鈕雇逞。
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/root_view">
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--一開(kāi)始就存在的數(shù)據(jù)-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開(kāi)始存在的數(shù)據(jù)"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<!--測(cè)試按鈕一-->
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="測(cè)試一"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent" />
<!--測(cè)試按鈕二-->
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="測(cè)試二"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>
一開(kāi)始的效果如下圖
然后編寫(xiě)代碼,初始化控件和設(shè)置點(diǎn)擊事件
public class MainActivity extends AppCompatActivity {
private ConstraintLayout layout;
private LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = findViewById(R.id.root_view);
linearLayout = findViewById(R.id.container);
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addView();
}
});
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addviewTwo();
}
});
}
/**
* 按鈕一的點(diǎn)擊事件
*/
private void addView() {
TextView textView = new TextView(this);
//獲取當(dāng)前時(shí)間并格式化
String currentTime = dateToStamp(System.currentTimeMillis());
textView.setText("測(cè)試一..."+currentTime);
textView.setTextColor(getResources().getColor(R.color.colorAccent));
linearLayout.addView(textView,0);
}
/**
* 按鈕二的點(diǎn)擊事件
*/
private void addviewTwo() {
TextView textView = new TextView(this);
//獲取當(dāng)前時(shí)間并格式化
String currentTime = dateToStamp(System.currentTimeMillis());
textView.setText("測(cè)試二..."+currentTime);
textView.setTextSize(20f);
textView.setTextColor(getResources().getColor(R.color.colorPrimary));
linearLayout.addView(textView,1);
}
/**
*格式化事件
*/
public String dateToStamp(long s) {
String res;
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(s);
res = simpleDateFormat.format(date);
} catch (Exception e) {
return "";
}
return res;
}
}
此時(shí)我們可以看到我們的按鈕使用的是 addview(view,index)茁裙,這個(gè)方法塘砸。首先button1的是addView(view,0),button2的是addview(view,1)晤锥,讓我們來(lái)看一下效果掉蔬。
點(diǎn)擊兩次button1后,如下圖:
可以看到新添加的數(shù)據(jù)都在最上面的第一個(gè)矾瘾。由此我們可以得出女轿,addView(view,0),在LinearLayout中在在頂部添加view。
接下來(lái)我們點(diǎn)擊幾次button2壕翩,看看效果
按鈕二的index的值是1蛉迹,根據(jù)效果來(lái)看addView會(huì)一直在第二層中添加view。
總結(jié)一下可以知道在LinearLayout中使用addView(view,index),當(dāng)index=0時(shí)放妈,會(huì)在頂層添加view北救,也就是第一層添加。當(dāng)index=1時(shí)芜抒,會(huì)在第二層添加view珍策。
2.2、RelativeLayout中使用
我們將布局文件中的LinearLayout變?yōu)镽elativeLayout
<RelativeLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--一開(kāi)始就存在的數(shù)據(jù)-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開(kāi)始存在的數(shù)據(jù)"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</RelativeLayout>
當(dāng)點(diǎn)擊按鈕時(shí)
可以看出來(lái)addView(view,index)宅倒,在RelativeLayout中使用就是添加view層攘宙,當(dāng)index=0是就會(huì)在最底層也就是第一層添加view層。當(dāng)index=1時(shí),就會(huì)在第二層添加view層模聋。
2.3 在其他布局文件中的效果和在RelativeLayout中是一樣的肩民。
3、方法分析
3.1链方、addView(view,index)分析
這里我們會(huì)想傳index的值是負(fù)數(shù)會(huì)是是怎樣的效果呢持痰?,比如index=-1祟蚀?我們改一下代碼工窍,試一下效果
private void addView() {
TextView textView = new TextView(this);
String currentTime = dateToStamp(System.currentTimeMillis());
textView.setText("測(cè)試一..."+currentTime);
textView.setTextColor(getResources().getColor(R.color.colorAccent));
linearLayout.addView(textView,-1);
}
我們修改成上面的代碼,運(yùn)行一下:
ok,我們發(fā)現(xiàn)會(huì)一直在最下面的一層添加view前酿,為什么會(huì)這樣患雏,我們點(diǎn)開(kāi)源碼來(lái)看一下,其中源碼中有一句對(duì)index的判斷罢维,如下:
if (index < 0) {
index = mChildrenCount;
}
addInArray(child, index);
源碼中如果index<0了淹仑,就將index賦值成了布局中子view的個(gè)數(shù)。有興趣的可以去看源碼肺孵。
3.2 addView(view) 分析
如果我們?cè)赼ddView中不傳參數(shù)會(huì)怎么樣呢匀借?我們繼續(xù)修改代碼運(yùn)行一下測(cè)試
private void addView() {
TextView textView = new TextView(this);
String currentTime = dateToStamp(System.currentTimeMillis());
textView.setText("測(cè)試一..."+currentTime);
textView.setTextColor(getResources().getColor(R.color.colorAccent));
linearLayout.addView(textView);
}
可以發(fā)現(xiàn)沒(méi)有傳index的時(shí)候,效果和傳入index小于0的效果是一樣的平窘,這是為什么呢吓肋?我們繼續(xù)點(diǎn)入源碼看:
public void addView(View child) {
addView(child, -1);
}
看源碼發(fā)現(xiàn)當(dāng)沒(méi)有傳index值的時(shí)候,會(huì)默認(rèn)index=-1瑰艘,此時(shí)就仍然在最下面添加view是鬼。
3.3 其他的都是比較簡(jiǎn)單的添加參數(shù),我們這里貼出源碼就不細(xì)說(shuō)了
addView(View child, int width, int height)
public void addView(View child, int width, int height) {
final LayoutParams params = generateDefaultLayoutParams();
params.width = width;
params.height = height;
addView(child, -1, params);
}
addView(View view, ViewGroup.LayoutParams params)
public void addView(View child, LayoutParams params) {
addView(child, -1, params);
}
三紫新、總結(jié)
addView動(dòng)態(tài)添加代碼的方法均蜜,在LiearLayout中會(huì)在豎直或者水平方向添加子view,在RelativeLayout中會(huì)增加view的層級(jí)數(shù)芒率。
感謝以下大神的資料
Android動(dòng)態(tài)添加View之a(chǎn)ddView的用法
Android使用addView動(dòng)態(tài)添加組件