Android交流

Android基础View详解

2021-08-13  本文已影响0人  帅次

View的继承关系

在Android系统中,任何可视化控件都需要从android.view.View类继承。而任何从android.view.View继承的类都可以称为视图(View)。Android的绝大部分UI组件都放在android.widget包及其子包,下图就是android.widget包中所有View及其子类的继承关系:

image

从上图看,有很多布局类等为什么没有在上图看到,在这里要说明一下这里仅是android.widget包的,还有其他视图的虽然也继承View但是他们不属于android.widget包例如下面两个组件:

RecyclerView继承ViewGroup,但是属于androidx.recyclerview.widget包的。

ConstraintLayout继承ViewGroup,但是属于androidx.constraintlayout.widget包的;

其他还有很多其他包、或自定义控件,这里就不做过多描述了。

Android中的视图类可分为3种:布局(Layout)类视图容器(View Container)类视图类(例TextView),这3种类都是android.view.View的子类。ViewGroup是一个容器类,该类也是View的重要子类,所有的布局类和视图容器类都是ViewGroup的子类,而视图类直接继承自View类。
下图描述了View、ViewGroup、视图容器类及视图类的继承关系。

image

从上图所示的继承关系可以看出:

对于一个Android应用的图形用户界面来说,ViewGroup作为容器来装其他组件,而ViewGroup里除了可以包含普通View组件之外,还可以再次包含ViewGroup组件。

image

创建View对象

使用XML布局定义View,再用代码控制View

XML布局文件是Android系统中定义视图的常用方法,所有的XML布局文件必须保存在res/layout目录中。XML布局文件的命名及定义需要注意如下几点:

举例

1.创建activity_view.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/color_666666"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tv_xml"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="@dimen/dimen_20"
        android:background="@color/color_188FFF"
        android:padding="@dimen/dimen_10"
        android:text="XML设置TextView"
        android:textColor="@color/white"
        android:textSize="@dimen/text_size_18" />
    <Button
        android:id="@+id/btn_xml"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="@dimen/dimen_20"
        android:background="@color/color_188FFF"
        android:padding="@dimen/dimen_10"
        android:text="按钮"
        android:textColor="@color/white"
        android:textSize="@dimen/text_size_18" />
</LinearLayout>

2.加载布局文件、关联控件

如果要使用上面的XML布局文件(activity_view.xml),通常需要在onCreate方法中使用setContentView方法指定XML布局文件的资源lD,并获取在activity_view.xml文件中定义的某个View,代码如下:

public class ViewActivity extends AppCompatActivity{
    private Button btnXml;
    private TextView tvXml;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //加载布局文件
        setContentView(R.layout.activity_view);
        //如果想获得在activity_view.xml文件中定义的某个View
        //关联控件:R.id.tv_xml是tvXml的ID,确保这个ID在R.layout.activity_view中
        tvXml = findViewById(R.id.tv_xml);
        //关联控件:R.id.btn_xml是btnXml的ID,确保这个ID在R.layout.activity_view中
        btnXml = findViewById(R.id.btn_xml);
    }
}

3.在获得XML布局文件中的视图对象时需要注意下面几点:

4.用代码控制视图

虽然使用XML布局文件可以非常方便地对控件进行布局,但若想控制这些控件的行为,仍然需要编写Java代码。在上面介绍了使用findViewByld方法获得指定的视图对象,当获得视图对象后,就可以使用代码来控制这些视图对象了。例如,下面的代码获得了一个TextView对象,并修改了TextView的文本。

TextView tvXml = findViewById(R.id.tv_xml);
//直接使用字符串来修改TextView的文本
tvXml.setText("帅次");
//使用字符串资源(res/values/strings.xml)
//其中R.string.str_tv_shuaici是字符串资源ID,系统会使用这个ID对应的字符串设置TextView的文本。
tvXml.setText(R.string.str_tv_shuaici);

选择其中一样即可,如果同时设置,最后一次设置为最终结果。

使用代码的方式来创建View对象

