【移动应用开发技术】Android中怎么实现一个bilibili刷新按钮_第1页
【移动应用开发技术】Android中怎么实现一个bilibili刷新按钮_第2页
【移动应用开发技术】Android中怎么实现一个bilibili刷新按钮_第3页
【移动应用开发技术】Android中怎么实现一个bilibili刷新按钮_第4页
【移动应用开发技术】Android中怎么实现一个bilibili刷新按钮_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】Android中怎么实现一个bilibili刷新按钮

Android中怎么实现一个bilibili刷新按钮,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1、分析先来看看原版效果:该按钮由3部分组成,分别是圆角矩形、文字、旋转图标。在点击按钮后,开始加载数据,旋转图标发生旋转,数据加载完成后,旋转图标复位并停止旋转。话不多说,开始敲代码。2、绘制这里,我们要绘制的部分有3个,分别是上面提到的圆角矩形、文字、旋转图标。那么这里就为这3部分分别声明了一些属性。要注意的一点是,这个类中有3个构造函数,因为有部分属性需要在构造函数中初始化(也为之后自定义属性做准备),所以,将第1个与第2个构造函数中的super修改为this。public

class

LQRRefreshButton

extends

View

{

//

圆角矩形属性

private

int

borderColor

=

Color.parseColor("#fb7299");

private

float

borderWidth

=

0;

private

float

borderRadius

=

120;

//

文字属性

private

String

text

=

"点击换一批";

private

int

textColor

=

Color.parseColor("#fb7299");

private

float

textSize

=

28;

//

旋转图标属性

private

int

iconSrc

=

R.mipmap.tag_center_refresh_icon;

private

float

iconSize

=

28;

private

Bitmap

iconBitmap;

private

float

space4TextAndIcon

=

20;

//

画笔

private

Paint

mPaint

=

new

Paint(Paint.ANTI_ALIAS_FLAG);

public

LQRRefreshButton(Context

context)

{

this(context,

null);

}

public

LQRRefreshButton(Context

context,

@Nullable

AttributeSet

attrs)

{

this(context,

attrs,

0);

}

public

LQRRefreshButton(Context

context,

@Nullable

AttributeSet

attrs,

int

defStyleAttr)

{

super(context,

attrs,

defStyleAttr);

//

将图标资源实例化为Bitmap

iconBitmap

=

BitmapFactory.decodeResource(getResources(),

R.mipmap.tag_center_refresh_icon);

}

@Override

protected

void

onDraw(Canvas

canvas)

{

super.onDraw(canvas);

//

1、画圆角矩形

//

2、画字

//

3、画刷新图标

}

}接下来着重完成onDraw()方法的实现:@Override

protected

void

onDraw(Canvas

canvas)

{

super.onDraw(canvas);

//

1、画圆角矩形

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setColor(borderColor);

mPaint.setStrokeWidth(borderWidth);

canvas.drawRoundRect(new

RectF(0,

0,

getWidth(),

getHeight()),

borderRadius,

borderRadius,

mPaint);

//

2、画字

mPaint.setTextSize(textSize);

mPaint.setColor(textColor);

mPaint.setStyle(Paint.Style.FILL);

float

measureText

=

mPaint.measureText(text);

float

measureAndIcon

=

measureText

+

space4TextAndIcon

+

iconSize;

float

textStartX

=

getWidth()

/

2

-

measureAndIcon

/

2;

float

textBaseY

=

getHeight()

/

2

+

(Math.abs(mPaint.ascent())

-

mPaint.descent())

/

2;

canvas.drawText(text,

textStartX,

textBaseY,

mPaint);

//

3、画刷新图标

float

iconStartX

=

textStartX

+

measureText

+

space4TextAndIcon;

canvas.drawBitmap(iconBitmap,

iconStartX,

getHeight()

/

2

-

iconSize

/

2,

mPaint);

}先来看看效果:我给该控件设置了宽为200dp,高为100dp。可以看到效果还不错,但还是有一点点问题的,下面就分别说说这3部分是怎么画的,及存在的小问题。1)画圆角矩形其实画圆角矩形很简单,设置好画笔的样式、颜色、线粗,再调用canvas的drawRoundRect()方法即可实现。因为我们要画的圆角矩形只需要画线,所以画笔的样式便设置为Paint.Style.STROKE。canvas的drawRoundRect()方法中,第一个参数是绘制范围,这里就直接按该控件的大小来设置即可。第二、三个参数是x轴和y轴的圆角半径,第三个参数是画笔(要画东西当然需要画笔~)。但你有没有发现,此时的线粗为0(borderWidth=0),矩形线怎么还有?这是因为画笔的样式为Paint.Style.STROKE,当线粗为0时,还要画出1px的线,因为对画笔来说,最小的线粗就是1px。所以,上面的代码需要做如下改动://

