二维码扫描之Zxing的一次实操记录,配合添加手电筒开关

刚好项目中涉及到了二维码扫描的功能,就记录下Zxing的使用过程,个人擅自添加了手电筒到界面,可以给大家一些参考。

首先看下效果图如下


这个红色的手电筒就是自定义加上去的,点击可以切换扫描时候的闪光灯的开关状态,下面看下一步一步实现的步骤。

1. 本实例基于AS 3.1.2的版本实现,所以看下依赖引入的实例。

implementation 'com.github.zagum:Android-SwitchIcon:1.3.7'
implementation('com.journeyapps:zxing-android-embedded:3.6.0') { transitive = false }
implementation 'com.google.zxing:core:3.3.0'

不过在引入之前需要在项目根目录的build.gradle中添加如下maven依赖地址

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
        jcenter()
    }
}

放上两个相关项目的Github地址,向原作者致敬

Android-SwitchIcon:https://github.com/zagum/Android-SwitchIcon

zxing-android-embedded : https://github.com/journeyapps/zxing-android-embedded

在GitHub上也有描述如何引入和使用,不太清楚的同学可以自己按照说明试下。

本实例使用了ButterKnife依赖,想偷懒的同学也记得一并引入。


2.看下准备工作,首先准备两个按钮的素材,这里呢我尝试了使用Vector 矢量图的素材,先把资源给大家。

首先是ic_torch.xml

<vector android:height="24dp" android:viewportHeight="1024"
    android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#ffffff" android:pathData="M514.38,543.73c16.17,0 29.27,14.4 29.27,32.17v81.45c0,17.76 -13.11,32.17 -29.27,32.17s-29.27,-14.4 -29.27,-32.17v-81.45c0,-17.76 13.11,-32.17 29.27,-32.17zM254.67,0h519.43c34.78,0 63.07,28.28 63.07,63.07v106.3c0,183.31 -100.17,293.63 -144.7,332.03v458.96c0,35.08 -28.44,63.64 -63.51,63.64L398.5,1024c-35.07,0 -62.21,-28.56 -62.21,-63.64L336.29,501.44c-44.52,-38.21 -144.7,-147.66 -144.7,-332.07L191.59,63.07C191.6,28.28 219.89,0 254.67,0zM612.48,952.32v-89.98L416.28,862.34v89.98L612.48,952.32zM762.3,234.46h-495.92c23.89,138.86 129.51,220.74 130.71,221.56 12.68,8.69 10.96,20.01 10.96,34.97v322.06h212.66L620.71,490.99c0,-14.9 -2.48,-26.17 10.11,-34.87 4.76,-3.36 107.66,-82.8 131.48,-221.66zM266.31,68.99v105.03h496.15L762.45,68.99L266.31,68.99z"/>
</vector>

另一个是扫描按钮ic_scan.xml

<vector android:height="24dp" android:viewportHeight="1024"
    android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#58aeae" android:pathData="M963.38,963.36L686.43,963.36v60.62L1024,1023.98L1024,692.67h-60.62v270.69zM60.62,692.67L0,692.67v331.31h337.57v-60.62L60.62,963.36v-270.69zM686.43,0v60.62h276.95v270.69L1024,331.31L1024,0L686.43,0zM60.62,60.62h276.95L337.57,0L0,0v331.31h60.62L60.62,60.62zM220.78,491.24L508.08,491.24L508.08,203.94L220.78,203.94L220.78,491.24zM281.4,264.56L447.46,264.56v166.06L281.4,430.62L281.4,264.56zM830.39,529.79L543.09,529.79v287.3h287.3L830.39,529.79zM769.77,756.47L603.71,756.47v-166.06L769.77,590.41v166.06zM767.99,205.92h60.62v285.13h-60.62L767.99,205.92zM545.07,205.92h113.34v113.34h-113.34v-113.34zM545.07,374.14h113.34v113.34h-113.34L545.07,374.14zM446.86,532.95h60.62L507.48,818.08h-60.62L446.86,532.95zM223.92,532.96h113.34v113.34h-113.34L223.92,532.96zM223.92,701.18h113.34L337.26,814.52h-113.34L223.92,701.18z"/>
</vector>

两个文件存放的位置在drawable文件夹中



3.素材准备好了之后开始处理界面和逻辑代码了,看下流程和实现。

