自定义View开发笔记(ing)

简介: 自定义View开发笔记(ing)
最近拜读一本书—— 《Android自定义控件开发入门与实战》,感慨良多,实为佳作,这里做做笔记摘录,写写自己的心得,作巩固分享之用;

画弧原理

  • 首先上Canvas下画弧函数源码:
    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) {
        throw new RuntimeException("Stub!");
    }

    public void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) {
        throw new RuntimeException("Stub!");
    }
  • 参数意义:

oval :用于确定圆弧形状与尺寸的椭圆边界(即椭圆外切矩形)
startAngle :开始角度(以时钟3点的方向为0°,逆时针为正方向
sweepAngle : 扫过角度(以时钟3点的方向为0°,逆时针为正方向
useCenter:是否有弧的两边,为true时带有两边,为false时不带,只有一条弧;
paint:绘制圆弧的画笔

  • 绘制圆弧原理
  • RectF(float left, float top, float right, float bottom)得到一个矩形,

此虚拟矩形内切绘制一个椭圆(如果长和宽相等,则为圆)。

  • 以矩形的中心为圆心,以时钟3点的方向为0°,

由中心以0°径向画出一条射线,
逆时针为正方向
从0°正方向旋转startAngle度,
射线和矩形内切椭圆相交得到一条直线段和一个交点。

  • 从这条直线开始,以顺时针为正方向,射线旋转sweepAngle度,

矩形内切椭圆相交,得到另一条直线段和交点,
这样一来,
**前后两个交点圆弧的两个端点
射线在这两条交线之间扫过的扇面外弧,即所画圆弧。**

相关阅读:


单词普及

  • intersect.

美 [ˌɪntərˈsekt]
vt.横断,横切,横穿;
vt.& vi.(指线条、道路等)相交,交叉;

  • cruncher.

美 [k'rʌntʃər]
[计]数字计算器;


postInvalidate()、invalidate()之别

  • postInvalidate()和invalidate()都是用来重绘控件的,

区别是invalidate()一定要在主线程中执行,否则就会报错;
而postInvalidate()函数则没有那么多讲究,
它可以在任何线程中执行,而不必一定是主线程,


关于addView()、removeView()

关于add、remove的速度
  • 下面代码案例中:

SpiderView是一个自定义控件,
ll_nextParent 是主布局下的一个LinearLayout,
现在在这个LinearLayout下做组件增删操作;

public class MainActivity extends AppCompatActivity {

    private LinearLayout ll_nextParent;
    private SpiderView spiderViewOri;
    private LinearLayout.LayoutParams layoutParams;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        configCustomViews(0);
    }

    private void initViews() {

        ll_nextParent = findViewById(R.id.ll_nextParent);

        layoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);

        ll_nextParent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //经过这个测试,这里的删除添加是毫秒级别的,
                // 添加之后删除的速度人眼分辨不出

                Toast.makeText(MainActivity.this, "shanchu", Toast.LENGTH_SHORT).show();
                ll_nextParent.removeView(spiderViewOri);

//                TextView test = new TextView(MainActivity.this);
//                test.setText("sdadasdasdada");
//                ll_nextParent.addView(test);

                Toast.makeText(MainActivity.this, "tianjia", Toast.LENGTH_SHORT).show();
                ll_nextParent.addView(spiderViewOri, layoutParams);
            }
        });
    }


    private void configCustomViews(int drawId) {
        switch (drawId) {
            case 0:
                spiderViewOri = new SpiderView(this);
                ll_nextParent.addView(spiderViewOri, layoutParams);
                break;

            case 1:
                break;

            default:
        }
    }

}
  • 运行的时候,

我们点击触发回调,先删后加(先removeView后addView),
而这个过程中呢,
更新布局的速度是毫秒级的,
人眼无法分辨;
后续在做根布局增删组件的时候,可以利用这个点;


关于报错

Bug.1

场景:主布局中,
LinearLayout1下套ScrollView,
ScrollView下套LinearLayout2,
LinearLayout2中添加复杂的自定义View,
比如SpiderView

