一、简介
- 所有的可视化控件都是继承自Android.view.View
- 创建方式 第一种xml创建,第二种Java代码创建
- 长度单位 一般写在dimens文件中,通过引用使用
单位 | 说明 |
---|---|
px | 屏幕实际像素,如320*480 |
dp(dip) | 屏幕的物理尺寸,大小为1英寸的1/72 |
sp | 与dp类似,根据用户的字体大小首选项进行的缩放 |
-
布局共有5种布局
LinearLayout 线性布局 分为垂直和水平方向
RelativeLayout 相对布局
TableLayout 表格布局
FrameLayout 框架布局 视图可以重叠
AbsoluteLayout 绝对布局 控件通过坐标放置
二、布局
- weight 权重,控件占的份数,如果容器中的控件权重都相同,则表示均分
- orientation 对于LinearLayout,排列方向,参数vertical和 horizontal
- margin 控件在容器中相距边的距离
- visibility 视图可见设置,三个值,visible、invisible、gone(把控件视图直接移除了)
- gravity 调整显示方式,居中啥的
- layout_x、layout_y AbsoluteLayout指定坐标
- layout_below、layout_above、layout_toLeftOf、layout_toRightOf RelativeLayout设置
- padding 控件上下左右距离
三、View 和ViewGroup
- Android 的UI 界面都是由 View 和ViewGroup及其派生类组合而成
- View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器。其本身也是从View派生出来的
-
View派生出的直接子类:
AnalogClock
ImageView
KeyboardView
ProgressBar
SurfaceView
TextView
ViewGroup
ViewStub -
ViewGroup派生出的直接子类:
AbsoluteLayout
AdapterView
FragmentBreadCrumbs
FrameLayout
LinearLayout
RelativeLayout
SlidingDrawer -
静态动态加载布局
include
ViewStup
四、自定义控件
- View是Android最基本的一种UI组件
- ViewGroup是一种特殊的View,可以包含多个子View和子ViewGroup
- 所有控件都直接或者间接继承自View
- 所有布局都直接或间接继承自ViewGroup
- 直接引入布局有两种方式include和ViewStup
- 当布局中有相应事件时,就需要自定义控件
4.1 引入布局
定义一个布局title
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_return"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="return"
android:layout_weight="1"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Title"
android:layout_weight="1"/>
<Button
android:id="@+id/btn_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edit"
android:layout_weight="1"/>
</LinearLayout>
引入
<include layout="@layout/title"/>
4.2 自定义控件
创建一个继承View或者View子类的类
public class TitleLayout extends LinearLayout {
private static final String TAG = "TitleLayout";
public TitleLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.title, this);
Button btn_return = findViewById(R.id.btn_return);
Button btn_edit = findViewById(R.id.btn_edit);
btn_edit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: Edit");
}
});
btn_return.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
((Activity)getContext()).finish();
}
});
}
}
使用自定义控件
<com.example.jony.customdemo1.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
注1:LayoutInflater.from(context).inflate(R.layout.title, this);
通过LayoutInflater的from()方法构建一个LayoutInflater对象,该对象调用inflate()方法动态加载一个布局文件,inflate()方法两个参数,第一个布局文件id,第二个参数是给加载好的布局再添加一个父布局
注2: ((Activity)getContext()).finish();
获得所在的上下文,并销毁,此例是直接在activity_main,所以点击就直接销毁主Activity,程序退出
带有自定义属性的自定义控件
自定义
public class CustomView extends View {
private boolean showtext;
private int labelPosition;
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, 0,0);
try {
showtext = a.getBoolean(R.styleable.CustomView_showText, false);
labelPosition = a.getInt(R.styleable.CustomView_labelPosition, 0);
}finally {
a.recycle();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
setBackgroundColor(Color.RED);
super.onDraw(canvas);
}
}
在values文件夹下创建attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="showText" format="boolean" />
<attr name="labelPosition" format="enum">
<enum name="left" value="0"/>
<enum name="right" value="1"/>
</attr>
</declare-styleable>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:custome="http://schemas.android.com/apk/com.example.jony.customdemo1"
tools:context="com.example.jony.customdemo1.MainActivity">
<!--使用自定义控件-->
<com.example.jony.customdemo1.CustomView
android:layout_width="100dp"
android:layout_height="20dp"
custome:showText="true"
custome:labelPosition="left"/>
</android.support.constraint.ConstraintLayout>
注:xmlns:custome="http://schemas.android.com/apk/com.example.jony.customdemo1"
自定义的命名空间,最后是应用的包名