自定义Progress小控件
progress各种各样的都有,自定义大多数也是简单的,根据业务需求来自己定义,记录一下,先上效果图
本来想找个第三方改改就上的,不过自己的业务需求有点不搭,一下子没找到合适的,也没这么多时间去找了,想想还是自己写个吧,因为也简单
主要就是需求就是椭圆进度,百分比跟随渐变背景,这样一想其实就是一个布局,然后控制里面的进度长度,或者移动,我这是控制长度,这样毕竟简单,而且扩展好,以后进度条有什么奇葩需求也好改
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView; import com.app.commonlibrary.R; /**
* Created by LiuZhen on 2017/7/8.
*/ public class UpdateProgressBar extends FrameLayout { private TextView tv_progress;
private int width;
private ViewGroup.LayoutParams params;
/**
* The progress text offset.
*/
private int mOffset;
/**
* The progress text size.
*/
private float mTextSize;
/**
* The progress text color.
*/
private int mTextColor;
private float default_text_size;
/**
* The progress area bar color.
*/
private int mReachedBarColor;
/**
* The bar unreached area color.
*/
private int mUnreachedBarColor;
private final int default_reached_color = Color.rgb(66, 145, 241);
private final int default_unreached_color = Color.rgb(204, 204, 204);
private final int default_text_color = Color.rgb(66, 145, 241); public UpdateProgressBar(@NonNull Context context) {
this(context,null);
} public UpdateProgressBar(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
} public UpdateProgressBar(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int desiredWidth = 100;
int desiredHeight = 100; int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec); int height; //Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
} //Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
} int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
ViewGroup.LayoutParams lp = child.getLayoutParams();
int childWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width);
int childHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height);
child.measure(childWidthSpec, childHeightSpec);
}
params = tv_progress.getLayoutParams();
params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
tv_progress.setLayoutParams(params);
height = tv_progress.getMeasuredHeight();
//MUST CALL THIS
setMeasuredDimension(width, height);
} private void init(AttributeSet attrs, int defStyleAttr){ default_text_size = 8;
//load styled attributes.
final TypedArray attributes = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.UpdateProgressBar,
defStyleAttr, 0); mTextSize = attributes.getDimension(R.styleable.UpdateProgressBar_update_text_size, default_text_size);
mReachedBarColor = attributes.getResourceId(R.styleable.UpdateProgressBar_update_reached_color, default_reached_color);
mUnreachedBarColor = attributes.getResourceId(R.styleable.UpdateProgressBar_update_unreached_color, default_unreached_color);
mTextColor = attributes.getColor(R.styleable.UpdateProgressBar_update_text_color, default_text_color); setDefaultProgressBar(); mOffset = px2dip(3); attributes.recycle();
} private void setDefaultProgressBar(){
setBackgroundResource(mUnreachedBarColor);
tv_progress = new TextView(getContext());
tv_progress.setTextSize(mTextSize);
tv_progress.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
tv_progress.setTextColor(mTextColor);
tv_progress.setLines(1);
tv_progress.setBackgroundResource(mReachedBarColor);
tv_progress.setPadding(dip2px(4),0,dip2px(8),0);
tv_progress.setText("0 %");
addView(tv_progress);
} public void setProgress(int progress){
tv_progress.setText(progress+"%");
int proWidth = width*progress/100;
if (tv_progress.getMeasuredWidth() < proWidth) {
//这里不能填充mOffset,因为是椭圆进度条,填充会导致椭圆宽度被进度条覆盖,导致不美观
// tv_progress.setLayoutParams(params);
tv_progress.setWidth(proWidth);
}
} /**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public int dip2px(float dpValue) {
final float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
} /**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public int px2dip(float pxValue) {
final float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
} /**
* 将px值转换为sp值,保证文字大小不变
*/
public int px2sp(float pxValue) {
final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
} /**
* 将sp值转换为px值,保证文字大小不变
*/
public int sp2px(float spValue) {
final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
} }
UpdateProgressBar
用法布局文件
<com.progressbar.example.UpdateProgressBar
xmlns:pro="http://schemas.android.com/apk/res-auto"
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
pro:update_text_size="6sp"
pro:update_text_color="#FFFFFF"
pro:update_unreached_color="@drawable/shape_corner_progressbg"
pro:update_reached_color="@drawable/shape_corner_progressbar"/>
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast; import com.progressbar.NumberProgressBar; import java.util.Timer;
import java.util.TimerTask; public class MainActivity extends AppCompatActivity {
private Timer timer;
private UpdateProgressBar progressBar;
private int progress; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (UpdateProgressBar)findViewById(R.id.progress); timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
progress++;
progressBar.setProgress(progress);
if(progress == 100) {
Toast.makeText(getApplicationContext(), getString(R.string.finish), Toast.LENGTH_SHORT).show();
// progress = 0;
// progressBar.setProgress(0);
timer.cancel();
}
}
});
}
}, 1000, 100);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} @Override
protected void onDestroy() {
super.onDestroy();
timer.cancel();
}
}
MainActivity
渐变背景
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#4984f2"/> <gradient
android:startColor="#4984f2"
android:endColor="#000" /> <corners
android:topLeftRadius="15dp"
android:topRightRadius="15dp"
android:bottomLeftRadius="15dp"
android:bottomRightRadius="15dp"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#dadada"/> <gradient
android:startColor="#FFF"
android:endColor="#000" /> <corners
android:topLeftRadius="15dp"
android:topRightRadius="15dp"
android:bottomLeftRadius="15dp"
android:bottomRightRadius="15dp"/>
</shape>
自定义Progress小控件的更多相关文章
- jquery和css自定义video播放控件
下面介绍一下通过jquery和css自定义video播放控件. Html5 Video是现在html5最流行的功能之一,得到了大多数最新版本的浏览器支持.包括IE9,也是如此.不同的浏览器提供了不同的 ...
- 在 Visual C++ 中开发自定义的绘图控件
本文讨论的重点介于两者 之间 — 公共控件赋予您想要的大部分功能,但控件的外观并不是您想要的.例如,列表视图控件提供在许多视图风格中显示数据列表的方式 — 小图标.大图标.列表和详细列表(报告).然而 ...
- jQ效果:jQuery和css自定义video播放控件
下面介绍一下通过jquery和css自定义video播放控件. Html5 Video是现在html5最流行的功能之一,得到了大多数最新版本的浏览器支持.包括IE9,也是如此.不同的浏览器提供了不同的 ...
- C#自定义Button按钮控件
C#自定义Button按钮控件 在实际项目开发中经常可以遇到.net自带控件并不一定可以满足需要,因此需要自定义开发一些新的控件,自定义控件的办法也有多种,可以自己绘制线条颜色图形等进行重绘,也可以采 ...
- C# WinForm自定义通用分页控件
大家好,前几天因工作需要要开发一个基于WinForm的小程序.其中要用到分页,最开始的想法找个第三方的dll用一下,但是后来想了想觉得不如自己写一个玩一下 之前的web开发中有各式各样的列表组件基本都 ...
- C# 根据BackgroundWoker异步模型和ProgressBar控件,自定义进度条控件
前言 程序开发过程中,难免会有的业务逻辑,或者算法之类产生让人能够感知的耗时操作,例如循环中对复杂逻辑处理;获取数据库百万乃至千万级数据;http请求的时候等...... 用户在使用UI操作并不知道程 ...
- kettle系列-[KettleUtil]kettle插件,类似kettle的自定义java类控件
该kettle插件功能类似kettle现有的定义java类插件,自定java类插件主要是支持在kettle中直接编写java代码实现自定特殊功能,而本控件主要是将自定义代码转移到jar包,就是说自定义 ...
- (转)sl简单自定义win窗体控件
sl简单自定义win窗体控件 相信大家接触过不少win窗体控件ChildWin子窗口就的sl自带的一个 而且网上也有很多类似的控件,而今天我和大家分享下自己制作个win窗体控件,希望对初学 ...
- WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...
随机推荐
- 免费申请使用IBM Cloud Lite(轻量套餐) 详细教程指南
注册轻量帐户可在 IBM CLOUD控制台中使用所选的显示有轻量标记的免费轻量套餐来构建应用程序和探索服务.轻量帐户不会到期,也无需信用卡. 本文详细的介绍了一下,免费云服务的申请以及使用!这次使用I ...
- JS中的特殊类别注意区分
undefined和null 在JavaScript中存在这样两种原始类型:Null与Undefined. 这两种类型常常会使JavaScript的开发人员产生疑惑,在什么时候是Null,什么时候又是 ...
- [Swift]LeetCode398. 随机数索引 | Random Pick Index
Given an array of integers with possible duplicates, randomly output the index of a given target num ...
- [Swift]LeetCode860. 柠檬水找零 | Lemonade Change
At a lemonade stand, each lemonade costs $5. Customers are standing in a queue to buy from you, and ...
- [Swift]LeetCode958. 二叉树的完全性检验 | Check Completeness of a Binary Tree
Given a binary tree, determine if it is a complete binary tree. Definition of a complete binary tree ...
- [Swift]LeetCode977. 有序数组的平方 | Squares of a Sorted Array
Given an array of integers A sorted in non-decreasing order, return an array of the squares of each ...
- python高级-生成器(17)
1. 什么是⽣成器 通过列表⽣成式,我们可以直接创建⼀个列表.但是,受到内存限制,列表容量肯定是有限的.⽽且,创建⼀个包含100万个元素的列表,不仅占⽤很⼤的存储空间,如果我们仅仅需要访问前⾯⼏个元素 ...
- 自定义圆形的ProgressBar
1.自定义圆形的ProgressBar 效果图: 圆形ProgressBar的样式主要有以下几个,我们这里以progressBarStyleLarge为例进行样式的修改,其他的类似. <Prog ...
- 《HelloGitHub月刊》第 09 期
<HelloGitHub>第 09 期 兴趣是最好的老师,<HelloGitHub>就是帮你找到兴趣! 前言 转眼就到年底了,月刊做到了第09期,感谢大家一路的支持和帮助
- 消息队列、socket(UDP)实现简易聊天系统
前言: 最近在学进程间通信,所以做了一个小项目练习一下.主要用消息队列和socket(UDP)实现这个系统,并数据库存储数据,对C语言操作数据库不熟悉的可以参照我的这篇博客:https://www.c ...