关于自定义组件-以apidemo中的LabelView进行讲解

Word论文插入带有方括号序号的参考文献——尾注+交叉引用 文章目录1. 尾注功能2. 为参考文献的序号添加方括号3. 调整参考文献前的序号大小4. 重复引用同一参考文献5. 将交叉引用的序号改为带有方括号的上标序号格式6. 删除参考文献前的尾注横线 1. 尾注功能 首先使用尾注功能顺序插入参考文献,暂时不考虑方括号问题,具体操作如下: ① 将光标放在需要插入参考文献角标的地方 ② 在word菜单栏,“引用-脚注部分右下角箭头”(用来设置尾注格式) ③如... 阅读详情

对于自定义组件,可以有两种方式,一种是继承View,重写里面的onDraw()函数,或者继承ViewGroup或者子类,自定义组合类型的组件。

下面以apidemo为例子进行讲解

下面是代码,我又进行了重新注释,应该好懂点了

1.对于构造函数,单个参数的构造函数是代码new的时候使用的,第二个构造函数是系统反射成对象用的,要想再xml中使用必须有两个参数的那个构造函数。

2.requestLayout();这个方法的作用是把新布局应用上去,但是界面还没刷新。

3.invalidate();这个是用来告诉界面刷新的,调用了这个方法不一定会立刻刷新,会在将来的某一刻刷新,刷新时调用onDraw()方法。

 

具体的一些细节还没有写完,先写到这里,有时间了再补充上去

 

了解一下这些api有利于明白自定义组件的过程

view

http://note.youdao.com/share/?id=1fcf0de6c7bbfec507fdb2b0962708ab&type=note

MessureSpec

http://note.youdao.com/share/?id=b992b2b83cd8ff3245ad5609a9499966&type=note

Paint

http://note.youdao.com/share/?id=735734a14ff01d96690f5c845f18ec7a&type=note

 

/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.apis.view;

// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import com.example.android.apis.R;


/**
 * Example of how to write a custom subclass of View. LabelView
 * is used to draw simple text views. Note that it does not handle
 * styled text or right-to-left writing systems.
 *
 */
public class LabelView extends View {
    private Paint mTextPaint;
    private int mAscent;
    private String mText;
    
    /**
     * Constructor.  This version is only needed if you will be instantiating
     * the object manually (not from a layout XML file).
     * @param context
     */
    public LabelView(Context context) {
        super(context);
        initLabelView();
    }

