位置: 编程技术 - 正文

Android 自定义组件之如何实现自定义组件(android自定义组件开发详解)

编辑:rootadmin

推荐整理分享Android 自定义组件之如何实现自定义组件(android自定义组件开发详解),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:android自定义组件开发详解,android自定义列表,android自定义组件开发详解,Android自定义组件性能,android自定义列表,android自定义组件,android自定义组件开发详解,Android自定义组件性能,内容如对您有帮助,希望把文章链接给更多的朋友!

原文地址: TextView, EditText, ListView, CheckBox,RadioButton, Gallery, Spinner,以及一些有特别作用的组件: AutoCompleteTextView, ImageSwitcher和 TextSwitcher。

可用的布局有:LinearLayout,FrameLayout,RelativeLayout,AbsoluteLayout,GridLayout (later on api level or v7-support)

基本做法

1. 继承自View或View的子类

2. 重写父类的一些方法,如:onDraw(),onMeasure(),onLayout()等

3. 使用自定义的组件类。

完全自定义组件1. 最普通的作法是,继承自View,实现你的自定义组件

2. 提供一个构造函数,采用有属性参数的,也可以使用自定义属性

3. 你可能想在组件中创建自己的事件监听器,属性访问器和修改器,或其他行为

4. 几乎肯定要重写onDraw(),onMeasure()。默认onDraw()什么也没作,onMeasure()则设置一个x的尺寸。

5. 根据需要重写其他方法 ...

onDraw()和onMeasure()

onDraw(),提供一个Canvas,可以绘制2D图形。

若要绘制3D图形,请继承GLSurfaceView,参见,api-demo下的 GLSurfaceViewActivity

Android 自定义组件之如何实现自定义组件(android自定义组件开发详解)

onMeasure() 测量组件

1. 宽度和高度在需要测量时调用该方法

2. 应该进行测量计算组件将需要呈现的宽度和高度。它应该尽量保持传入的规&#;范围内,尽管它可以选择超过它们(在这种情况下,父视图可以选择做什么,包括裁剪,滚动,抛出一个异常,或者要求onMeasure()再次尝试,或使用不同的测量规&#;)

3. 宽高计算完毕后,必须调用用setMeasuredDimession(int width, int height),进行设置。否则将抛出一个异常

