Android自定义View之图形图像(模仿360的刷新球自定义一个SeekBar)
2015-09-18 21:43
477 查看
概述:
360安全卫士的那个刷新球(姑且叫它刷新球,因为真的不知道叫什么好,不是dota里的刷新球!!),里面像住了水一样,生动可爱,看似简单,写起来不太简单,本例程只是实现了它的部分功能而已,说实话,跟360的刷新球比起来差距还是很大,我这个长得有点挫。本历程需要用到的知识包括:android的自定义View,自定义canvas、path、Bitmap、Handler
先结果演示:
Damo
public class MyPathView extends View { private int width; private int height; private int progress; private int maxProgress = 100; private Path mPath; private Paint mPaintCircle; private Paint mPaintWave; private Paint mPaintText; private Bitmap mBitmapBubble; private Canvas mCanvasBitmap; private int size = 0;//水波动幅度 private int count;//水流动距离 private boolean isAdd = true; private static final int START_W***E = 0x21; public int getProgress() { return progress; } public void setProgress(int progress) { this.progress = progress; invalidate(); } public int getMaxProgress() { return maxProgress; } public void setMaxProgress(int maxProgress) { this.maxProgress = maxProgress; } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case START_W***E: count += 30; if (count >= 180) { count = 0; } if (isAdd) { size += 7; if (size > 41) { isAdd = false; } } else { size -= 7; if (size <= -41) { isAdd = true; } } invalidate(); sendEmptyMessageDelayed(START_W***E, 100); break; } } }; public MyPathView(Context context) { super(context); } public MyPathView(Context context, AttributeSet attrs) { super(context, attrs); mPaintCircle = new Paint(); mPaintCircle.setStyle(Paint.Style.FILL_AND_STROKE); mPaintCircle.setColor(Color.argb(0X4f, 0x4d, 0x4d, 0xff)); mPaintText = new Paint(); mPaintText.setColor(Color.WHITE); mPaintText.setTextSize(50); mPaintText.setTextAlign(Paint.Align.CENTER); mPaintWave = new Paint(); mPaintWave.setColor(Color.argb(0xaa, 0xff, 0x7c, 0x00)); mPaintWave.setStyle(Paint.Style.FILL); //不显示非重叠部分,并且重叠部分显示自己 PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP); mPaintWave.setXfermode(mode); mPath = new Path(); handler.sendEmptyMessageDelayed(START_W***E, 1000); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height); mBitmapBubble = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); mCanvasBitmap = new Canvas(mBitmapBubble); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPath.reset(); //canvas.drawColor(Color.argb(0xaa, 0x88, 0x7e, 0x7f));//自定义颜色 mCanvasBitmap.drawCircle(width / 2, height / 2, 200, mPaintCircle); mPath.reset(); //用path圈出一个矩形,把水波和球的包含进去 mPath.moveTo(width / 2 + 200, height / 2 + 200 - progress / maxProgress * 400); mPath.lineTo(width / 2 + 200, height / 2 + 200); mPath.lineTo(0, height / 2 + 200); mPath.lineTo(0, height / 2 + 200 - progress / maxProgress * 400); /* 画一条个模拟流动的波浪 */ //当count增大时,重绘会显示向前流动效果,count的值不能大于width/2-200 mPath.lineTo(count, height / 2 + 200 -(float) progress / maxProgress * 400); // mPath.moveTo(count,200); //size的从大到小从小到大变化,重绘时会产生波浪起伏效果 for (int i = 0; i < 20; i++) { /* rQuadTo()方法每次都会自动移动到下一位置,参数依次为水平幅度, 垂直幅度,水平位移,处置位移 */ mPath.rQuadTo(20, size, 90, 0); mPath.rQuadTo(20, -size, 90, 0); } mPath.close(); mCanvasBitmap.drawPath(mPath, mPaintWave); canvas.drawBitmap(mBitmapBubble, 0, 0, null); //绘制文本,当前进度 canvas.drawText(progress*100/maxProgress+"%",width/2,height/2,mPaintText); } }
主活动调用自定义View:
public class MainActivity extends Activity { private int progress; private Button mButtonStart; private MyPathView myPathView; private static final int DOWNLOAD_UPDATE = 0x99; //模拟下载 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); //处理msg switch (msg.what) { case DOWNLOAD_UPDATE: progress += 1; //当progress大于maxProgress时,不再调用一下方法 if (progress<=myPathView.getMaxProgress()){ myPathView.setProgress(progress);//设置新的进度 sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 100);//每隔100毫秒发送一次handler } break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButtonStart = (Button) findViewById(R.id.button_start); myPathView = (MyPathView) findViewById(R.id.progress_view_first); mButtonStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //向handler发送一个延时空消息,1000毫秒后发送 mHandler.sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 1000); } }); } }
布局调用自定义View:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/button_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start Download"/> <com.example.administrator.selfdefinedview.widget.MyPathView android:id="@+id/progress_view_first" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
相关文章推荐
- Android公共库的建立方法
- Android自定义View---PorterDuffXfermode两个交叠图形的显示
- Android公共库的建立方法
- Android-自定义属性的使用
- Android设置透明、半透明等效果
- 为 Activity 设置切换动画
- Android之Color颜色值和RGB颜色对照表
- Android绘图:360加速球
- Android 自定义View——蒙版擦除效果实现
- android selector 小坑
- Android绘图:Canvas绘制联系人姓氏侧滑列表
- Android图形图像之自定义控件属性(demo:刮刮乐与打码以及图片的缓存)
- Android中的AnimationDrawable的使用
- android BrocadcastReceiver
- 左右 android AES 所述机器的一部分 javax.crypto.BadPaddingException: pad block corrupted
- android通讯录根据首字母分组(二)
- android使用自定义字体
- Android4.1添加新的按键(2)
- Android4 .1添加新的按键(1)
- Android4.1添加新的按键(3)