1、画圆角矩形

if

(borderWidth

>

0)

{

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setColor(borderColor);

mPaint.setStrokeWidth(borderWidth);

canvas.drawRoundRect(new

RectF(0,

0,

getWidth(),

getHeight()),

borderRadius,

borderRadius,

mPaint);

}2)画字画字的一般步骤是设置文字大小、文字颜色、画笔样式,绘制起点。其中后2个最为重要。画笔样式对画出的字是有影响的,当画笔样式为Paint.Style.STROKE时,画出来的字是镂空的(不信你可以试试),我们需要的是实心的字,所以需要修改画笔的样式为Paint.Style.FILL。在安卓中,文字的绘制跟其它绘制是不同的,例如,圆角矩形和旋转图标的绘制起点是左上角,而文字则是按文字左下字为起点,也就是按基线(Baseline)来绘制,故需要得到基线起点的坐标。如上图中,现在要获得的就是文字左下角的点,这要怎么求呢?先说x,一般需要让文字居中显示(跟文字的对齐方式也有关系,这里以默认的左对齐为例),所以计算公式一般为:x=控件宽度/2-文字长度/2。但我们这个控件有点不同,它还需要考虑到旋转图标的位置问题,所以x应该这么求:x=控件宽度/2-(文字长度+空隙+旋转图标宽度)/2。//

得到文字长度

float

measureText

=

mPaint.measureText(text);

//

得到

文字长度+空隙+旋转图标宽度

float

measureAndIcon

=

measureText

+

space4TextAndIcon

+

iconSize;

//

得到文字绘制起点

float

textStartX

=

getWidth()

/

2

-

measureAndIcon

/

2;再说y,如图所示:如果直接用控件的高度的一半作为文字绘制的基线,那么绘制出来的文字肯定偏上,这是因为Ascent的高度比Descent的高度要高的多,我们在计算Baseline时,需要在Ascent中减去Descent的高度得到两者高度差,再让控件中心y坐标加上(下降)这个高度差的一半。故:float

textBaseY

=

getHeight()

/

2

+

(Math.abs(mPaint.ascent())

-

mPaint.descent())

/

2;3)画刷新图标最后就是画刷新图标了,它是以左上角为起点的,通过canvas的drawBitmap()方法进行绘制即可。但是,有一点需要注意,iconSize是我自己定的一个大小,并不是图标的实际大小,所以在往后做旋转动画时获取到的旋转中心会有误差,将导致图标旋转时不是按中心进行旋转。所以,这里需要对图标大小进行调整:public

class

LQRRefreshButton

extends

View

{

...

public

LQRRefreshButton(Context

context,

@Nullable

AttributeSet

attrs,

int

defStyleAttr)

{

super(context,

attrs,

defStyleAttr);

//

icon

iconBitmap

=

BitmapFactory.decodeResource(getResources(),

iconSrc);

iconBitmap

=

zoomImg(iconBitmap,

iconSize,

iconSize);

}

public

Bitmap

zoomImg(Bitmap

bm,

float

newWidth,

float

newHeight)

{

//

获得图片的宽高

int

width

=

bm.getWidth();

int

height

=

bm.getHeight();

//

计算缩放比例

float

scaleWidth

=

((float)

newWidth)

/

width;

float

scaleHeight

=

((float)

newHeight)

/

height;

//

取得想要缩放的matrix参数

Matrix

matrix

=

new

Matrix();

matrix.postScale(scaleWidth,

scaleHeight);

//

得到新的图片

Bitmap

newbm

=

Bitmap.createBitmap(bm,

0,

0,

width,

height,

matrix,

true);

return

newbm;

}

...

}3、动画现在,要实现旋转图标的旋转功能了。原理就是在canvas绘制图标时,将canvas进行旋转,canvas旋转着绘制图标也很简单,只需要4步:canvas.save();

canvas.rotate(degress,

centerX,

centerY);

canvas.drawBitmap(iconBitmap,

iconStartX,

getHeight()

/

2

-

iconSize

/

2,

mPaint);

