百度搜下自定义控件真的是五花八门,什么都有。但是每个app都有自己的特色,选择一款合适自己app风格的进度条才是最重要的。这里打造的这款进度条是针对内容上传的进度条,在进度条里可以显示上传的内容和上传的进度,还可以对上传的内容进行操作,比如取消上传、上传失败之后重新上传等。
现在开始打造这款进度条,首先要准备进度条的背景。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 背景 gradient是渐变,corners定义的是圆角 -->
<item android:id="@android:id/background">
<shape>
<solid android:color="#ffffffff" />
</shape>
</item>
<!-- 第二条进度条颜色 -->
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="#ffffffff"/>
</shape>
</clip>
</item>
<!-- 进度条 -->
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="#FF96A8D0" />
</shape>
</clip>
</item>
</layer-list>
这是正常上传时进度条的背景,这里用到了layer-list,这是将多个item按照顺序层叠起来,类似photoshop图层。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 背景 gradient是渐变,corners定义的是圆角 -->
<item android:id="@android:id/background">
<shape>
<solid android:color="#ffffffff" />
</shape>
</item>
<!-- 第二条进度条颜色 -->
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="#ffffffff"/>
</shape>
</clip>
</item>
<!-- 进度条 -->
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="#FFFF6666" />
</shape>
</clip>
</item>
</layer-list>
这是上传失败时的进度条背景。
接下来看进度条的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/progress_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffffff">
<RelativeLayout
android:id="@+id/progress_layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="2dp"
android:paddingTop="5dp">
<FrameLayout
android:id="@+id/imglayout"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp">
<ImageView
android:id="@+id/progress_imageview01"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:background="#ffededed"
android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/progress_imageview02"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_marginLeft="8dp"
android:layout_gravity="center_vertical"
android:background="#ffededed"
android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/progress_imageview"
android:layout_width="38dp"
android:layout_height="38dp"
android:layout_gravity="center_vertical"
android:background="#ffededed"
android:scaleType="centerCrop"/>
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_toRightOf="@+id/imglayout"
android:layout_centerVertical="true"
android:orientation="vertical">
<TextView
android:id="@+id/progress_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxWidth="175dp"
android:singleLine="true"
android:textColor="#ff999999"
android:textSize="14dp"/>
<TextView
android:id="@+id/progress_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxEms="12"
android:singleLine="true"
android:text="正在发送"
android:textColor="#ff333333"
android:textSize="12dp"/>
</LinearLayout>
<ImageView
android:id="@+id/progress_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="@drawable/probar_selector"
android:paddingTop="5dp"/>
<ImageView
android:id="@+id/progress_re_release"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/progress_cancel"
android:background="@drawable/re_probar_selector"/>
</RelativeLayout>
<ProgressBar
android:id="@+id/upload_progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@+id/progress_layout1"
android:progressDrawable="@drawable/probar_bg"/>
</RelativeLayout>
</RelativeLayout>
FrameLayout布局将三张图片叠加起来,给用户一种三维立体空间的感觉,然后将用户上传的内容显示在textView上,为用户添加可以操作的上传的按钮等等,最后在设置上传的进度条。
public class CustomProbar extends RelativeLayout {
private ProgressBar mSendBar;
private RelativeLayout mProgressLayout;
private View mProgress;
private ImageView[] mIV;
private TextView mProContent;
private ImageView mReRelease;
private ImageView mCancleRelease;
private TextView mState;
private Handler mHandler = new Handler();
private UploadClickListenr mUploadDataClickListenr;
private Bitmap[] mBmps = new Bitmap[3];
private boolean[]mHasBitmaps = new boolean[]{true,true,true};
public CustomProbar(Context context) {
this(context, null);
}
public CustomProbar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomProbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
/**
* 初始化控件
*
* @param context
*/
private void initView(Context context) {
mProgress = (View) LayoutInflater.from(context).inflate(R.layout.probar_layout, null);
addView(mProgress);
mSendBar = (ProgressBar) mProgress.findViewById(R.id.upload_progressbar);
mSendBar.setVisibility(View.GONE);
mSendBar.setMax(100);
mProgressLayout = (RelativeLayout) mProgress.findViewById(R.id.progress_layout);
mProgressLayout.setVisibility(View.GONE);
ImageView mProImgView = (ImageView) mProgress.findViewById(R.id.progress_imageview);
ImageView mProImgView01 = (ImageView) mProgress.findViewById(R.id.progress_imageview01);
ImageView mProImgView02 = (ImageView) mProgress.findViewById(R.id.progress_imageview02);
mIV = new ImageView[]{mProImgView,mProImgView01,mProImgView02};
mProContent = (TextView) mProgress.findViewById(R.id.progress_content);
mReRelease = (ImageView) mProgress.findViewById(R.id.progress_re_release);
mReRelease.setOnClickListener(mOnclickListener);
mReRelease.setVisibility(View.GONE);
mCancleRelease = (ImageView) mProgress.findViewById(R.id.progress_cancel);
mCancleRelease.setOnClickListener(mOnclickListener);
mState = (TextView) mProgress.findViewById(R.id.progress_state);
}
/**
* 点击事件监听器
*/
private OnClickListener mOnclickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (v == mReRelease) {
if (mUploadDataClickListenr != null) {
mUploadDataClickListenr.reRelease();
}
} else if (v == mCancleRelease) {
if (mUploadDataClickListenr != null) {
mUploadDataClickListenr.cancleRelease();
}
}
}
};
/**
* 设置图片,退出清除bitmap
*/
public void setProgressImage(final String[] imgs) {
if (imgs != null && imgs.length > 0) {
setImageVisi();
if (imgs.length <= 2) {
mIV[1].setVisibility(View.GONE);
}
if (imgs.length <= 1) {
mIV[2].setVisibility(View.GONE);
}
new Thread(new Runnable() {
@Override
public void run() {
//将图片路径docode解析成bitmap,如果解bitmap失败则将mHasBitmaps[]设为false
//将bitmap设置到ImageView上
mHandler.post(new Runnable() {
@Override
public void run() {
if (!mHasBitmaps[0] || !mHasBitmaps[1] || !mHasBitmaps[2]) {
setImageDefault();
return;
}
//设置图片
}
});
}
}).start();
} else {
setImageDefault();
}
}
/**
* ImageView的默认状态
*
*/
public void setImageDefault() {
for (int i = 0; i < 3; i++) {
mIV[i].setImageBitmap(null);
mIV[i].setBackgroundColor(0xffededed);
mIV[i].setVisibility(View.GONE);
}
}
/**
* 再设置ImageView之前调用
*
*/
public void setImageVisi() {
for (int i = 0; i < 3; i++) {
mIV[i].setImageBitmap(null);
mIV[i].setBackgroundColor(0xffededed);
mIV[i].setVisibility(View.VISIBLE);
}
}
/**
* 更新进度
*
* @param uploadSize 进度
* @param content 发送的内容
*/
public void visibleProgress(int uploadSize, String content) {
mSendBar.setVisibility(View.VISIBLE);
mProgressLayout.setVisibility(View.VISIBLE);
mSendBar.setProgressDrawable(getResources().getDrawable(R.drawable.probar_bg));
mSendBar.setProgress(uploadSize);
mProContent.setText(content);
mState.setText("正在发送");
mState.setTextColor(0xff000000);
mReRelease.setVisibility(View.GONE);
}
/**
* 取消发送或上传成功之后调用
*
*/
public void setGoneLayout() {
mSendBar.setVisibility(View.GONE);
mProgressLayout.setVisibility(View.GONE);
}
/**
* 发送失败调用
* 改变probar状态
*/
public void releaseResult(String message) {
mSendBar.setProgressDrawable(getResources().getDrawable(R.drawable.fail_progress_bg));
mReRelease.setVisibility(View.VISIBLE);
mState.setText(message);
mState.setTextColor(0xffff6666);
}
/**
* 重新发送调用
* 改变probar状态
*/
public void reRelease() {
mState.setText("正在发送");
mState.setTextColor(0xff000000);
mReRelease.setVisibility(View.GONE);
mSendBar.setProgressDrawable(getResources().getDrawable(R.drawable.probar_bg));
}
/**
* 关闭probar时候调用,回收释放bitmap
*/
public void closeView() {
for (int i = 0; i < 3; i++) {
if (mBmps[i] != null && !mBmps[i].isRecycled()) {
mBmps[i].recycle();
mBmps[i] = null;
}
}
}
/**
* 取消和重发按钮的回调
* @param l
*/
public void setUploadClickListenr(UploadClickListenr l) {
this.mUploadDataClickListenr = l;
}
public interface UploadClickListenr {
void reRelease();
void cancleRelease();
}
}
这是进度条控件的逻辑实现,为进度条设置状态和信息等等,为取消和重发按钮设置点击事件的回调。
最后使用就很简单,只需要为进度条初始化和设置信息就可以了。
<com.lwj.uiproject.CustomProbar
android:id="@+id/probar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
public class ProBarActivity extends BaseActivity {
private CustomProbar mProbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pro_bar);
mProbar = (CustomProbar)findViewById(R.id.probar_layout);
mProbar.visibleProgress(50,"nihao");
mProbar.setUploadClickListenr(new CustomProbar.UploadClickListenr() {
@Override
public void reRelease() {
//重发
}
@Override
public void cancleRelease() {
//取消
}
});
}
}
如果需要操作上传就需要实现点击事件的接口,在方法里面进行逻辑处理。