首先是MainActivity点击按钮跳转

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.scan_btn)
    ImageView scanBtn;
    @BindView(R.id.scan_result)
    TextView scanResult;

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

    }


    @OnClick(R.id.scan_btn)
    public void onClick() {
        // 跳转到扫码界面进行扫码
        IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
        intentIntegrator
                .setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES)
                .setPrompt("将二维码/条码放入框内,即可自动扫描")//写那句提示的话
                .setOrientationLocked(false)//扫描方向固定
                .setCaptureActivity(ScanActivity.class) // 设置自定义的activity
                .initiateScan(); // 初始化扫描
    }

    // Get the results:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if (result != null) {
            if (result.getContents() == null) {
                Toast.makeText(this, R.string.scan_cancel, Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
                scanResult.setText("扫描结果:\n"+result.getContents());

            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

}

布局文件activity_main.xml很简单,就只有一个按钮,点击后会跳转到ScanActivity页面,在ScanActivity中可以增加些逻辑,因为activity_main.xml比较简单,这里就不贴出来了。按钮素材已经给了,怎么放的话大家可以自由发挥。看下ScanActivity写法,其中的注释写的很清楚了,其余的也是按照文档上的标准的东西来写的,拷贝用的话问题基本不大。

public class ScanActivity extends AppCompatActivity  {

    @BindView(R.id.dbv_custom)
    DecoratedBarcodeView dbvCustom;
    @BindView(R.id.switch_light)
    SwitchIconView switchLight;

    private CaptureManager captureManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan);
        ButterKnife.bind(this);

        // 如果没有闪光灯功能,就去掉相关按钮
        if (!hasFlash()) {
            switchLight.setVisibility(View.GONE);
        }

        captureManager = new CaptureManager(this, dbvCustom);
        captureManager.initializeFromIntent(getIntent(), savedInstanceState);
        captureManager.decode();

    }

    @Override
    protected void onPause() {
        super.onPause();
        captureManager.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        captureManager.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        captureManager.onDestroy();
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        captureManager.onSaveInstanceState(outState);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return dbvCustom.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
    }

    // 判断是否有闪光灯功能
    private boolean hasFlash() {
        return getApplicationContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    }

    @OnClick({R.id.switch_light, R.id.dbv_custom})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.switch_light:
                Log.d("CJT" , "switch_light  --  onClick");
                switchLight.switchState(true);
                if(switchLight.isIconEnabled()){
                    dbvCustom.setTorchOn(); // 打开手电筒
                }else{
                    dbvCustom.setTorchOff(); // 关闭手电筒
                }
                break;
            case R.id.dbv_custom:
                Log.d("CJT" , "dbv_custom  --  onClick");
                break;
        }
    }
}

贴出来对应的布局文件。acitivity_scan.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.ScanActivity">


    <com.journeyapps.barcodescanner.DecoratedBarcodeView
        android:id="@+id/dbv_custom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:zxing_framing_rect_height="200dp"
        app:zxing_framing_rect_width="200dp"
        app:zxing_preview_scaling_strategy="fitXY"
        app:zxing_use_texture_view="true" >


        <com.github.zagum.switchicon.SwitchIconView
            android:id="@+id/switch_light"
            android:layout_width="42dp"
            android:layout_height="42dp"
            android:layout_marginBottom="45dp"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_gravity="center"
            android:layout_marginTop="200dp"
            app:layout_constraintBottom_toBottomOf="@+id/dbv_custom"
            app:layout_constraintEnd_toEndOf="@+id/dbv_custom"
            app:layout_constraintStart_toStartOf="@+id/dbv_custom"
            app:si_animation_duration="200"
            app:si_disabled_alpha=".3"
            app:si_disabled_color="@color/state_off"
            app:si_enabled="false"
            app:si_no_dash="true"
            app:si_tint_color="@color/state_on"
            app:srcCompat="@drawable/ic_torch" />

    </com.journeyapps.barcodescanner.DecoratedBarcodeView>

</android.support.constraint.ConstraintLayout>

布局用的是默认的约束布局,其实用熟练了不比RelativLayout差,当然布局啥的也是根据大家的喜好自己使用,其中DecoratedBarcodeView是引入的Zxing依赖包自定义的一个布局,看了源码是继承自FrameLayout的,所以当然可以在这个布局上再添加些东西了,所以直接添加了一个SwitchIconView的控件,记得调下位置,居中靠底部就好了,这个SwitchIconView也有需要注意的地方

a.定义好si_disable_color和si_tint_color连个颜色资源,分别是切换状态时候的不同颜色

b.设置好srcCompat资源,这个最好使用矢量图来设置

c.si_no_dash是指在switchicon在off状态是否加斜杠,默然不加,duration是指动画时间,alpha是指off下的透明度


4.总结:在扫描界面扫码后得到的结果会回调MainActivty中的onActivityResult方法,把得到的结果返回。大家可以根据需要处理了,我这里主要演示在扫码界面使用第三方的控件定制了一个手电筒的开关按钮,控制闪光灯的开关,大家可以多方位的去实践创造更多的例子,Github确实给我们提供了很多便利,感谢前人的无私奉献。



  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涛声依旧Cjt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值