圓形進度條+二維碼掃描+自定義組合控制元件標題欄+自定義矩形view+介面回撥方法

Dewey-W發表於2017-11-05

說明:實現二維碼掃描:先在Android Studio上匯入libzing的Module,然後在當前app的Dependencies上把那個libzing庫檔案新增上去,這樣我們的app就關聯了那個libzing庫。



       詳情參考: http://blog.csdn.net/weixin_39586678/article/details/78132046#comments


需求:

(1)標題欄通過組合View的方式進行實現,統一對外暴露左側按鈕和右側按鈕點選的方法;

(2)在點選右側的回撥方法中跳轉到圖二所示頁面,圖二的頁面標題欄顯示上一個頁面組合View的檢視,通過自定義ViewGroup的方式實現梯形佈局(下一個檢視的起始位置是上一個檢視的結束位置)。

(3)圖一中間的進度條使用繼承自View的方式進行實現,並使用自定義屬性的方式來設定進度條中間的顏色。

(4)點選掃描二維碼按鈕之後,進度條開始以每秒10%的進度進行,當進度條走到100%後,跳轉到圖三的掃描二維碼頁面,實現掃描二維碼的功能


效果圖:

圖一:


圖二:


圖三:



功能程式碼:

1. 先定義自定義組合控制元件的標題欄 title_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--首先定義標題欄,使用組合控制元件-->
    <LinearLayout
        android:layout_height="52dp"
        android:background="#d3daec"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_gravity="center_vertical">

        <Button
            android:id="@+id/button_backward"
            android:layout_width="70dp"
            android:layout_height="match_parent"
            android:drawableLeft="@drawable/back_arrow"
            android:drawablePadding="6dp"
            android:background="#d3daec"
            android:gravity="center"
            android:paddingLeft="5dp"
            android:singleLine="true"  />

        <TextView
            android:text="那些花兒"
            android:textSize="28sp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:textColor="#878787"
            android:layout_gravity="center"
            android:layout_height="wrap_content"   />

        <Button
            android:singleLine="true"
            android:background="#d3daec"
            android:layout_width="70dp"
            android:id="@+id/button_forward"
            android:layout_marginRight="15dp"
            android:layout_height="wrap_content"
            android:drawableRight="@mipmap/ic_launcher" />
    </LinearLayout>

</LinearLayout>


對應的實現自定義組合控制元件的標題欄的java類:TitleView.java

package com.bwie.weekone_moni_jiekou.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import com.bwie.weekone_moni_jiekou.R;

/**
 * 自定義組合控制元件實現標題欄
 */
public class TitleView extends LinearLayout implements View.OnClickListener{
    private Context conText;
    public TitleView(Context context) {
        super(context);
    }

    public TitleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        conText = context;

        //將自定義組合控制元件佈局按鈕id填充到當前頁面
        View view = LayoutInflater.from(context).inflate(R.layout.title_layout, this, true);
        Button button_backward = view.findViewById(R.id.button_backward);
        Button button_forward = view.findViewById(R.id.button_forward);
        button_forward.setOnClickListener(this);
        button_backward.setOnClickListener(this);
    }

    public TitleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void onClick(View view) {
        //呼叫介面的方法
        titleViewClickListener.titleViewButtonClicked(view);
    }

    //自定義 介面的成員
    OnTitleViewClickListener titleViewClickListener;

    //自定義 實現按鈕點選事件的介面
    public interface  OnTitleViewClickListener{
        public void titleViewButtonClicked(View view);  //View view:傳的引數
    }

    //使用setter設定介面回撥的宣告變數
    public void setOnTitleViewClickListener(OnTitleViewClickListener titleViewClickListener){
        //在setter中把這個介面的實現 賦值給這個TitleView類上面實現的介面
        this.titleViewClickListener = titleViewClickListener;
    }
}

2. 實現引用標題欄的主程式碼類:MainActivity.java

package com.bwie.weekone_moni_jiekou;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import com.bwie.weekone_moni_jiekou.view.CustomCircleView;
import com.bwie.weekone_moni_jiekou.view.TitleView;

public class MainActivity extends AppCompatActivity {
    private CustomCircleView custom_circle;
    private TitleView titleView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //拿到圓形滾動條和自定義標題欄的檢視
        custom_circle = (CustomCircleView) findViewById(R.id.custom_Circle);
        titleView = (TitleView) findViewById(R.id.titleView);

