- 通过前面的学习可以看到自定义一个View的时候,继承View的时候,必须实现一个构造函数,但是有三个构造函数,每一个构造函数都是在特定的场景下所必须实现的,否则会报inflate的错误那么应该如何选择
public RegionTest(Context context) {
super(context);
}
public RegionTest(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RegionTest(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
- 下面来看两种引入的方式:
- xml文件引入
- 动态引入
- xml文件引入:
- 使用
public RegionTest(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
- 首先自定义一个View,分别在三个构造函数中打印信息从日志中也会发现调用的是什么构造函数
- xml文件引入:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical">
<com.example.adminstator.myviewdesign.RegionTest.RegionTest
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</LinearLayout>
- 动态添加控件:
- xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="wjx"/>
</LinearLayout>
* 在活动中添加动态加载控件的部分
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout rootView = (LinearLayout) findViewById(R.id.root);
PaintTest paintTest = new PaintTest(this);
LinearLayout.LayoutParams layoutParams = new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
rootView.addView(paintTest, layoutParams);
}
-
在添加子控件的时候,需要先找到要添加子空间的节点的实例,比如上述中的LinearLayout的实例,然后通过rootView.addView()将生成的子空间实例添加到LinearLayout中
-
LayoutParams:
- 在xml中添加控件时 ,layout_width, layout_height是必须设置的属性,取值有fill_parent, match_parent, wrap_content以及具体的值,就是为了告诉父控件布局的样式,同样LayoutParams的作用就是为了设置控件的宽和高,对应于xml中的属性
-
LayoutParams的三个构造函数:
//用于指定具体的宽和高,取值有LayoutParams.MATCH_PARENT
LayoutParams.FILL_PARENT和具体值
public LayoutParams(int width, int height)
//下面两个构造函数不太常用
//用于从AttributeSet中取出参数的相关值
public LayoutParams(Context context, AttributeSet attrs)
//直接从现成的LayoutParams中复制 一份内容
public LayoutParams(LayoutParams source)
- 在四大布局中都有自己相应的设置布局参数的方法,既然每个布局都要实现一套LayoutParams类,那么我们在动态添加布局的时候,直接使用xxxLayout.LayoutParams即可,如果使用错误,那么会在addView中进行强制转换,成功与否取决于是否具有相同的的属性,成功的话不会报错,不成功报错。
- RelativeLayout要比LinearLayout特殊,因为它不仅要设置上述两个属性还有其他的相对的位置属性
- 复杂的属性的添加通过RelativeLayout.LayoutParams的addRule()函数
public void addRule(it verb, int anchor);
- 设置margin:
layoutParams.setMargins(10, 20, 30, 40);
- 设置layout_weight:
//提供一个构造函数
public LayoutParams(int width, int height, float weight)
//或者使用常用的构造控件属性的方法 并加上
layoutParams.weight = 1.0f;
- 设置layout_gravity:
layoutParams.gravity = Gravity.TOP;
//其他属性
Gravity.BOTTOM
Gravity.LEFT
Gravity.RIGHT
Gravity.CENTER_VERTICAL
不同属性之间可以使用 | 连接
- 设置android:gravity:
- 如果不设置该属性空间内的控件则会在左上角显示
button.setGravity(上面的属性)
rootView.setGravity(上面的属性)
- addView(),动态添加控件都是用这个函数来实现,是viewGroup中的一个函数有五个构造函数:
//在节点末尾添加 一个控件,布局使用默认布局
public void addView(View child)
//在指定位置添加一个View控件,index的取值有 -1、0和正数,-1表示在节点末尾添加一个view控件,此时的效果就与addView(View child)相同; 0表示在容器顶端添加一个View控件;取值为正数的时候,表示在对应的索引位置插入一个view控件
public void addView(View child, int index)
//自定义布局参数
public void addView(View child, LayoutParams params)
//自定义布局参数和指定位置
public void addView(View child, int index, LayoutParams params)
//指定宽和高,内部会利用传入的width, height属性构造出一个LayoutParams对象
public void addView(View child, int width, int height)