Android 自定义控件---SpreadView
来源:互联网 发布:跑步口罩推荐 知乎 编辑:程序博客网 时间:2024/06/11 11:19
1、效果图:主要模仿Fuubo的欢迎界面,一个三层扩散的水波纹.
2、实现思路:
1、在布局主要用帧布局,让三个水波纹的View重叠
2、设置三个水波纹的View扩散的延迟时间
3、可设置三个水波纹的View的坐标,
可设置是否开始(因为我们有时要Activity中先设置好波纹的坐标,不能让波纹先出现),
可设置是否为第一次(第一次要进行初始化主要为了设置延迟,不然每次都会有延迟,不同延迟时间的SpreadView相差的时间越来越多)。
3、实现:
根据思路所以接下来要做的一个自定义VIEW就是去绘制一个可扩散的,可设置扩散延迟的实心圆。
1、 先设置自定义View属性(attr文件中):
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <declare-styleable name="SpreadView">
- <attr name="xDown" format="integer" />
- <attr name="yDown" format="integer" />
- <attr name="start" format="boolean" />
- <attr name="delay" format="integer" />
- <attr name="first" format="boolean" />
- </declare-styleable>
- </resources>
2、 然后新建一个继承View的SpreadView类:
- public class SpreadView extends View {
- //建立一个波纹的集合
- private List<Wave> waveList;
- //波纹的x,y坐标
- private int x = 0 ;
- private int y = 0 ;
- //波纹是否在运行,是否为第一次
- private boolean start ,first ;
- //波纹开始的延迟时间
- private int delay ;
- public void setStart(boolean start) {
- this.start = start;
- }
- public void setFirst(boolean first) {
- this.first = first;
- }
- public void setX(int x) {
- this.x = x;
- }
- public void setY(int y) {
- this.y = y;
- }
- public void setDelay(int delay) {
- this.delay = delay;
- }
- //波纹设置的最大透明度
- private static final int MAX_ALPHA = 255;
- public SpreadView(Context context, AttributeSet attrs) {
- super(context, attrs);
- //获取属性信息和设置默认值
- TypedArray a = context.obtainStyledAttributes(attrs,
- R.styleable.SpreadView);
- x = a.getInt(R.styleable.SpreadView_xDown,0);
- y = a.getInt(R.styleable.SpreadView_yDown,0);
- start = a.getBoolean(R.styleable.SpreadView_start,false);
- delay = a.getInt(R.styleable.SpreadView_delay,0);
- first = a.getBoolean(R.styleable.SpreadView_first,true);
- //波纹集合的实例化
- waveList = Collections.synchronizedList(new ArrayList<Wave>());
- //记得回收属性容器
- a.recycle();
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- if(waveList.size()==0&&(!first)) //波纹集合大小为0时,初始化
- init(); //非第一次初始化
- else if(waveList.size()==0&&first)
- initFirst(); //第一次初始化
- //绘制圆
- Wave wave = waveList.get(0);
- if(wave!=null)
- canvas.drawCircle(wave.xDown, wave.yDown, wave.radius, wave.paint);//用波纹的属性
- }
- private void initFirst() {
- if(this.start) { //如果属性值设为开始
- Wave wave = new Wave();
- wave.radius = 0;
- wave.alpha = MAX_ALPHA;
- wave.xDown = x;
- wave.yDown = y;
- wave.paint = initPaint(wave.alpha);
- waveList.add(wave);
- first = false; //设置第一次为false
- mHandler.sendEmptyMessageDelayed(0, delay);//带延迟异步任务
- }
- }
- //更新画笔
- private Paint initPaint(int alpha) {
- Paint paint = new Paint();
- paint.setAntiAlias(true);
- paint.setAlpha(alpha);
- paint.setColor(Color.WHITE);
- return paint;
- }
- public final Handler.Callback mHandlerCallback = new Handler.Callback(){
- @Override
- public boolean handleMessage(Message msg) {
- switch (msg.what){
- case 0:
- refreshState();
- invalidate();
- if (waveList != null &&waveList.size()>0) {
- mHandler.sendEmptyMessage(0); //不带延迟的异步
- }
- return true;
- default:
- return false;
- }
- }
- };
- private Handler mHandler = new Handler(mHandlerCallback);
- private void refreshState() {
- Wave w = waveList.get(0);
- if (w == null) {
- this.postInvalidate(); //如果没有波纹就重新绘制,重新运行onDraw()初始化
- } else {
- //波纹每次增加的半径大小,可自己修改,记得要转换为px。
- //(这里0.6单位为dp可以大概指出最大半径),如果不转换,那波纹的最大半径因手机的分辨率不同而不同
- w.radius += dip2px(getContext(),0.6f);
- //波纹每次减小的透明度
- w.alpha -= 1;
- //更新波纹的透明度
- w.paint.setAlpha(w.alpha);
- //当透明度小于0时,清理波纹列表,重新绘制初始化
- if (w.alpha < 0) {
- waveList.clear();
- this.postInvalidate();
- }
- }
- }
- public void init() {
- if(this.start) {
- Wave wave = new Wave();
- wave.radius = 0;
- wave.alpha = MAX_ALPHA;
- wave.xDown = x;
- wave.yDown = y;
- wave.paint = initPaint(wave.alpha);
- waveList.add(wave);
- mHandler.sendEmptyMessageDelayed(0, 1000);
- }
- }
- private class Wave {
- float radius;
- Paint paint;
- int xDown;
- int yDown;
- int alpha;
- }
- public static int dip2px(Context context, float dpValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
- return (int) (dpValue * scale + 0.5f);
- }
- }
注意每个SpreadView的延迟时间和ImageView的属性
4、接下来我们就要根据上面的布局在Activity手动计算波纹位置了:我们要把波纹的中心设在图片的中心(可看开始的效果图)
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/main"
- >
- <com.scb.administrator.a.SpreadView
- android:id="@+id/sv"
- app:xDown="0"
- app:yDown="0"
- app:start="false"
- app:first="true"
- app:delay="0"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- <com.scb.administrator.a.SpreadView
- android:id="@+id/sv1"
- app:xDown="0"
- app:yDown="0"
- app:start="false"
- app:first="true"
- app:delay="1900"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- <com.scb.administrator.a.SpreadView
- android:id="@+id/sv2"
- app:xDown="0"
- app:yDown="0"
- app:first="true"
- app:start="false"
- app:delay="3800"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#00000000"
- android:id="@+id/re_create2"
- >
- <TextView
- android:gravity="center"
- android:textSize="19sp"
- android:layout_margin="80dp"
- android:textStyle="italic"
- android:textColor="@color/white"
- android:text="H\nU\nS\nT\nO\nO"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- <ImageView
- android:id="@+id/go"
- android:background="#00000000"
- android:src="@drawable/fap_login"
- android:layout_margin="40dp"
- android:scaleType="centerCrop"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
- android:layout_width="54dp"
- android:layout_height="54dp" />
- </RelativeLayout>
- </FrameLayout>
4、接下来我们就要根据上面的布局在Activity手动计算波纹位置了:我们要把波纹的中心设在图片的中心(可看开始的效果图)
0 0
- Android 自定义控件---SpreadView
- Android 自定义控件---SpreadView
- [Android自定义控件] Android自定义控件
- Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- [Android自定义控件] Android自定义控件
- Android 自定义控件 单页翻书控件
- android虚线控件---自定义控件
- android自定义控件实例 --控件
- Android自定义控件--组合控件
- android 控件 自定义组合控件
- 【android自定义控件】ProgressBar自定义
- Android自定义控件 自定义属性
- Android自定义控件 -- 自定义View
- Android自定义控件 -- 自定义ViewGroup
- 如何编写一个自己的校验框架
- 像素翻转
- Android 5.0+ 解析(五)FloatingActionButton控件
- python学习01
- android api 中setVisibility( )的用法(可显示或隐藏布局或控件...)
- Android 自定义控件---SpreadView
- 字符串学习3
- Yii2 CURD使用心得(一)
- Summernote在线编辑器的使用,这也是个插件
- 根据图论构建可量化评估的产品设计模型-类图(Like Graph)
- redis简单应用
- Codeforces Round #291 (Div. 2)A Chewbaсca and Number
- 14.1 同步函数、死锁现象
- HDU1161 Eddy's mistakes