“This is the 8th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021”

Start by customizing a nice progress bar

public class GradualChangeProgressBar extends View {

    /** * Gradient color group */
    private int[] GRADIENT_COLORS = {Color.parseColor("#f3f3f3"), Color.parseColor("#06c661")};
    /** * Maximum progress */
    private float max = 100;
    /** * Current progress */
    private float progress;
    /** * brush */
    private Paint mPaint;
    /** * the width of the outer stroke */
    private float BORDER_STROCK;
    /** * The distance between the progress rectangle and the control boundary,≥BORDER_STROCK */
    private float PROGRESS_STROCK;
    // Width and height of the progress bar
    private int mWidth, mHeight;
    /** * Draw the rectangle for the progress bar */
    private RectF mRectF;

    /** * First layer rectangle color (progress bar stroke color) */
    private String FirstLayerColor ="#98d98e";
    public GradualChangeProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    public GradualChangeProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GradualChangeProgressBar(Context context) {
        this(context, null);
    }

    private void initView(a) {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mRectF = new RectF();
        BORDER_STROCK = getResources().getDimension(R.dimen.x2);
        BORDER_STROCK = getResources().getDimension(R.dimen.x2);
        PROGRESS_STROCK = getResources().getDimension(R.dimen.x3);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int round = mHeight / 2;// Radians are half the height
        mRectF.set(0.0, mWidth, mHeight);// First layer rectangle (stroke layer)
        mPaint.setColor(Color.parseColor(FirstLayerColor));// First layer rectangle color (progress bar stroke color)
        canvas.drawRoundRect(mRectF, round, round, mPaint);// Draw the first layer of rounded rectangle
        mPaint.setColor(Color.WHITE);// Second layer rectangle color (background layer color)
        mRectF.set(BORDER_STROCK, BORDER_STROCK, mWidth - BORDER_STROCK, mHeight - BORDER_STROCK);// Second layer rectangle (background layer)
        canvas.drawRoundRect(mRectF, round, round, mPaint);// Draw the background layer rounded rectangle (over the stroke layer)
        if (progress == 0)// If progress is 0, no progress is drawn
            return;
        float section = progress / max;
        // Layer 3 rectangle (progress layer)
        mRectF.set(PROGRESS_STROCK, PROGRESS_STROCK, (mWidth - PROGRESS_STROCK) * section, mHeight - PROGRESS_STROCK);
        // Create a linear color gradient
        LinearGradient shader = new LinearGradient(PROGRESS_STROCK, PROGRESS_STROCK,
                (mWidth - PROGRESS_STROCK) * section, mHeight - PROGRESS_STROCK, GRADIENT_COLORS, null, Shader.TileMode.MIRROR);
        mPaint.setShader(shader);// Layer 3 rectangle color (progress gradient)
        canvas.drawRoundRect(mRectF, round, round, mPaint);// Draw the third layer (progress layer) rounded rectangle (over the background layer)
        mPaint.setShader(null);// Clear the previously passed shader
    }

    /*** * Set the maximum progress **@param maxCount
     */
    public void setMax(float maxCount) {
        this.max = maxCount;
    }

    /*** * Sets the current progress **@param currentCount
     */
    public void setProgress(float currentCount) {
        this.progress = currentCount > max ? max : currentCount;
        invalidate();
    }

    public float getMax(a) {
        return max;
    }


    /** * Measure the width and height of the progress bar */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
            mWidth = widthSpecSize;
        } else {
            mWidth = 0;
        }
        if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
            mHeight = (int) getResources().getDimension(R.dimen.x20);
        } else{ mHeight = heightSpecSize; } setMeasuredDimension(mWidth, mHeight); }}Copy the code

With the introduction of the Fragment class, Google officially recommends you to use DialogFragment instead of the traditional Dialog. DialogFragment has very good features that Dialog does not have. You can make it more reusable (less coupling) and more convenient (better handling of screen flips).

  • Overwrite the onCreateView method in DialogFragment. The View created by this method will be used as the content layout of the Dialog in the same way that method 1 was used in the Activity.

Overwrite DialogFragment onCreateView method

Encapsulate an abstract class inheritanceDialogFragment

