糖果派对官方网站_可以赌钱的糖果游戏_手机版
自定义View简单案例-自绘控件

自定义View简单案例-自绘控件

作者:网络编程    来源:未知    发布时间:2020-03-13 03:20    浏览量:

福寿年高的效应

继承View

bb电子糖果派对 1

持续ViewGroup实现四个顶栏

bb电子糖果派对 2

上边来促成地点效果自定义View基础:Android开垦之自定义View基本功

自定义控件

应用情况: 在实际费用中临时会凌驾现存的UI控件无法满足项目须求,或叁个成效涉及到多少个UI控件的构成,或促成某一神效的UI,那时候必得通过自定义View的点子,实现那些功效,举例股票(stockState of Qatar的实时总括图、电子书等。

  在Android中,视图控件差非常少被分为两类,即ViewGroup和View,ViewGroup控件作为父控件,满含并关押着子View,通过ViewGroup和View便形成了控件树,各种ViewGoup对象和View对象正是控件树中的节点。在控件树中,以树的深度来遍历查找对应的控件成分,同一时间,上层控件担当子控件的衡量与绘图,并传递人机联作事件。

继承View

须求自定义绘制内容,须求延续View,应当要重写onDraw方法,在onDraw方法中来开展绘图,完成onMeasure方法,来度量控件的长空。

public class SimpleView extends View { public SimpleView(Context context) { super; } public SimpleView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); }}

@Overrideprotected void onDraw(Canvas canvas) { super.onDraw;}

那边不作管理

@Overridepublic boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent;}