下面是一些View中可被调用的方法总结(未全部包含,可自行查看类&#;onXxx的方法):

CategoryMethodsDescriptionCreationConstructorsThere is a form of the constructor that are called when the view is created from code and a form that is called when the view is inflated from a layout file. The second form should parse and apply any attributes defined in the layout file.onFinishInflate()Called after a view and all of its children has been inflated from XML.LayoutonMeasure(int, int)Called to determine the size requirements for this view and all of its children.onLayout(boolean, int, int, int, int)Called when this view should assign a size and position to all of its children.onSizeChanged(int, int, int, int)Called when the size of this view has changed.DrawingonDraw(Canvas)Called when the view should render its content.Event processingonKeyDown(int, KeyEvent)Called when a new key event occurs.onKeyUp(int, KeyEvent)Called when a key up event occurs.onTrackballEvent(MotionEvent)Called when a trackball motion event occurs.onTouchEvent(MotionEvent)Called when a touch screen motion event occurs.FocusonFocusChanged(boolean, int, Rect)Called when the view gains or loses focus.onWindowFocusChanged(boolean)Called when the window containing the view gains or loses focus.AttachingonAttachedToWindow()Called when the view is attached to a window.onDetachedFromWindow()Called when the view is detached from its window.onWindowVisibilityChanged(int)Called when the visibility of the window containing the view has changed.自定义View示例

adi-demo下的示例:LabelView

[java] view plaincopy/* * Copyright (C) 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 * * * * 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 android.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.view.View; /** * 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 { /** * Constructor. This version is only needed if you will be instantiating * the object manually (not from a layout XML file). * @param context the application environment */ 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(); Resources.StyledAttributes a = context.obtainStyledAttributes(attrs, R.styleable.LabelView); CharSequence s = a.getString(R.styleable.LabelView_text); if (s != null) { setText(s.toString()); } ColorStateList textColor = a.getColorList(R.styleable. LabelView_textColor); if (textColor != null) { setTextColor(textColor.getDefaultColor(0)); } int textSize = a.getInt(R.styleable.LabelView_textSize, 0); if (textSize > 0) { setTextSize(textSize); } a.recycle(); } */ private void initLabelView() { mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setTextSize(); mTextPaint.setColor(0xFF); mPaddingLeft = 3; mPaddingTop = 3; mPaddingRight = 3; mPaddingBottom = 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; requestLayout(); invalidate(); } /** * Sets the text size for this label * @param size Font size */ public void setTextSize(int size) { 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) { 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; 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 result = (int) mTextPaint.measureText(mText) &#; mPaddingLeft &#; mPaddingRight; 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; } /** * 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; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); mAscent = (int) mTextPaint.ascent(); 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()) &#; mPaddingTop &#; mPaddingBottom; 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, mPaddingLeft, mPaddingTop - mAscent, mTextPaint); } private Paint mTextPaint; private String mText; private int mAscent; }

应用该自定义组件的layout xml:

[html] view plaincopy<LinearLayout xmlns:android=" xmlns:app=" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.example.android.apis.view.LabelView android:background="@drawable/red" android:layout_width="match_parent" android:layout_height="wrap_content" app:text="Red"/> <com.example.android.apis.view.LabelView android:background="@drawable/blue" android:layout_width="match_parent" android:layout_height="wrap_content" app:text="Blue" app:textSize="dp"/> <com.example.android.apis.view.LabelView android:background="@drawable/green" android:layout_width="match_parent" android:layout_height="wrap_content" app:text="Green" app:textColor="#ffffffff" /> </LinearLayout> 该示例演示了:

1. 继承自View的完全自定义组件

2. 带参数的构造函数(一些属性参数在xml中设置)。还使用了自定义属性 R.styleable.LabelView

3. 一些标准的public 方法,如setText()、setTextSize()、setTextColor()

4. onMeasure()测量组件尺寸,内部由measureWidth(int measureSpec) 和 measureHeight(int measureSpec)来测量。

5. onDraw()将Label绘制到画面Canvas上

复合组件由一些现有组件,复合成一个新的组件。要创建一个复合组件:1. 通常需要创建一个类,继承自一个Layout,或者ViewGroup。2. 在构造函数中,需要先调用父类相应的构造函数。然后设置一些需要的组件用于复合。可以使用自定义属性3. 可以创建监听器,监听处理一些可能的动作4. 可能有一些 属性的 get / set 方法5. 如果继承自某一Layout类时,不需要重写onDraw()和onMeasure(),因为Layout类中有默认的行为。如有必要,当然也可以重写6. 可能重写其他一些onXxx(),以达到你想要的效果复合组件示例api-demo下的List4和List6里的内部类SpeachView,以下为List6中的源码[java] view plaincopyprivate class SpeechView extends LinearLayout { public SpeechView(Context context, String title, String dialogue, boolean expanded) { super(context); this.setOrientation(VERTICAL); // Here we build the child views in code. They could also have // been specified in an XML file. mTitle = new TextView(context); mTitle.setText(title); addView(mTitle, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); mDialogue = new TextView(context); mDialogue.setText(dialogue); addView(mDialogue, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); mDialogue.setVisibility(expanded ? VISIBLE : GONE); } /** * Convenience method to set the title of a SpeechView */ public void setTitle(String title) { mTitle.setText(title); } /** * Convenience method to set the dialogue of a SpeechView */ public void setDialogue(String words) { mDialogue.setText(words); } /** * Convenience method to expand or hide the dialogue */ public void setExpanded(boolean expanded) {//该方法在List4中没有 mDialogue.setVisibility(expanded ? VISIBLE : GONE); } private TextView mTitle; private TextView mDialogue; } SpeachView,继承了LinearLayout,纵向布局。内部有一个TextView的title,一个TextView的dialogue。List4完全展开两个TextView;List6点击title可以收缩/展开dialogue。修改现有View类型继承自一个现有的View,以增强其功能,满足需要。sdk中有个记事本NotePad的示例工程。其中有一个类就是扩展了EditText。在NoteEditor类中:[java] view plaincopypublic static class LinedEditText extends EditText { private Rect mRect; private Paint mPaint; // This constructor is used by LayoutInflater public LinedEditText(Context context, AttributeSet attrs) { super(context, attrs); // Creates a Rect and a Paint object, and sets the style and color of the Paint object. mRect = new Rect(); mPaint = new Paint(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(0xFF); } /** * This is called to draw the LinedEditText object * @param canvas The canvas on which the background is drawn. */ @Override protected void onDraw(Canvas canvas) { // Gets the number of lines of text in the View. int count = getLineCount(); //edittext中有几行, edittext继承textview // Gets the global Rect and Paint objects Rect r = mRect; Paint paint = mPaint; /* * Draws one line in the rectangle for every line of text in the EditText */ for (int i = 0; i < count; i&#;&#;) { // Gets the baseline coordinates for the current line of text int baseline = getLineBounds(i, r);//将一行的范围坐标赋给矩形r;返回一行y方向上的基准线坐标 /* * Draws a line in the background from the left of the rectangle to the right, * at a vertical position one dip below the baseline, using the "paint" object * for details. */ canvas.drawLine(r.left, baseline &#; 1, r.right, baseline &#; 1, paint);//绘制一条线,宽度为原行的宽度,高度为从基线开始&#;1个像素 } // Finishes up by calling the parent method super.onDraw(canvas); } } 定义一个public的静态内部类,以便它可以被访问:NoteEditor.MyEditText它是静态内部类,意味着,它不依靠外部类的成员,不会产生一些“组合的方法”。继承自EditText类的初始化构造函数中,先调用父类的构造方法,并且它是带属性参数的构造函数。在使用时,从一个xml布局文件inflate重写的方法只有onDraw()被重写。在onDraw()中绘制了一条蓝色的线,该线从每行文本的的基线开始向下1像素,宽度为行宽。方法结束前,调用super.onDraw()使用自定义组件[html] view plaincopy<view xmlns:android=" class="com.example.android.notepad.NoteEditor$LinedEditText" android:id="@&#;id/note" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:padding="5dp" android:scrollbars="vertical" android:fadingEdge="vertical" android:gravity="top" android:textSize="sp" android:capitalize="sentences" /> 使用完全限定类名,引入自定义组件。使用$引用内部类。

Android动画探索——图标依次变大的水滴效果 一直打算模仿ios,做一个安卓的水滴效果:比如有四个图标,四个图标依次出现,并由小变大。就像水滴掉落时一头大一头小一样。首先分析需求:1.四

安卓getListView().setTextFilterEnabled(true) getListView().setTextFilterEnabled(true),函数setTextFilterEnabled,属性为true表示listview获得当前焦点的时候,与相应用户输入的匹配符进行比对,筛选出匹配的ListV

通过WIFI连接安卓设备调试 首先在安卓终端下载一个shell程序,我下载的是androidterminalemulator下载完成,安装,运行如下命令:surootsetpropservice.adb.tcp.portstopadbdstartadbd命令完成,可

标签: android自定义组件开发详解

本文链接地址:https://www.jiuchutong.com/biancheng/381030.html 转载请保留说明!

上一篇:JUnit4 多线程执行测试用例(junit 原理)

下一篇:Android动画探索——图标依次变大的水滴效果(android view动画)

  • 个人所得税手续费返还增值税税率
  • 电子税务局登陆密码总是错误怎么办
  • 用友软件生成凭证合并进项税
  • 计提税金及附加会计分录
  • 增值税发票注明金额是含税还是不含税
  • 人工成本比例
  • 其他预算收入科目核算内容
  • 公允价值变动损益会计处理
  • 法院受理费用
  • 劳保费计入管理费用的什么
  • 即征即退和一般项目进项税比例怎样算出进项税额
  • 建筑公司收到工程服务发票怎么做会计分录
  • 发票超过2个月可以报销吗
  • 土建税率是多少
  • 公益性捐赠需要缴纳增值税吗
  • 2018年建筑增值税税率表
  • 电子银行承兑如何背书给别人
  • 会计档案保管最新规定
  • 自建自用建筑物,其自建行为不是建筑业税目的征税范围
  • 季度预缴所得税可以弥补以前亏损吗
  • 本月计提下月冲回
  • 环境保护税入账什么会计科目
  • 如何调整往来账款
  • 民法典对知识产权的定义
  • 总公司以固定资产出资入股,固定资产是不是新公司的
  • 家装行业如何确认收入
  • 苹果mac os 10.4
  • 企业转手员工工龄怎么算
  • 修改配置文件是什么意思
  • php单独运行
  • 一亩地是多少平方?
  • php框架怎么用
  • 工程项目会计怎么样
  • 商企预提待付的钱怎么办
  • unplugin-auto-import/vite
  • es6 promise finally
  • 使用微软必应需要哪些条件
  • 购买电子承兑差额是多少
  • 单位多缴个人社保证明
  • 总分机构纳税
  • 纳税人识别号和信用代码一样吗
  • 资产负债表坏账准备计入哪里科目
  • sql2000安装不上是什么原因
  • 保险公司给员工奖励是违法的吗
  • sql 字符串
  • sqlldr并发
  • 小规模纳税人免税政策2023年
  • 购销合同上没有金额,怎么写比较好
  • 商场活动经费预算
  • 对外投资需要股东会决议吗
  • 无形资产入账价值包括费用化支出吗
  • 科目汇总表一张几行啊
  • 未完工的工程施工怎么处理
  • 对公网银回单可以导出吗
  • 企业在非同一控制下的企业合并
  • 固定资产折旧年限的最新规定2023
  • 建账需要准备什么东西
  • Microsoft SQLServer的版本区别及选择
  • mysql修改允许远程连接
  • win8.1开机密码忘了
  • mac系统操作的小技巧
  • mac安装pyenv
  • surface 优惠
  • mac os如何安装软件
  • windows8开机蓝屏
  • windows10预览版是什么
  • win8.1系统要求配置
  • cocos点击事件
  • diskpart ntfs
  • jQ处理xml文件和xml字符串的方法(详解)
  • vuecli脚手架是干什么的
  • jQuery中的AjaxSubmit使用讲解
  • 提出好的建议
  • jquery插件怎么写
  • 办税服务厅怎么开通扣缴端数据下载
  • 税务局房屋评估怎样做低
  • 小微企业印花税的税率是多少
  • 宝安区西乡税务所长
  • 上海市网上税务局如何登录
  • 金三申报系统里面怎么申报社保?
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设