abstract class AbsDialogFragment extends DialogFragment {
Copy the code

Override the onCreateDialog function

@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { mContext = new WeakReference<>(getActivity()).get(); MRootView = LayOutinflater.from (mContext).inflate(getLayoutId(), null); Dialog = new Dialog(mContext, getDialogStyle()); // Instantiate Dialog dialog.setContentView(mRootView); dialog.setCancelable(canCancel()); dialog.setCanceledOnTouchOutside(canCancel()); setWindowAttributes(dialog.getWindow()); return dialog; }Copy the code

All the code

public abstract class AbsDialogFragment extends DialogFragment {

    protected Context mContext;
    protected View mRootView;

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        mContext = new WeakReference<>(getActivity()).get();

        mRootView = LayoutInflater.from(mContext).inflate(getLayoutId(), null);
        Dialog dialog = new Dialog(mContext, getDialogStyle());
        dialog.setContentView(mRootView);
        dialog.setCancelable(canCancel());
        dialog.setCanceledOnTouchOutside(canCancel());
        setWindowAttributes(dialog.getWindow());
        return dialog;
    }

    protected abstract int getLayoutId(a);

    protected abstract int getDialogStyle(a);

    protected abstract boolean canCancel(a);

    protected abstract void setWindowAttributes(Window window);

    protected View findViewById(int id) {
        if(mRootView ! =null) {
            return mRootView.findViewById(id);
        }
        return null;
    }

    protected boolean canClick(a) {
        returnClickUtil.canClick(); }}Copy the code

The original author of the progress bar code github_2011, the above code has been changed on this basis

Design a simple and generous layout

dialog_loading_progress_layout.xml


      
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/card_shape"
    android:padding="16dp"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <TextView
        android:id="@+id/tv_title"
        android:textColor="@color/black"
        android:textSize="17dp"
        android:text="Up in"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <cn.xy.view.view.GradualChangeProgressBar
        android:id="@+id/progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="36dip"
        android:layout_marginLeft="16dip"
        android:layout_marginRight="16dip"
        app:layout_constraintTop_toBottomOf="@+id/tv_title"/>


    <TextView
        android:id="@+id/tv_suspend"
        android:text="Hang"
        android:textColor="@color/purple_700"
        android:paddingTop="6dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingBottom="6dp"
        android:background="@drawable/bg_operator"
        android:layout_marginTop="39dip"
        android:layout_marginRight="16dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/progress"
        app:layout_constraintEnd_toEndOf="parent" />

    <TextView
        android:id="@+id/tv_value"
        android:text="99%"
        android:textColor="@color/purple_700"
        android:layout_marginTop="39dip"
        android:paddingTop="6dp"
        android:paddingRight="9dp"
        android:paddingBottom="6dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/progress"
       app:layout_constraintEnd_toStartOf="@+id/tv_suspend"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

The DialogProgressBar is then created and inherited from the AbsDialogFragment class. The next step is to simply initialize the controller to call the AIP

public class DialogProgressBar extends AbsDialogFragment implements View.OnClickListener {

    private TextView mTvTivle;/ / title
    private TextView mTvValue;// Current progress
    private TextView mTvSuspend;// Suspend the button
    private Context mContext =null;
    private GradualChangeProgressBar progressView ;// Customize the progress bar

    @Override
    protected int getLayoutId(a) {
        return R.layout.dialog_loading_progress_layout;
    }

    @Override
    protected int getDialogStyle(a) {
        return R.style.dialog;
    }

    @Override
    protected boolean canCancel(a) {
        return true;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Initialize the controller
        findViewById(R.id.tv_suspend).setOnClickListener(this);
        progressView = (GradualChangeProgressBar)findViewById(R.id.progress);
        mTvTivle = (TextView)findViewById(R.id.tv_title);
        mTvValue = (TextView)findViewById(R.id.tv_value);
        
    }


    @Override
    protected void setWindowAttributes(Window window) {
// window.setWindowAnimations(R.style.bottomToTopAnim);
        WindowManager.LayoutParams params = window.getAttributes();
        // Define the layout width and height
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.gravity = Gravity.CENTER;
        window.setAttributes(params);
    }


    /*** * Set the progress *@param progress
     */
    public void setProgress(float progress) {
        progressView.setProgress(progress);
        mTvValue.setText((int)progress+"%");
    }

    /** * set the title *@param title
     */
    public void setTitle(String title){
        mTvTivle.setText(title);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_suspend :
            // Click events can be emitted through the interface
                break; } dismiss(); }}Copy the code

A method is called

DialogProgressBar fragment = new DialogProgressBar();
fragment.show(getSupportFragmentManager(), "DialogProgressBar");
fragment.setProgress(val);
Copy the code

Hee hee no renderings will be treated as water paste