此时如果不做任何处理的话,
运行时一般那个复杂的自定义View是 不会被渲染出来的,
并且会报下面这个错:
Skipped xxx frames! The application may be doing too much work on its main thread
跳帧过多,程序在主线程中做了太多事情了,需要优化逻辑


关于自定义控件的宽高

**所有的自定义控件在被引入布局时,
layout_width和layout_height属性的值默认都是match_parent,
当然可以通过测量控件大小以使用wrap_content**


自定义组件引入

有xml引入和动态添加两种方法;


如何通过文件名拿到对应的资源ID


getIdentifier()函数的完整声明如下:

  • int getIdentifier(String name,String defType,String defPackage)
  • String name:所要查找资源ID的资源名称。
  • String defType:资源所在的文件类型。
  • String defPackage:应用包名。

由于我们的图片资源在drawable系列文件夹中,所以defType就是“drawable”。

  • 如果想获得string,则可以这样写:

getResources().getIdentifier("name","string",packdgeName);

  • 如果想获得array中的数组,则可以这样写:

getResources().getIdentifier("name","array",packdgeName);
















相关文章
|
Kubernetes 关系型数据库 MySQL
Helm入门(一篇就够了)
Helm入门(一篇就够了)
551 0
|
JavaScript Shell Android开发
安装使用Frida在Android上进行hook
我们对Android应用进行hook最常用的就是Xposed,它相对来说更加完善,而且有强大的社区和丰富的插件。而Frida则于Xposed不同,它是一款轻量级的Hook框架,可用于多平台,相同的是它依然需要root环境。本文就以Android为例来详细说说如何安装并使用它。
761 0
|
10月前
|
机器学习/深度学习 传感器 算法
《DeepSeek赋能工业互联网:大幅提升设备故障诊断准确率》
DeepSeek技术通过多源数据融合、深度学习算法和实时在线监测,大幅提升工业互联网中设备故障诊断的准确性和及时性。它整合振动、温度、压力等多类型数据,构建精准故障模型,支持钢铁、化工、电力等行业的设备状态全面感知。DeepSeek还具备持续学习能力,适应复杂多变的工业场景,确保长期稳定的高精度故障诊断,助力企业实现高效、安全的生产运营。
812 3
|
Kubernetes Java 编译器
解锁极致性能:Quarkus如何让JVM应用调优变得前所未有的简单与高效!
Quarkus是一款专为GraalVM和OpenJDK设计的Kubernetes Native Java框架,采用AOT编译技术将Java应用转化为本地代码,大幅提升启动速度与运行效率。它简化了性能调优流程,如自动优化垃圾回收、类加载、内存管理及线程管理等,使开发者无需深入理解JVM细节即可轻松提升应用性能。与传统JVM应用相比,Quarkus显著降低了性能调优的复杂度。
379 2
|
10月前
|
API 开发工具 Python
阿里云PAI部署DeepSeek及调用
本文介绍如何在阿里云PAI EAS上部署DeepSeek模型,涵盖7B模型的部署、SDK和API调用。7B模型只需一张A10显卡,部署时间约10分钟。文章详细展示了模型信息查看、在线调试及通过OpenAI SDK和Python Requests进行调用的步骤,并附有测试结果和参考文档链接。
3717 11
阿里云PAI部署DeepSeek及调用
|
数据采集 数据可视化 数据挖掘
爬虫技术对携程网旅游景点和酒店信息的数据挖掘和分析应用
爬虫技术是一种通过网络爬取目标网站的数据并进行分析的技术,它可以用于各种领域,如电子商务、社交媒体、新闻、教育等。本文将介绍如何使用爬虫技术对携程网旅游景点和酒店信息进行数据挖掘和分析,以及如何利用Selenium库和代理IP技术实现爬虫程序
1344 0
|
存储 Kubernetes 搜索推荐
使用容器方式创建firecracker虚拟机
使用容器方式创建firecracker虚拟机
630 1
|
存储 运维 Cloud Native
数据库技术的前沿探索:创新、挑战与未来机遇
一、引言 数据库技术作为信息化社会的基础设施,一直在不断演进以适应日益复杂的数据处理需求
1255 0
|
Android开发
android|Magisk注入Zygisk的过程
android|Magisk注入Zygisk的过程
1665 1
 android|Magisk注入Zygisk的过程