canvas.restore();接下来要做的,就是计算出旋转中心,旋转角度,并不停止的去调用onDraw()编制图标,可以使用ValueAnimator或ObjectAnimator实现这个功能,这里选用ObjectAnimator。实现如下:public

class

LQRRefreshButton

extends

View

{

...

private

float

degress

=

0;

private

ObjectAnimator

mAnimator;

public

LQRRefreshButton(Context

context,

@Nullable

AttributeSet

attrs,

int

defStyleAttr)

{

super(context,

attrs,

defStyleAttr);

//

旋转动画

mAnimator

=

ObjectAnimator.ofObject(this,

"degress",

new

FloatEvaluator(),

360,

0);

mAnimator.setDuration(2000);

mAnimator.setRepeatMode(ObjectAnimator.RESTART);

mAnimator.setInterpolator(new

LinearInterpolator());

mAnimator.setRepeatCount(ObjectAnimator.INFINITE);

}

@Override

protected

void

onDraw(Canvas

canvas)

{

super.onDraw(canvas);

...

//

3、画刷新图标

float

iconStartX

=

textStartX

+

measureText

+

space4TextAndIcon;

canvas.save();

float

centerX

=

iconStartX

+

iconSize

/

2;

int

centerY

=

getHeight()

/

2;

canvas.rotate(degress,

centerX,

centerY);

canvas.drawBitmap(iconBitmap,

iconStartX,

getHeight()

/

2

-

iconSize

/

2,

mPaint);

canvas.restore();

}

public

void

start()

{

mAnimator.start();

}

public

void

stop()

{

mAnimator.cancel();

setDegress(0);

}

public

float

getDegress()

{

return

degress;

}

public

void

setDegress(float

degress)

{

this.degress

=

degress;

invalidate();

}

}使用ObjectAnimator可以对任意属性值进行修改,所以需要在该控件中声明一个旋转角度变量(degress),并编写getter和setter方法,还需要在setter方法中调用invalidate(),这样才能在角度值发生变换时,让控件回调onDraw()进行图标的旋转绘制。ObjectAnimator的使用也不复杂,这里就不详细介绍了。来看下动画效果吧:4、自定义属性一个自定义控件,是不能把属性值写死在控件里的,所以我们需要自定义属性,从外界获取这些属性值。1)属性文件编写在attrs.xml中编写如下代码:<?xml

version="1.0"

encoding="utf-8"?>

<resources>

<declare-styleable

name="LQRRefreshButton">

<attr

name="refresh_btn_borderColor"

format="color"/>

<attr

name="refresh_btn_borderWidth"

format="dimension"/>

<attr

name="refresh_btn_borderRadius"

format="dimension"/>

<attr

name="refresh_btn_text"

format="string"/>

<attr

name="refresh_btn_textColor"

format="color"/>

<attr

name="refresh_btn_textSize"

format="dimension"/>

<attr

name="refresh_btn_iconSrc"

format="reference"/>

<attr

name="refresh_btn_iconSize"

format="dimension"/>

<attr

name="refresh_btn_space4TextAndIcon"

format="dimension"/>

</declare-styleable>

</resources>2)属性值获取在控件的第三个构造函数中获取这些属性值:public

class

LQRRefreshButton

extends

View

{

public

LQRRefreshButton(Context

context,

@Nullable

AttributeSet

attrs,

int

defStyleAttr)

{

super(context,

attrs,

defStyleAttr);

//

获取自定义属性值

TypedArray

ta

=

context.obtainStyledAttributes(attrs,

R.styleable.LQRRefreshButton);

borderColor

=

ta.getColor(R.styleable.LQRRefreshButton_refresh_btn_borderColor,

Color.parseColor("#fb7299"));

borderWidth

=

ta.getDimension(R.styleable.LQRRefreshButton_refresh_btn_borderWidth,

dipToPx(0));

borderRadius

=

ta.getDimension(R.styleable.LQRRefreshButton_refresh_btn_borderRadius,

dipToPx(60));

text

=

ta.getString(R.styleable.LQRRefreshButton_refresh_btn_text);

if

(text

==

null)

text

=

"";

textColor

=

ta.getColor(R.styleable.LQRRefreshButton_refresh_btn_textColor,

Color.parseColor("#fb7299"));

textSize

=

ta.getDimension(R.styleable.LQRRefreshButton_refresh_btn_textSize,

spToPx(14));

iconSrc

=

ta.getResourceId(R.styleable.LQRRefreshButton_refresh_btn_ic

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论