百度搜下自定義控制元件真的是五花八門,什麼都有。但是每個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() {
//取消
}
});
}
}
複製程式碼
如果需要操作上傳就需要實現點選事件的介面,在方法裡面進行邏輯處理。