在一個ViewGroup中新增子view
阿新 • • 發佈:2019-02-13
所有的Android中的控制元件都是繼承於View,ViewGroup也不例外。在ViewGroup中有個addView的方法能動態的新增一個子view。
這個是一個簡單的例子,能在程式碼中動態的新增一個子view:
示例圖片:
package com.example.foreveross.myapplication; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.RecyclerView; import android.view.Gravity; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private LinearLayout mLay; private Button mBtn1; private Button mBtn2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); initEvent(); } private void initEvent() { mBtn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mBtn2.setBackgroundColor(Color.RED); } }); } private void initData() { TextView tv = new TextView(this); tv.setText("動態新增的"); tv.setGravity(Gravity.CENTER); tv.setTextSize(20); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); mLay.addView(tv, layoutParams); } private void initView() { mLay = (LinearLayout) findViewById(R.id.llay); mBtn1 = (Button) findViewById(R.id.btn1); mBtn2 = (Button) findViewById(R.id.btn2); } }
1.關於ViewGroup的原始碼也翻看了一些:
關於addView有下面幾種方法過載:
1.直接傳入一個view進行新增:
public void addView(View child) {
addView(child, -1);
}
2.傳入子view,並設定子view在ViewGroup中的子view的插入位置:3.新增子view,並設定新增view的寬高:public void addView(View child, int index) { if (child == null) { throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup"); } LayoutParams params = child.getLayoutParams(); //獲取子view的layout引數 if (params == null) { params = generateDefaultLayoutParams(); if (params == null) { throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null"); } } addView(child, index, params); }
public void addView(View child, int width, int height) {
final LayoutParams params = generateDefaultLayoutParams();
params.width = width;
params.height = height;
addView(child, -1, params);
}
4.新增子view,並傳入view的layout的引數:
5.最終所有的addview的方法都會呼叫如下方法:public void addView(View child, LayoutParams params) { addView(child, -1, params); }
public void addView(View child, int index, LayoutParams params) {
if (DBG) {
System.out.println(this + " addView");
}
if (child == null) {
throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
// addViewInner() will call child.requestLayout() when setting the new LayoutParams
// therefore, we call requestLayout() on ourselves before, so that the child's request
// will be blocked at our level
requestLayout(); //當view的佈局失效改變時會呼叫這個,它會按規則重新佈局view的樹(view tree)
invalidate(true);
addViewInner(child, index, params, false); //call子view
}
所以當加入子view時必須設定LayoutParams的值,對於LayoutParams只是傳入子view的寬高和位置的資訊:
public LayoutParams(Context c, AttributeSet attrs); //傳入xml檔案中設定的屬性值,存於R檔案中
public LayoutParams(int width, int height); //直接傳入寬高的值
public LayoutParams(LayoutParams source) //傳寬高的source值
protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr); //佈局setLayoutDimension之後的寬高值 在這裡有一個MarginLayoutParams是繼承於LayoutParams的,能在這裡設定Margin的值總結與感悟:
之前開發過程中不習慣於去檢視原始碼,對一些API都只是存在只會用不知道其中的原理
及當中的流程執行過程。當自己真正的靜下心來去看原始碼的過程中無形之中汲取了原始碼
中優秀精簡的程式設計精華,不積跬步無以至千里。相信當量的積累到一定程度那必然
是質的飛越!!!