打造可显示上传内容的自定义进度条

429 阅读5分钟

百度搜下自定义控件真的是五花八门,什么都有。但是每个app都有自己的特色,选择一款合适自己app风格的进度条才是最重要的。这里打造的这款进度条是针对内容上传的进度条,在进度条里可以显示上传的内容和上传的进度,还可以对上传的内容进行操作,比如取消上传、上传失败之后重新上传等。

521ab5a1ea304b938849f410805404bd.jpg
这是进度条的效果。

现在开始打造这款进度条,首先要准备进度条的背景。

<?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() {
                //取消
            }
        });
    }
}

如果需要操作上传就需要实现点击事件的接口,在方法里面进行逻辑处理。