Android自定义View

本文介绍了Android自定义View的原理和实现方法,包括自绘控件、重写控件和组合控件等,并提供了详细的步骤说明及案例分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android自定义View

什么是自定义View?

通过直接继承或者重写View子类实现逻辑的View,称之为自定义View。

为什么要自定义View?

在实际项目中android 自带的View无法满足特定的需求,所以需要扩展或者修改原生View,满足特定的需求;

android自带View结构

这里写图片描述

自定义View类型?

  • 自绘控件:直接继承View类的方式自绘控件。
  • 重写控件:简介继承View子类的方式是重写控件。
  • 组合控件:简介继承View子类,需要用到原生控件组合到一起。

下面以案例的形式记录自己所学的这几种自定义View。


自绘控件:

使用步骤:

* 继承View
* 实现接口Listener接口(没有可以不用)
* 重写构造方法(两个参数的)
* 重写onDraw方法
* Paint画笔
* Canvas绘制
* invalidate方法刷新
* 在布局文件中引用

画笔的常用方法及解释:

* setAntilias():设置画笔的锯齿效果
* setColor():设置画笔颜色
* setARGB():设置画笔的A.R.G.B值
* setAlpha():设置画笔的透明度
* setStyle():设置画笔的风格(空心或者实心)
* setStrokeWidth():设置空心边框的宽度
* getColor():获取画笔的颜色
* setTextSize():设置字体的尺寸

画布的常用方法及解释:

* drawLine():绘制直线
* drawCircle():绘制圆形
* drawBirmap():绘制图形
* drawRect():绘制矩形
* drawText():绘制字符

invalidate()方法:调用这个方法后,会再次 执行onDraw()方法

案例一:绘制计数器

这里写图片描述

第一步:创建一个类,继承View

package com.lenovo.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CountNumView extends View {


}

第二步:重写构造方法,两个参数的

  public CountNumView(Context context, AttributeSet attrs) {
  super(context, attrs);
  }

第三步:重写onDraw()方法

@Override
  protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
//创建画笔
  Paint p = new Paint();
//设置画笔颜色
  p.setColor(Color.RED);
//绘制圆形画布:参数
//圆心的x轴,圆心的y轴,半径大小,画笔
  canvas.drawCircle(getWidth()/2, getHeight()/2, 150, p);
  }

第四步:在布局中调用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lenovo.activity.MainActivity" >

    <com.lenovo.view.CountNumView

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        />

</RelativeLayout>

重写控件

步骤:

1. 新建一个类继承系统提供的View
2. 重写对应的构造方法
3. 实现逻辑并定义时间监听
4. 在布局文件中引用

四个案例在一起:
这里写图片描述

案例一:重写Button实现自定义返回Button

第一步:新建一个类继承Button

public class FinishButtonView extends Button implements OnClickListener{
}

第二步:构造方法(两个参数的)

     private Activity mActivity;

     // 实现构造方法
     public FinishButtonView(Context context, AttributeSet attrs) {
           super(context, attrs);
           //获取到activity
           mActivity = (Activity) getContext();
           //设置监听
           this.setOnClickListener(this);

     }

第三步:监听销毁页面

//监听
     @Override
     public void onClick(View v) {
           //销毁页面
           mActivity.finish();
     }

第四步:在布局中引用(控件名称是包名+类名)

    <com.example.view.FinishButtonView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="销毁页面" />
案例二:重写ImageView实现自定义相框

第一步:新建一个类继承ImageView

public class CustomImageView extends ImageView{
}

第二步:构造方法(两个参数的),并初始化画笔

private Paint mPain;

     //构造方法
     public CustomImageView(Context context, AttributeSet attrs) {
           super(context, attrs);
           init();
     }

     //初始化画笔
     private void init() {
           mPain = new Paint();
           mPain.setColor(Color.RED);
           //空心
           mPain.setStyle(Paint.Style.STROKE);
           //宽度
           mPain.setStrokeWidth(10);
     }

第三步:重写onDraw方法

     //重写onDraw方法
     @Override
     protected void onDraw(Canvas canvas) {
           super.onDraw(canvas);
           //得到图片边缘轮廓
           Rect bounds = canvas.getClipBounds();
           bounds.bottom--;
           bounds.right--;
           canvas.drawRect(bounds, mPain);
     }

第四步:在布局中引用

    <com.example.view.CustomImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"      
        android:src="@drawable/ic_launcher"
        />
案例三:重写ListView实现下拉刷新

提示:只是实现了样式,没有实现功能。

首先,建立一个头部布局:
这里写图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="下拉刷新" />

</LinearLayout>

* PS:必须是Linear Layout布局 *

第一步:新建一个类继承ListView

public class CustomListView extends ListView {}

第二步:构造方法(两个参数的)

     // 阻尼系数
     private double damping = 0.3;
     // 视图
     private View view;
     public CustomListView(Context context, AttributeSet attrs) {
           super(context, attrs);
           // 绑定布局
           view = View.inflate(context, R.layout.header, null);
           // 测量模式
           view.measure(0, 0);
           // 获取高度
           height = view.getMeasuredHeight();
           // 隐藏头部
           view.setPadding(0, -height, 0, 0);
           // 添加到头部
           addHeaderView(view);

     }

第三步:监听手势

// 高度
     private int height;
     // 按下
     private int downY;
     // 滑动
     private int moveY;
   // 手势监听
     @Override
     public boolean onTouchEvent(MotionEvent ev) {

           switch (ev.getAction()) {
           // 按下
           case MotionEvent.ACTION_DOWN:
                downY = (int) ev.getY();
                break;
           // 抬起
           case MotionEvent.ACTION_UP:
                // 隐藏头部
                view.setPadding(0, -height, 0, 0);
                // 刷新
                view.invalidate();
                break;
           // 移动
           case MotionEvent.ACTION_MOVE:
                // 获取滑动Y
                moveY = (int) ev.getY();
                // 下拉
                view.setPadding(0, (int) (((moveY - downY) - height) * damping), 0, 0);
                // 刷新
                view.invalidate();
                break;

           }

           return super.onTouchEvent(ev);

     }

第四步:引用,填充数据,这里不再赘述,不会的可以去看看我之前写的。
BaseAdapter
ArrayAdapter

组合控件

案例一:将多个控件组合在一起使用。

步骤:

1. 新建一个布局
2. 新建类继承跟布局标签
3. 绑定布局

第一步:新建一个布局。
这里写图片描述

二三步:

public class FinishButtonView extends Button implements OnClickListener{

     private Activity mActivity;

     // 实现构造方法
     public FinishButtonView(Context context, AttributeSet attrs) {
           super(context, attrs);
           //获取到activity
           mActivity = (Activity) getContext();
           //设置监听
           this.setOnClickListener(this);

     }

     //监听
     @Override
     public void onClick(View v) {
           //销毁页面
           mActivity.finish();
     }

}

自定义布局就到这里了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值