Android 自定义View——带下载进度Button
2016-08-08 15:16
351 查看
之前看到某些应用商店的下载按钮带下载进度提示,感觉很实用,自己也试着简单地实现这个功能。下面是效果图
在attrs.xml添加下载进度按钮所需的自定义属性
<declare-styleable name="DownLoadButton"> <attr name="normalBackground" format="reference|color"/> <attr name="downLoadedBackground" format="reference|color"/> <attr name="downLoadCompleteBackground" format="reference|color"/> <attr name="textColor" format="reference|color"/> </declare-styleable>
自定义下载进度按钮的代码
/** * Created by 犀利的小牛 on 2016/8/8. */ public class DownLoadButton extends Button { private Paint paint; /** * 文本颜色 */ private int textColor; /** * 未下载状态背景 */ private Drawable normalBackground; /** * 已下载进度背景 */ private Drawable downLoadBackground; /** * 下载完成背景 */ private Drawable completeBackground; /** * 未下载状态 */ public final static int STATE_NORMAL = 0; /** * 下载中 */ public final static int STATE_DOWNLOADING = 1; /** * 下载完成 */ public final static int STATE_COMPLETE = 2; /** * 当前状态 */ private int curState = 0; /** * 当前下载进度 * 百分比 */ private int curPrecent = 0; private OnDownLoadButtonClickListener onDownLoadButtonClickListener; public DownLoadButton(Context context) { this(context, null); } public DownLoadButton(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DownLoadButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DownLoadButton, defStyleAttr, 0); normalBackground = getResources().getDrawable(R.drawable.rect_normal_bg); downLoadBackground = getResources().getDrawable(R.drawable.rect_downloaded_bg); completeBackground = getResources().getDrawable(R.drawable.rect_complete_bg); final int N = a.getIndexCount(); for (int i = 0; i < N; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.DownLoadButton_normalBackground: normalBackground = a.getDrawable(attr); break; case R.styleable.DownLoadButton_downLoadedBackground: downLoadBackground = a.getDrawable(attr); break; case R.styleable.DownLoadButton_downLoadCompleteBackground: completeBackground = a.getDrawable(attr); break; case R.styleable.DownLoadButton_textColor: textColor = a.getColor(attr, getResources().getColor(R.color.color_white)); break; } } /** * 设置button本身的文字为透明以免干扰我们自己绘制上去的文字 */ setTextColor(getResources().getColor(R.color.color_transparent)); paint = new Paint(); paint.setAntiAlias(true); paint.setTextSize(getTextSize()); paint.setColor(textColor); curState = STATE_NORMAL; setGravity(Gravity.CENTER); /** * 设置点击事件 * 这个方法行得通,但是我感觉有更好的实现方式。 */ setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (onDownLoadButtonClickListener != null) { //点击时返回当前的状态 onDownLoadButtonClickListener.onClick(v, curState); } } }); } /** * 设置当前状态 * * @param state */ public void setState(int state) { this.curState = state; postInvalidate(); } /** * 设置下载进度 * * @param precent * 完成进度百分比 */ public void setDownLoadProgress(int precent) { this.curPrecent = precent; postInvalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width = 0; int height = 0; /** * 计算文本显示所需宽高 */ Rect textBound = new Rect(); String tip = getResources().getString(R.string.download_complete); paint.getTextBounds("下载完成", 0, tip.length(), textBound); if(widthMode == MeasureSpec.EXACTLY){ width = widthSize+getPaddingLeft()+getPaddingRight(); }else{ width = textBound.width()+getPaddingLeft()+getPaddingRight(); } if(heightMode == MeasureSpec.EXACTLY){ height = heightSize+getPaddingTop()+getPaddingBottom(); }else{ height = textBound.height()+getPaddingTop()+getPaddingBottom(); } setMeasuredDimension(width,height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); String tip = ""; switch (curState) { case STATE_NORMAL: tip = getResources().getString(R.string.download); curPrecent = 0; setBackgroundDrawable(normalBackground); break; case STATE_DOWNLOADING: tip = curPrecent+"%"; //计算当前进度所需宽度 int downLoadedWidth = (int) (getMeasuredWidth() * ((double) curPrecent / 100)); Rect rect = new Rect(0, 0, downLoadedWidth, getMeasuredHeight()); downLoadBackground.setBounds(rect); downLoadBackground.draw(canvas); break; case STATE_COMPLETE: tip = getResources().getString(R.string.download_complete); setBackgroundDrawable(completeBackground); break; } /** * 绘制提示文本 */ Rect textBound = new Rect(); paint.getTextBounds(tip, 0, tip.length(), textBound); canvas.drawText(tip,(getMeasuredWidth()-textBound.width())/2,(getMeasuredHeight()+textBound.height())/2, paint); } public void setOnDownLoadButtonClickListener(OnDownLoadButtonClickListener onDownLoadButtonClickListener) { this.onDownLoadButtonClickListener = onDownLoadButtonClickListener; } public interface OnDownLoadButtonClickListener { void onClick(View v, int curState); } }
MainActicity中的代码很简单,模拟下载过程
/** * Created by 犀利的小牛 on 2016/8/8. */ public class MainActivity extends AppCompatActivity implements DownLoadButton.OnDownLoadButtonClickListener { private DownLoadButton downLoadButton; private DownLoadHandler downLoadHandler; private final static int MESSAGE_DOWNLOADING = 0; private int downLoadedPrecent = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); downLoadHandler = new DownLoadHandler(); downLoadButton = (DownLoadButton) findViewById(R.id.downLoadButton); downLoadButton.setOnDownLoadButtonClickListener(this); } @Override public void onClick(View v, int curState) { if (curState == DownLoadButton.STATE_NORMAL) { //开始下载 downLoadButton.setState(DownLoadButton.STATE_DOWNLOADING); downLoadHandler.sendEmptyMessageDelayed(MESSAGE_DOWNLOADING,2000); }else if(curState == DownLoadButton.STATE_DOWNLOADING){ //下载中如果被点击时停止下载,这里可以根据自个的需求换成暂停或者其他 downLoadButton.setState(DownLoadButton.STATE_NORMAL); downLoadedPrecent = 0; downLoadHandler.removeMessages(MESSAGE_DOWNLOADING); } } private class DownLoadHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what){ case MESSAGE_DOWNLOADING: //模拟下载 downLoadedPrecent+=10; if(downLoadedPrecent>=100){ downLoadButton.setState(DownLoadButton.STATE_COMPLETE); }else{ downLoadButton.setDownLoadProgress(downLoadedPrecent); sendEmptyMessageDelayed(MESSAGE_DOWNLOADING,2000); } break; } } } }
最后是布局的代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:orientation="horizontal"> <com.xiaoniu.downloadbuttom.DownLoadButton android:id="@+id/downLoadButton" android:layout_width="120dp" android:layout_height="80px" android:textColor="@android:color/white" app:normalBackground="@drawable/rect_normal_bg" app:downLoadedBackground="@drawable/rect_downloaded_bg" app:downLoadCompleteBackground="@drawable/rect_downloaded_bg" android:textSize="20sp" app:textColor="@color/color_white" /> </LinearLayout>
————————————————————————
源码地址
相关文章推荐
- Android中使用自定义View实现下载进度的显示
- Android自定义View之可随时暂停、开启的圆形下载进度条
- Android自定义View绘制圆形、方形、弧形、球形四种形态的模仿下载进度条
- 自定义view实现下载进度button
- android自定义view 图片下载进度CoverView
- android 自定义下载进度条
- 【android】自定义ProgressDialog实现暂时隐藏进度值并显示等待状态(附源码下载)
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android自定义view 之 圆环ImageView 和 圆角按钮Button
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- android自定义Dialog实现文件下载和下载进度
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android自定义view之图片加载进度
- android 圆形进度条 自定义view
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Android高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- android文件下载及自定义通知显示下载进度
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)