        //呼叫自定義控制元件類中介面,實現按鈕的點選事件
        titleView.setOnTitleViewClickListener(new TitleView.OnTitleViewClickListener() {
            @Override
            public void titleViewButtonClicked(View view) {
                //判斷當前點選的view是哪個按鈕
                if (view.getId() == R.id.button_backward){       //左邊的返回按鈕
                    Toast.makeText(MainActivity.this, "點選返回", Toast.LENGTH_SHORT).show();
                    finish();
                }else if  (view.getId() == R.id.button_forward){ //右邊的登入按鈕{
                    //點選右邊的按鈕 跳轉到 SecondActivity,顯示矩形view
                    Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                    startActivity(intent);
                    finish();
                }
            }
        });
    }

    //點選按鈕,呼叫滾動條的方法,掃描二維碼
    public void saoMiaoCode(View view) {
        custom_circle.start();
    }
}

實現主程式碼類佈局的xml檔案:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!--呼叫自定義組合控制元件的標題欄-->
    <com.bwie.weekone_moni_jiekou.view.TitleView
        android:layout_weight="1"
        android:id="@+id/titleView"
        android:layout_height="0dp"
        android:layout_width="match_parent"  ></com.bwie.weekone_moni_jiekou.view.TitleView>

    <LinearLayout
        android:gravity="center"
        android:layout_weight="6"
        android:layout_height="0dp"
        android:orientation="vertical"
        android:layout_width="match_parent"  >

            <com.bwie.weekone_moni_jiekou.view.CustomCircleView
                android:id="@+id/custom_Circle"
                android:layout_width="300dp"
                android:layout_height="300dp" />

            <Button
                android:textSize="21sp"
                android:text="掃描二維碼"
                android:textColor="#80706e"
                android:layout_width="188dp"
                android:background="#619e85"
                android:onClick="saoMiaoCode"
                android:layout_marginTop="58dp"
                android:layout_height="wrap_content"  />
    </LinearLayout>
</LinearLayout>

3.  跳轉後的頁面,顯示矩形view:SecondActivity.java

package com.bwie.weekone_moni_jiekou;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
//顯示矩形view的頁面
public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        //點選第二個頁面的返回按鈕跳轉至上一個頁面
        Button button_backward = (Button) findViewById(R.id.button_backward);
        button_backward.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(SecondActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}

對應的xml佈局:activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!--首先定義標題欄,使用組合控制元件-->
    <LinearLayout
        android:layout_weight="0.35"
        android:layout_height="0dp"
        android:background="#d3daec"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_gravity="center_vertical">

        <Button
            android:id="@+id/button_backward"
            android:layout_width="70dp"
            android:layout_height="match_parent"
            android:drawableLeft="@drawable/back_arrow"
            android:drawablePadding="6dp"
            android:background="#d3daec"
            android:gravity="center"
            android:paddingLeft="5dp"
            android:singleLine="true"  />

        <TextView
            android:text="那些花兒"
            android:textSize="28sp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:textColor="#878787"
            android:layout_gravity="center"
            android:layout_height="wrap_content"   />

        <Button
            android:singleLine="true"
            android:layout_width="70dp"
            android:layout_marginRight="15dp"
            android:layout_height="wrap_content"
            android:drawableRight="@mipmap/ic_launcher" />
    </LinearLayout>

    <com.bwie.weekone_moni_jiekou.view.CustomRectView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="6"></com.bwie.weekone_moni_jiekou.view.CustomRectView>
</LinearLayout>

4. 實現自定義圓環進度條view:CustomCircleView.java

package com.bwie.weekone_moni_jiekou.view;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import com.xys.libzxing.zxing.activity.CaptureActivity;

/**
 * 自定義圓環進度條,顯示進度百分比
 * 點選掃描二維碼按鈕之後,進度條開始以每秒10%的進度進行,
 * 當進度條走到100%後,跳轉到圖三的掃描二維碼頁面,實現掃描二維碼的功能
 */
public class CustomCircleView extends View{
    private int progress = 0;
    private Context context;
    private Paint paint;

    public CustomCircleView(Context context) {
        super(context);
    }