在更高级的Android应用中,往往需要动态添加视图。要实现这个功能,最重要的是获得当前的视图容器对象,这个容器对象所对应的类需要继承ViewGroup类。
将其他的视图添加到当前的容器视图中需要如下几步:

实例

1.获得当前的容器视图对象

//1、获取activity_view.xml中LinearLayout对象
 //2、也可以给LinearLayout添加@+id/,然后通过findViewById关联控件也能获取LinearLayout对象
LinearLayout linearLayout =
        (LinearLayout)getLayoutInflater().inflate(R.layout.activity_view,null);
//加载布局文件
setContentView(linearLayout);

2.获得或创建待添加的视图对象

EditText editText = new EditText(this);
editText.setHint("请输入内容");

3.将相应的视图对象添加到容器视图中

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //1、获取activity_view.xml中LinearLayout对象
        //2、也可以给LinearLayout添加@+id/,然后通过findViewById关联控件也能获取LinearLayout对象
        LinearLayout linearLayout =
                (LinearLayout)getLayoutInflater().inflate(R.layout.activity_view,null);
        //加载布局文件
        setContentView(linearLayout);
        EditText editText = new EditText(this);
        editText.setHint("请输入内容");
        linearLayout.addView(editText);
    }

效果图如下:


image

总结

自定义View

为什么要自定义View

Android系统提供了一系列的原生控件,但这些原生控件并不能够满足我们的需求时,我们就需要自定义View了。

自定义View的基本方法

自定义View的最基本的三个方法分别是: onMeasure()、onLayout()、onDraw();
View在Activity中显示出来,要经历测量、布局和绘制三个步骤,分别对应三个动作:measure、layout和draw。

image

需要用到的两个对象

这两个方法暂时了解就行,如果拓展开,这不够写,后面可能会针对这两个对象单独拉一个章节出来。

自绘控件View实例

1、直接继承View类

自绘View控件时,最主要工作就是绘制出丰富的内容,这一过程是在重写的onDraw方法中实现的。由于是View,它没有子控件了,所以重写onLayout没有意义。onMeasure的方法可以根据自己的需要来决定是否需要重写,很多情况下,不重写该方法并不影响正常的绘制。

/**
 * 创建人:scc
 * 功能描述:自定义View
 */
public class CustomView extends View {
    private Paint paint;
    //从代码创建视图时使用的简单构造函数。
    public CustomView(Context context) {
        super(context);
    }
    //从XML使用视图时调用的构造函数。
    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    //View的绘制工作
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //实例化画笔对象
        paint = new Paint();
        //给画笔设置颜色
        paint.setColor(Color.RED);
        //设置画笔属性
        //paint.setStyle(Paint.Style.FILL);//画笔属性是实心圆
        paint.setStyle(Paint.Style.STROKE);//画笔属性是空心圆
        paint.setStrokeWidth(10);//设置画笔粗细
        //cx:圆心的x坐标;cy:圆心的y坐标;参数三:圆的半径;参数四:定义好的画笔
        canvas.drawCircle(getWidth() / 4, getHeight() / 4, 150, paint);
    }
}

2、在布局 XML 文件中使用自定义View

<com.scc.demo.view.CustomView
        android:id="@+id/view_circle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

3、实现效果:

image

性能优化

在自定义View时需要注意,避免犯以下的性能错误:

可进一步了解和优化:

在自定义View时要小心避免调用非必要的方法,因为这样会导致重复强行绘制整个视图层级,消耗宝贵的帧绘制周期。检查清楚View.invalite()和View.requestLayout()方法调用时间位置,因为这会影响整个UI,导致GPU和它的帧速率变慢。

永远不要在View.onDraw()方法中及调用的方法中进行内存分配,避免带来负担。垃圾回收器多次释放内存,会导致卡顿。最好的方式就是在View被首次创建出来时,实例化这些对象。

到这里View基本差不多了,还有其他属性、方法、事件等,在后面的TexView、Button、Layout等中慢慢了解。

上一篇下一篇

猜你喜欢

热点阅读