打造可顯示上傳內容的自定義進度條

鋸齒流沙發表於2017-12-26

百度搜下自定義控制元件真的是五花八門,什麼都有。但是每個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() {
                //取消
            }
        });
    }
}
複製程式碼

如果需要操作上傳就需要實現點選事件的介面,在方法裡面進行邏輯處理。

相關文章