    public CustomCircleView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public CustomCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;

        //建立一支畫筆
        paint = new Paint();
        //設定畫筆的顏色
        paint.setColor(Color.BLUE);
        //設定畫筆的style:內容是填充的空心圓
        paint.setStyle(Paint.Style.STROKE);
    }
    //執行進度條是耗時操作,需放在子執行緒中執行,進度達到100%後跳轉至 掃描二維碼 頁面
    public void start() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (progress >= 360) {
                        Intent intent = new Intent(context, CaptureActivity.class);
                        context.startActivity(intent);
                        return;
                    }
                    progress += 10;

                    //子執行緒重新整理 系統呼叫onDraw() 方法
                    postInvalidate();

                    try {
                        Thread.sleep(188);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //(1)獲取當前自定義view的寬高度
        int x = getWidth() / 2;
        int y = getHeight() / 2;

        //(2)設定圓半徑的大小
        int radius = 200;

        //(3)設定畫筆的粗細
        paint.setStrokeWidth(16);

        //(4)定義一個矩形區域:RectF物件持有一個矩形的四個float座標值
        RectF rectF = new RectF(x- radius,y - radius,x + radius, y + radius);
        //畫一個圓弧:drawArc方法:繪製圓弧,該方法用於在畫布上繪製圓弧,通過指定圓弧所在的橢圓物件、起始角度、終止角度來實現。
        canvas.drawArc(rectF,-90,progress,false,paint);

        //(5)把progress轉換為int值
        int intProgress = (int) ((float) progress / 360 * 100);

        //(6) measureText  測量字串的寬度
        float textWidth = paint.measureText(intProgress + "%");

        //(7)定義一個矩形區域:Rect物件持有一個矩形的四個integer座標值
        Rect rect = new Rect();
        //測量矩形中百分比的值的位置
        paint.getTextBounds(intProgress+"%",0,(intProgress+"%").length(),rect);

        //(8)設定畫筆寫出內容的size高度和粗細
        paint.setTextSize(28);
        paint.setStrokeWidth(1);

        //(9)畫出文字  rect.height() 獲取字串的高度
        canvas.drawText(intProgress+"%",x-textWidth/2,y+textWidth/2,paint);
    }
}

5. 實現自定義矩形view的類:CustomRectView.java

package com.bwie.weekone_moni_jiekou.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

/**
 * 自定義3個首尾相連的矩形view
 */
public class CustomRectView extends View{
    public CustomRectView(Context context) {
        super(context);
    }
    public CustomRectView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public CustomRectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //(1)設定畫筆的size
        Paint paint1 = new Paint();
        paint1.setTextSize(10);
        //(2)設定畫筆的顏色
        paint1.setColor(Color.BLUE);
        //(3)drawRect 就是使用畫筆繪製一個矩形 前面兩個引數代表起始座標, 也就是左上角 後面兩個引數可以標識你想畫的長度和寬度 也可以理解為右下角的座標點。
        Rect rect = new Rect(0,0,350,85);
        canvas.drawRect(rect, paint1);

        //(1)設定畫筆的size
        Paint paint2 = new Paint();
        paint2.setTextSize(10);
        //(2)設定畫筆的顏色
        paint2.setColor(Color.GREEN);
        //(3)drawRect 就是使用畫筆繪製一個矩形 前面兩個引數代表起始座標, 也就是左上角 後面兩個引數可以標識你想畫的長度和寬度 也可以理解為右下角的座標點。
        Rect rect2 = new Rect(350,80,730,160);
        canvas.drawRect(rect2, paint2);

        //(1)設定畫筆的size
        Paint paint3 = new Paint();
        paint3.setTextSize(10);
        //(2)設定畫筆的顏色
        paint3.setColor(Color.RED);
        //(3)drawRect 就是使用畫筆繪製一個矩形 前面兩個引數代表起始座標, 也就是左上角 後面兩個引數可以標識你想畫的長度和寬度 也可以理解為右下角的座標點。
        Rect rect3 = new Rect(730,160,1080,250);
        canvas.drawRect(rect3, paint3);
    }
}

注:掃描二維碼:最好在AndroidManifest.xml中新增相機使用許可權:

<uses-permission android:name="android.permission.CAMERA"></uses-permission>


相關文章