    /**
     * Construct object, initializing with any attributes we understand from a
     * layout file. These attributes are defined in
     * SDK/assets/res/any/classes.xml.
     * 
     * @see android.view.View#View(android.content.Context, android.util.AttributeSet)
     */
    public LabelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initLabelView();

        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.LabelView);

        CharSequence s = a.getString(R.styleable.LabelView_text);
        if (s != null) {
            setText(s.toString());
        }

        // Retrieve the color(s) to be used for this view and apply them.
        // Note, if you only care about supporting a single color, that you
        // can instead call a.getColor() and pass that to setTextColor().
        setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF000000));

        int textSize = a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0);
        if (textSize > 0) {
            setTextSize(textSize);
        }

        a.recycle();
    }

    private final void initLabelView() {
    	//create text paint to setting text
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);//设置是否抗锯齿
        // Must manually scale the desired text size to match screen density
        mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
        mTextPaint.setColor(0xFF000000);
        setPadding(3, 3, 3, 3);
    }

    /**
     * Sets the text to display in this label
     * @param text The text to display. This will be drawn as one line.
     */
    public void setText(String text) {
        mText = text;
        //Call this when something has changed which has invalidated the layout of this view. This will schedule a layout pass of the view tree. 
        //当有些东西已经改变使这个view的布局已经无效使调用此方法,这个方法会把一个新的布局安排到视图树中去。
        requestLayout();
        //Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate(). 
        //调用这个方法使当前的整个view显示无效,当这个view可见时,将来的某一时刻会调用onDraw(android.graphics.Canvas),这个方法必须在UI线程中调用,如果从非UI线程中调用postInvalidate()方法,从而换成新的显示。
        invalidate();
    }

    /**
     * Sets the text size for this label
     * @param size Font size
     */
    public void setTextSize(int size) {
        // This text size has been pre-scaled by the getDimensionPixelOffset method
        mTextPaint.setTextSize(size);
        requestLayout();
        invalidate();
    }

    /**
     * Sets the text color for this label.
     * @param color ARGB value for the text
     */
    public void setTextColor(int color) {
        mTextPaint.setColor(color);
        invalidate();
    }

    /**
     * @see android.view.View#measure(int, int)
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    	//This mehod must be called by onMeasure(int, int) to store the measured width and measured height. Failing to do so will trigger an exception at measurement time.
        //这个方法必须在onMeasure(int, int)中被调用,去存储测量的宽度和高度。如果不调用的话,在测量期间会抛出异常。
    	setMeasuredDimension(measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
    }

    /**
     * Determines the width of this view
     * @param measureSpec A measureSpec packed into an int
     * @return The width of the view, honoring constraints from measureSpec
     */
    private int measureWidth(int measureSpec) {
        int result = 0;
        //返回测量模式
        int specMode = MeasureSpec.getMode(measureSpec);
        //返回测量的大小
        int specSize = MeasureSpec.getSize(measureSpec);
        //如果模式是准确模式的话,大小只能是指定的大小,即通过传过来的模式得到的大小。
        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
        	//计算这个view的大小:size = 左右空隙的大小+字符串的大小
            result = (int) mTextPaint.measureText(mText) + getPaddingLeft()
                    + getPaddingRight();
            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
            	//在AT_MOST模式,即最大模式的情况下,size只能小于等于指定的大小,大小取指定大小和计算出的大小中的一个最小的。
                result = Math.min(result, specSize);
            }
        }

        return result;
    }

    /**
     * Determines the height of this view
     * @param measureSpec A measureSpec packed into an int
     * @return The height of the view, honoring constraints from measureSpec
     */
    private int measureHeight(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        
        mAscent = (int) mTextPaint.ascent();//返回字体基线上部的大小,返回的是负数
        //关于字体的基线,可以看下我的这个翻译http://note.youdao.com/share/?id=735734a14ff01d96690f5c845f18ec7a&type=note
        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text (beware: ascent is a negative number)
        	//高度=基线上部的大小+基线下部的大小+上下的空隙
            result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop()
                    + getPaddingBottom();
            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    /**
     * Render the text
     * 
     * @see android.view.View#onDraw(android.graphics.Canvas)
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
    }
}


 

华为od 面试八股文_测试/测试开发_01_含答案 华为od面试八股文_测试/测试开发_01_含答案 阅读详情

相关推荐

群晖NAS断电后IP变了?3步搞定静态IP设置(附Linux挂载指南)

本文针对群晖NAS因断电重启导致IP地址变化的问题,提供了从根源到实践的完整解决方案。核心内容包括如何为NAS配置静态IP以彻底解决连接中断,并详细讲解了在Linux系统中通过NFS协议稳定挂载NAS共享文件夹的步骤与指南,确保网络存储服务持久可靠。

weixin_29271263的博客 851

一个label 里面 显示中文和英文不同颜色

- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor yellowColor]; //这个是你请求的 东西 NSString *stringlabel = @"hello的期望Word的期望"; UILabel *label = [[UILabel alloc]...

weixin_30410119的博客 246

mac搭建ios自动化环境之WebDriverAgent配置

一、WebDriverAgent 1、简单介绍: WebDriverAgent是facebook为苹果公司开发的一款自动化测试工具,github上有下载资源;另外appium安装后也会自动安装自带的WebDriverAgent;可以用自带的,也可以从github下载并替换自带的; 2、不同appium版本自带WebDriverAgent默认路径不同 1)appium 1.10.1之前版本: npm方式安装: /usr/local/lib/node_modules/appium/node_modules/a

qq_30237715的博客 2761

在Android系统settings里添加设置选项

目的:在通话设置菜单下,添加一dect设置菜单,里面再添加一checkBOxPreference  来使能硬件模块。  -------------------------  目前做的项目,需要在系统settings里面添加一选项来使能硬件模块,里面涉及到的preference知识,请网上了解,这里记录下方法。  1,settings 应用一般在 目录:\packages\apps\

yzx41099296的专栏 5116

3张RTX 4090就能跑!BAGEL-7B多模态模型本地部署避坑指南(附Flash Attention安装技巧)

本文详细介绍了如何在3张RTX 4090显卡上本地部署BAGEL-7B多模态模型,包括硬件配置、环境设置、多卡并行优化及常见问题解决方案。特别提供了Flash Attention安装技巧和显存优化策略,帮助开发者高效运行这一开源多模态模型,实现文本与图像生成任务。

1a2s3d4f5g的博客 652

RabbitMQ的使用(JAVA)

Java快速上手的MQ上线!

.............. 1万+

如何封装使用api形式调用的vue组件

在实际开发中一般有两种封装vue组件的方法:一种就是常用的的通过props父组件传值给子组件的方法:   子组件    父组件:   还有一种就是通过调用api的形式,下面例子是本人在实际项目中封装的一个自定义图标的弹窗组件 首先实现组件的UI页面(css部分截图不完整) 在vue文件的同目录下新建alertTips.js文件 页面中调用方法: 转载于:ht...

weixin_34223655的博客 1577

GPU加速的容器化AI开发:AnolisOS/CentOS8中的NVIDIA驱动与CUDA最佳实践

本文详细介绍了在AnolisOS/CentOS8系统中配置NVIDIA驱动与CUDA的最佳实践,涵盖驱动安装、CUDA工具链配置、容器运行时设置及性能优化等关键步骤。特别针对容器化AI开发场景,提供了GPU透传和资源管理的实用方案,帮助开发者构建高效的GPU加速开发环境。

weixin_27791839的博客 339

Android 8.0 Settings流程分析与变动

开! 场!  白! 好! 难! 写!一,相比Android Settings 7.0    如下图,在7.0的基础上,去掉了7.0新加的侧滑菜单(可能是觉得有点鸡肋吧)。多加了一级页面,把原来类别标题变成的第一级菜单的子项。在代码架构也稍加变动,并引入架构组件之LifeCycle(生命周期感知,本文不作介绍)。二,第一级菜单的加载浏览源码,大多数我们从程序的AndroidManifest.xml入...

若瑜的博客 1万+

【TC397第23篇】深度解析TC397 EB MCAL开发系列:UART配置与POLL模式数据交互

通过本文,我们深度解析了TC397 EB MCAL开发系列中UART配置的POLL模式下的数据交互。从技术要点的介绍到实际案例的演示,希望读者能够更好地理解UART在POLL模式下的配置与应用。这不仅是对嵌入式系统开发的一次深刻探索,更是为项目提供了一种高效通信的解决方案。在未来的文章中,我们将继续深入研究嵌入式系统开发的各个方面,为广大开发者提供更多实用的技术知识。敬请期待,一同迎接嵌入式技术的新篇章!

一直在水些技术小文 470

道路施工检测 (construction) - 基于Mapillary Vistas数据集的YOLOv11目标检测及UI界面实现

目标检测是计算机视觉的重要任务,目标是识别图像中的目标物体类别及其位置(用边界框表示)。两阶段检测器:如Faster R-CNN,准确度高但速度较慢单阶段检测器:如YOLO系列、SSD,速度快且精度相对较好,适合实时场景数据量:约25,000张高分辨率街景图标注类型:语义分割、实例分割、多类别检测类别示例:construction, road, car, person, traffic sign等格式:COCO风格JSON标注。

YOLO 496

剖析API Demos中的LabelView

对于谷歌给我们提供的ApiDemo里有很多有学习参考价值的实例,今天来学习理解其中的一个实例类LabelView,此类 继承View,并对View中的onMeasure(),Ondraw()方法进行了重写,其中涉及到setMeasuredDimension() , MeasureSpec,Canvas,Paint,以及自定义 属性的一些应用。 像完全自定义控件(也就是继承View自定义控件)

manymore13 的个人专栏 6839

RK3588平台开发系列讲解(SARADC篇)SARADC的工作流程

📢本篇将介绍SARADC的源码分析和工作流程。

内核笔记 3231

View编程(5): 自定义View_01_ApiDemo源码研究

android提供的APIDemo中,在/res/values下面有个attrs.xml文件。 其内容如下: <!-- Copyright (C) 2007 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you m

CodingMan 3874

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Apidemo学习 android 自定义View

哈哈,兄弟我终于自己写了一个view,不是网上那种简单的哦,还是有一定技术含量的, 我是通过学习ApiDemo(android自带的sample)里面LabelView实现的, 先谈谈学习过程,觉得一开始不应当盲目的动手做,应对想把原理搞明白,哪怕一个很小的View,也应当将各个细节弄清楚, 等这些搞定了,接下来的工作就是水道渠成了! 自定义一个View那必须继

梦想无论怎样模糊,总潜伏在我们心底,使我们的心境永远得不到安宁. 750

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

速读原著-Android应用开发入门教程(自定义的视图)

7.3 自定义的视图 自定义的 View 的含义是通过扩展的方法,实现一个扩展 android.view.View 类的类,这个类的本质也是一个控件,通过它可以直接构建 UI。 参考示例程序:CustomView(ApiDemo=>Views=>CustomView ) 源代码:com/example/android/apis/view/CustomView1.java com/exa...

逍遥云恋 599

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

自定义View的界面和行为

Vew对象是所有控件和布局对象的基类, 呈现给用户的界面基本上就一棵view树, 要实现自定义的view对象, 可以继承已有的控件对象,如TextView, Button等,在对其中的一些方法进行重写来覆盖原先控件对象的行为和界面,也可以完全从View对象继承,然后重写VIew对象的一些重要方法,如onMeasure(), onDraw(),(这些on-like方法基本是对象对系统中特定事件所做出

1575

Android中View的绘制过程 onMeasure方法简述 附有自定义View例子

Android中View的绘制过程   当Activity获得焦点时,它将被要求绘制自己的布局,Android framework将会处理绘制过程,Activity只需提供它的布局的根节点。   绘制过程从布局的根节点开始,从根节点开始测量和绘制整个layout tree。   每一个ViewGroup负责要求它的每一个孩子被绘制,每一个View负责绘制自己。   因为整个树是...

weixin_30391339的博客 61

android中onMeasure初看,深入理解布局之一!

原文地址:http://my.oschina.net/banxi/blog/51247 今天学习android自定义组件:docs/guide/topics/ui/custom-components.html 其中有两个对布局界面影响很的方法,onDraw(),和onMeasure(). onDraw()比较好理解.onMeasure()就比较难理解一些,也更复杂些 ,引用文档中

专注Android开发 769

Android中View的绘制过程 onMeasure方法简述 附有自定义View例

http://www.cnblogs.com/mengdd/p/3332882.html Android中View的绘制过程   当Activity获得焦点时,它将被要求绘制自己的布局,Android framework将会处理绘制过程,Activity只需提供它的布局的根节点。   绘制过程从布局的根节点开始,从根节点开始测量和绘制整个layout tree。

宝剑锋从磨砺出,梅花香自苦寒来! 913
上一篇: Android 动画框架详解,第 1 部分
下一篇: android退出应用程序的江湖七招(升级版)
com360
博客等级 码龄16年 225粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值