1.聊起绘制,当然须求画笔了。初阶化画笔

 /** * 初始化画笔 */ private void initPaint() { // 定义画笔 paint = new Paint(); // 设置画笔的字体大小 paint.setTextSize; // 线条的样式 - 粗体 斜线 paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setStrokeWidth; // 设置画笔的颜色 paint.setColor(Color.RED); // 设置画笔的样式 // Paint.Style.STROKE - 边线样式 - 圆 // Paint.Style.FILL - 填充样式 - 圆 paint.setStyle(Paint.Style.STROKE); //paint.setStyle(Paint.Style.FILL); // 是否抗锯齿 paint.setAntiAlias; }

2.绘制图形

 /** * 用于绘制 * 当初始化View(在代码中添加自定义控件,或者在布局中添加加载时),此方法会调用 * * @param canvas - 画布 */ @Override protected void onDraw(Canvas canvas) { super.onDraw; /****************绘制内容***************/ // 绘制线(float startX, float startY, float stopX, float stopY, Paint paint) canvas.drawLine(100, 100, 600, 300, paint); // 绘制圆(float cx, float cy, float radius, Paint paint) canvas.drawCircle(500, 500, 200, paint); // 绘制文字(String text, float x, float y, Paint paint) canvas.drawText("绘制内容", 450, 750, paint); // 绘制矩形1(float left, float top, float right, float bottom, Paint paint) canvas.drawRect(400, 950, 600, 1100, paint); // 绘制矩形2 RectF rect = new RectF(); rect.left = 400; rect.top = 950; rect.right = 600; rect.bottom = 1100; //canvas.drawRect(rect,paint); }

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:andro xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.rair.customview.SimpleViewActivity"> <com.rair.customview.view.SimpleView android:layout_width="match_parent" android:layout_height="match_parent" /></android.support.constraint.ConstraintLayout>

bb电子糖果派对 3

public class SimpleView extends View { // 声明画笔 private Paint paint; // 创建构造方法 public SimpleView(Context context) { //super; // 调用当前类的其他的构造方法 this(context, null); } /** * 如果在布局中添加自定义控件,则需要添加如下构造方法 * * @param context - 上下文 * @param AttributeSet set - 属性对象,它包含这当前控件所有的属性 */ public SimpleView(Context context, AttributeSet set) { super(context, set); initPaint(); } /** * 初始化画笔 */ private void initPaint() { // 定义画笔 paint = new Paint(); // 设置画笔的字体大小 paint.setTextSize; // 线条的样式 - 粗体 斜线 paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setStrokeWidth; // 设置画笔的颜色 paint.setColor(Color.RED); // 设置画笔的样式 // Paint.Style.STROKE - 边线样式 - 圆 // Paint.Style.FILL - 填充样式 - 圆 paint.setStyle(Paint.Style.STROKE); //paint.setStyle(Paint.Style.FILL); // 是否抗锯齿 paint.setAntiAlias; } /** * 用于绘制 * 当初始化View(在代码中添加自定义控件,或者在布局中添加加载时),此方法会调用 * * @param canvas - 画布 */ @Override protected void onDraw(Canvas canvas) { super.onDraw; /****************绘制内容***************/ // 绘制线 canvas.drawLine(100, 100, 600, 300, paint); // 绘制圆 canvas.drawCircle(500, 500, 200, paint); // 绘制文字 canvas.drawText("绘制内容", 450, 750, paint); // 绘制矩形 RectF rect = new RectF(); rect.left = 400; rect.top = 950; rect.right = 600; rect.bottom = 1100; //canvas.drawRect(rect,paint); canvas.drawRect(400, 950, 600, 1100, paint); } @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent; }}
  • 绘制,供给绘制控件,重写onDraw方法
  • 通过在ViewGroup中经过this.addView(<控件对象>State of Qatar来增添控件
  • onMeasure方法,来衡量控件的空间
  • onLayout方法必得兑现,在此办法中处理子控件的地点。当视图初叶化,只怕视图地方发生变动时候,调用此格局。
public class GroupView extends ViewGroup { public GroupView(Context context) { this(context, null); } public GroupView(Context context, AttributeSet attrs) { super(context, attrs); }}

作用中左为Imageiew,中间是TextView

 private ImageView imageView; private TextView tvTitle; /** * 添加子控件 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void addViews(Context context) { imageView = new ImageView; imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setBackground(backDrawable); LayoutParams layoutParam = new LayoutParams; imageView.setLayoutParams(layoutParam); // 添加一个ImageView this.addView(imageView); // 添加一个TextView tvTitle = new TextView; tvTitle.setTextSize; tvTitle.setText; tvTitle.setTextColor(titleColor); this.addView; }

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 要测量子控件的高度和宽度 // 计算子控件 measureChildren(widthMeasureSpec, heightMeasureSpec); // 先计量控件的宽度 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int measureWidth = 0; // 确切大小 500dp 或者 match_parent if (widthMode == MeasureSpec.EXACTLY) { measureWidth = MeasureSpec.getSize(widthMeasureSpec); } // wrap_content else if (widthMode == MeasureSpec.AT_MOST) { // 设置屏幕的宽度 measureWidth = screenWidth; } // 高度计算,获取最高的控件 int measureHeight = 0; int childCount = this.getChildCount(); for (int i = 0; i < childCount; i++) { View child = this.getChildAt; // child.getMeasuredHeight()能够获取到具体的控件大小 // 必须先调用measureChildren(widthMeasureSpec,heightMeasureSpec); // 判断哪个控件的高度最大,来作为视图容器的高度 if (child.getMeasuredHeight() > measureHeight) { measureHeight = child.getMeasuredHeight(); } } setMeasuredDimension(measureWidth, measureHeight + 50); }
  • int MeasureSpec.getMode 获取控件大小格局
    • MeasureSpec.EXACTLY,确切空间,布局中的属性值平时为match_parent或方便固定的值(如钦点了160dp)
    • MeasureSpec.AT_MOST 尽量多的上空,布局中的属性值wrap_content
    • MeasureSpec.UNSPECIFIED 未钦点的,平时在父控件中利用
  • 自定义View简单案例-自绘控件。MeasureSpec.getSize 得到控件大小
<resources> <declare-styleable name="GroupView"> <!-- 背景 --> <attr name="nav_bg" format="color|reference" /> <!-- 标题颜色 --> <attr name="title_color" format="color|reference" /> <!-- 标题文字 --> <attr name="title_text" format="string|reference" /> <!-- 标题文字大小 --> <attr name="title_size" format="dimension|reference" /> <!-- 返回图标 --> <attr name="back_image" format="reference" /> </declare-styleable></resources>

 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GroupView); title = array.getString(R.styleable.GroupView_title_text); bgColor = array.getColor(R.styleable.GroupView_nav_bg, 0x0); titleColor = array.getColor(R.styleable.GroupView_title_color, 0xF); backDrawable = array.getDrawable(R.styleable.GroupView_back_image); titleSize = array.getDimensionPixelSize(R.styleable.GroupView_title_size, 10); array.recycle(); // 设置背景颜色 this.setBackgroundColor; // 初始化画笔 paint = new Paint(); paint.setAntiAlias; paint.setStyle(Paint.Style.FILL); paint.setColor;

onLayout方法必得得以达成,在这里办法中管理子控件的地方。当视图起初化,或然视图地方发生变动时候,调用此格局。

切实按供给总括

 /** * 当视图初始化,或者视图位置发生改变时候 * * @param changed 是否改变 * @param l 左 * @param t 上 * @param r 右 * @param b 下 */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //getWidth() // 需要设置子控件显示的位置 //getChildAt.layout(); // 控件的宽度 int viewWidth = getMeasuredWidth(); int viewHeight = getMeasuredHeight(); int left = 0, top = 0, right = 0, bottom = 0; int childCount = this.getChildCount(); View view = null; for (int i = 0; i < childCount; i++) { view = this.getChildAt; if  { left = view.getMeasuredWidth() / 3; } else if  { left = (viewWidth - view.getMeasuredWidth / 2; } top = (viewHeight - view.getMeasuredHeight / 2; right = left + view.getMeasuredWidth(); bottom = top + view.getMeasuredHeight(); view.layout(left, top, right, bottom); } }

 public interface OnFinishListener { void onFinish(); } private OnFinishListener listener; public void setOnFinishListener(OnFinishListener listener) { this.listener = listener; }

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:andro xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.rair.customview.GroupViewActivity"> <com.rair.customview.view.GroupView android: android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:back_image="@drawable/ic_arrow_back_black_24dp" app:nav_bg="@color/colorAccent" app:title_color="@color/white" app:title_size="25sp" app:title_text="首页" /> <com.rair.customview.view.GroupView android: android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_marginTop="10dp" app:back_image="@drawable/ic_arrow_back_black_24dp" app:nav_bg="@color/colorAccent" app:title_color="@color/white" app:title_size="25sp" app:title_text="首页" /></LinearLayout>

安装事件监听(点击再次回到落出Activity)

public class GroupViewActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_group_view); GroupView groupView = (GroupView) findViewById(R.id.m_groupview); groupView.setOnFinishListener(new GroupView.OnFinishListener() { @Override public void onFinish() { finish; }}

bb电子糖果派对 4

分类

1.卫冕View需求自定义绘制内容,要求一连View,应当要重写onDraw方法,在onDraw方法中来进展绘图,完成onMeasure方法,来衡量控件的上空。

2.继承ViewGroup

  • 因而在ViewGroup中经过this.addView(<控件对象>卡塔尔国来增加控件
  • onMeasure方法,来衡量控件的空中
  • onLayout方法必得兑现,在这里情势中管理子控件的职责。当视图开端化,或许视图地方爆发改造时候,调用此办法。

通过三番若干遍系统现已存在的视图容器,在早先化时候,直接加载构造

mInflater.inflate(<布局资源的ID>,this);mIvBack = (ImageView) findViewById(R.id.btn_back);

经过持续系统现已存在的视图也许视图容器,在中间更动此视图大概视图容器的效率比如:通过更换ListView增加删除功效

  Android控件树:

Demo已上传

GitHub:

自定义View步骤

  • 创设类,世袭View及View的子类,并提供相关的布局方法
  • 重写onMeasure(卡塔尔国方法,并调用setMeasuredDimension(int width, int height卡塔尔设置控件的分寸
  • 重写onDraw(State of Qatar方法,实现绘制特定内容
  • 重写onTouchEvent(State of Qatar格局管理触摸事件
  • 在构造文件中应用<类全名>并安装属性

  bb电子糖果派对 5

自定义View属性

1.位置:res/values/attrs.xml

2.属性集

<?xml version="1.0" encoding="utf-8"?><resources> <!-- 声明属性集 --> <declare-styleable name="LabelView"> <attr name="text" format="string"/> <attr name="textSize" format="dimension"/> <attr name="textColor" format="color" /> </declare-styleable></resources>

3.钦定属性名及其内容格式例:<attr name="text" format="string" />

string 字符型integer 整数型dimension 尺寸值color 颜色值reference 参谋某一财富IDboolean:布尔值

  AndroidUI分界面布局图:

动用自定义View属性

在布局控件标签中援用:xmlns:my="""

在自定义View的View(Context context, AttributeSet attrsState of Qatar构造方法中,获取自定义属性的值

//TypedArray是一个用来存放由context.obtainStyledAttributes获得的属性的数组 //在使用完成后,一定要调用recycle方法 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LabelView); CharSequence s = ta.getString(R.styleable.LabelView_text); if (s != null) { setText(s.toString; } setTextColor(ta.getColor(R.styleable.LabelView_textColor, 0xFF000000)); int textSize = ta.getDimensionPixelSize(R.styleable.LabelView_textSize, 0); if (textSize > 0) { setTextSize; } ta.recycle();

  bb电子糖果派对 6

涉及相关类

  • View 动态实例化控件的结构方法
  • View(Context context, AttributeSet attrsState of Qatar 布局中央银行使控件的协会的艺术
  • onMeasure(int widthMeasureSpec, int heightMeasureSpec)自定义控件时重写的法子,用于度量控件大小
  • onDraw(Canvas canvasState of Qatar 在自义控件上制图相关内容
  • onTouchEvent(MotionEventState of Qatar 完结触摸事件管理办法
  • setPadding(int l,int t,int r,int b卡塔尔 设置内部间距
  • layout(int l, int t, int r,int b卡塔尔国 更改控件地方的主意
  • requestLayout(卡塔尔(قطر‎ //消逝构造,获取新的构造空间(刷新UI,重新调用onDraw
  • invalidate(卡塔尔国 //重新绘制新的数额(刷新UI,重新调用onDraw
  • int MeasureSpec.getMode 获取控件大小情势
    • MeasureSpec.EXACTLY,确切空间,结构中的属性值日常为match_parent或160dp固定值
    • MeasureSpec.AT_MOST 尽量多的上空,构造中的属性值wrap_content
    • MeasureSpec.UNSPECIFIED 未钦点的,平常在父控件中运用
  • MeasureSpec.getSize 拿到控件大小
  • TypeArray Context.obtainStyledAttributes(attrs,揽胜极光.styleable.LabelView)获取钦定attrs中的全部属性
  • String getString(R.styleable.LabelView_text卡塔尔 获取钦定属性的文本值
  • int getDimensionPixelSize(R.styleable.LabelView_textSize, 0卡塔尔获取钦赐属性的间距值
  • int getColor(R.styleable.LabelView_textColor, 0xFF000000卡塔尔国获取钦赐属性的颜色值
  • Paint.setAntiAlias 启用抗锯齿
  • Paint.setTextSize(int pixes卡塔尔(قطر‎ 设置字体大小,像素,通常转成sp
  • Paint.setColor(int color卡塔尔国 设置颜色
  • Paint.setStyle(Paint.Style卡塔尔(قطر‎ 设置画笔样式
  • float mTextPaint.measureText 度量文字的分寸
  • Paint.ascent(卡塔尔国 获取文字基准线以上到文字顶上部分的区间,负数
  • Paint.descent(State of Qatar 获取文字基准线以下到文字尾巴部分的区间
  • canvas.drawText(String,int x,int y,PaintState of Qatar 绘制文本
  • canvas.drawRoundRect(RectF,int rx,int ry,PaintState of Qatar 绘制圆角四边方形
  • canvas.drawBitmap(bitmap, left, top, paint卡塔尔 绘制图片
  • canvas.drawCircle(cx, cy, radius, paint) 绘制圆
  • canvas.drawLine(startX, startY, stopX, stopY, paintState of Qatar 绘制线条

Xfermode有多个子类 :AvoidXfermode 钦命了二个颜料和容差,强迫Paint防止在它上边绘制(大概只在它下面绘制卡塔尔。PixelXorXfermode 当覆盖原来就有的颜色时,应用三个简易的像素异或操作。PorterDuffXfermode 那是一个相当刚劲的转移情势,使用它,能够采纳图像合成的16条Porter-Duff法规的即兴一条来决定Paint怎样与原来就有个别Canvas图像实行相互影响。

bb电子糖果派对 7

要使用转变情势,可以接收setXferMode方法,如下所示:

AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID);borderPen.setXfermode;

PorterDuff.Mode为枚举类,一共有17个枚举值:

1.PorterDuff.Mode.CLEA瑞虎所绘制不会交到到画布上。2.PorterDuff.Mode.SRC显示上层绘制图片3.PorterDuff.Mode.DST展现下层绘制图片4.波特Duff.Mode.SRC_OVE福睿斯平常绘制显示,上下层绘制叠盖。5.PorterDuff.Mode.DST_OVECR-V上下层都来得。下层居上呈现。6.PorterDuff.Mode.SRC_IN取两层绘制交集。彰显上层。7.PorterDuff.Mode.DST_IN取两层绘制交集。彰显下层。8.波特Duff.Mode.SRC_OUT取上层绘制非交集部分。9.PorterDuff.Mode.DST_OUT取下层绘制非交集部分。10.PorterDuff.Mode.SRC_ATOP取下层非交集部分与上层交集部分11.PorterDuff.Mode.DST_ATOP取上层非交集部分与下层交集部分12.PorterDuff.Mode.XO奥迪Q5异或:去除两图层交集部分13.波特Duff.Mode.DA路虎极光KEN取两图层全部区域,交集部分颜色加深14.PorterDuff.Mode.LIGHTEN取两图层全体,点亮交集部分颜料15.PorterDuff.Mode.MULTIPLY取两图层交集部分叠合后颜色16.PorterDuff.Mode.SCREEN取两图层全体区域,交集部分改为透明色

一.衡量View的工具类:MeasureSpec

  1.MeasureSpec含有了衡量的情势和衡量的尺寸,通过MeasureSpec.getMode(卡塔尔国获取度量方式,通过MeasureSpec.getSize(卡塔尔国获取衡量大小;

  2.MeasureSpec是三个33人的int值,高2位为度量的格局,低叁拾一人为度量的分寸,使用位运算的意在进步优化成效。

二.度量的格局

  1.EXACTLY,准确值形式:将layout_width或layout_height属性钦赐为现实数值恐怕match_parent。

  2.AT_MOST,最大值情势:将layout_width或layout_height指定为wrap_content。

  3.UNSPECIFIED: View想多大就多大

三.View类暗中认可的onMeasure(卡塔尔(قطر‎方法只援助EXACTLY格局,倘若要扶植任何方式,就必需重写onMeasure(State of Qatar,重写onMeasure(卡塔尔国的沙盘代码:

 1 package com.example.demoapp.views;
 2 
 3 import android.content.Context;
 4 import android.view.View;
 5 
 6 public class MeasuredView extends View {
 7     public MeasuredView(Context context) {
 8         super(context);
 9     }
10     
11     @Override
12     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
13         // 调用父类的onMeasure()
14         super.onMeasure(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
15         // 或者直接调用父类的setMeasuredDimension(),因为父类的onMeasure()最终调用了setMeasuredDimension()
16         // setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
17     }
18     
19     /**
20      * 测量View的width
21      * @param measureSpec MeasureSpec对象
22      * @return View的width
23      */
24     private int measureWidth(int measureSpec) {
25         int result = 0;
26         int specMode = MeasureSpec.getMode(measureSpec);
27         int specSize = MeasureSpec.getSize(measureSpec);
28         
29         if (specMode == MeasureSpec.EXACTLY) {
30             result = specSize;
31         } else {
32             result = 200;
33             if (specMode == MeasureSpec.AT_MOST) {
34                 result = Math.min(result, specSize);
35             }
36         }
37         return result;
38     }
39     
40     /**
41      * 测量View的height
42      * @param measureSpec MeasureSpec对象
43      * @return View的height
44      */
45     private int measureHeight(int measureSpec) {
46         int result = 0;
47         int specMode = MeasureSpec.getMode(measureSpec);
48         int specSize = MeasureSpec.getSize(measureSpec);
49         
50         if (specMode == MeasureSpec.EXACTLY) {
51             result = specSize;
52         } else {
53             result = 200;
54             if (specMode == MeasureSpec.AT_MOST) {
55                 result = Math.min(result, specSize);
56             }
57         }
58         return result;
59     }
60 }

bb电子糖果派对,四.View的绘制

  1.2D制图必备利器——Canvas

  1)获取Canvas对象的情势:

    a.由艺术中的参数字传送入,举个例子,View的onDraw(卡塔尔国中有多个参数正是Canvas对象

    b.通过构造方法布局,即:Canvas canvas = new Canvas(bitmapState of Qatar,在Canvas的构造方法传入三个Bitmap对象,就能够获取叁个Canvas对象。通过传入Bitmap对象组织Canvas对象的过程称为“画布的装载”,传入的Bitmap对象承载了多有绘制在Canvas上的像素音信,调用Canvas.drawXXX方法(如:Canvas.drawBitmap(bitmap, 0, 0, null卡塔尔国)都将产生在该Bitmap对象上。

  2)利用Canvas绘图

下一篇:没有了
友情链接: 网站地图
Copyright © 2015-2019 http://www.tk-web.com. bb电子糖果派对有限公司 版权所有