0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlutterでQRコードを作ってみた

Last updated at Posted at 2020-12-01

はじめに

パッケージを使うだけで簡単に作れるQRコードリーダーです。

初投稿 and 自分用アプリでアウトプットも兼ねてるので、ツッコミ所あったら優しくお願いします。

#機能
【1】QRコードの読み取り(ギャラリー内とカメラに対応) ⇒Firebase MLkit不要
【2】QRコードの生成

環境

Windows10
AndroidStudio4.1

参考にしたレイアウト

https://www.youtube.com/watch?v=Hq-Ciuc6k0Y
この動画のコードで、詳細は動画内で確認できるので省略します。
※英語字幕のみの動画ですが、ホットリロード多めなので内容は理解できると思います。

#必要なパッケージ
pubspec.yaml に qr_flutter を追加します。

pubspec.yaml
dependencies:
  qr_flutter: ^3.2.0
  url_launcher: ^5.7.2
  super_qr_reader: ^2.0.2
  

目次

  1. Chapter1
  2. Chapter2
  3. Chapter3
  4. Chapter4
  5. 参考文献

Chapter1 トップ画面の作成

main.dart
import 'package:flutter/material.dart';
import 'package:tahara_qrcode_reader/HomePage.dart';


void main (){
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHomePage(),
    );
  }
}

mainからMyHomePageを呼び出し

HomePage.dart
import 'package:flutter/material.dart';
import 'package:tahara_qrcode_reader/QR%20Generator/QRGenerator.dart';
import 'package:tahara_qrcode_reader/ScanQR.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("QRスキャン / QR作成"),
      ),
      body: Container(
        height: MediaQuery
            .of(context)
            .size
            .height,
        child: SingleChildScrollView(
          child: ConstrainedBox(
            constraints: BoxConstraints(
                minHeight: (MediaQuery
                    .of(context)
                    .size
                    .height) -
                    AppBar().preferredSize.height -
                    kToolbarHeight),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                CircleAvatar(
                  backgroundImage: AssetImage(
                      "assets/images/aho5.jpg"
                  ),
                  foregroundColor: Colors.transparent,
                  backgroundColor: Colors.transparent,
                  radius: 150,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Hero(tag: "スキャン QR",
                      child: Container(
                        width: ((MediaQuery
                            .of(context)
                            .size
                            .width) / 2) - 45,
                        height: 50,
                        child: OutlineButton(
                          focusColor: Colors.red,
                          highlightColor: Colors.blue,
                          hoverColor: Colors.lightBlue[100],
                          borderSide: BorderSide(width: 3, color: Colors.blue),
                          shape: StadiumBorder(),
                          child: Text("QRをスキャン", style: TextStyle(fontSize: 15),
                          ),
                          onPressed: () {
                            Navigator.push(context, MaterialPageRoute(
                                builder: (context) => ScanQR()));
                          },
                        ),
                      ),
                    ),
                    SizedBox(width: 25,),
                    Container(
                      width: ((MediaQuery
                          .of(context)
                          .size
                          .width) / 2) - 45,
                      height: 50,
                      child: OutlineButton(
                        focusColor: Colors.red,
                        highlightColor: Colors.blue,
                        hoverColor: Colors.lightBlue[100],
                        borderSide: BorderSide(width: 3, color: Colors.blue),
                        shape: StadiumBorder(),
                        child: Text("QRを作成", style: TextStyle(fontSize: 17),
                        ),
                        onPressed: () {
                          Navigator.push(context, MaterialPageRoute(
                              builder: (context) => QRGenerator()));
                        },
                      ),
                    ),

                  ],
                )

              ],),

          ),
        ),
      ),
    );
  }
}

正直この辺は「参考にしたレイアウト」のほぼ丸コピ。
ボタン部分を「QRをスキャン」と「QRを作成」に変更
あとは CircleAvatar内に好きな画像を入れるだけ

Chapter2 QRスキャン部分

まずはコードから、そのあと解説

ScanQR.dart
import 'package:flutter/material.dart';
import 'package:super_qr_reader/super_qr_reader.dart';
import 'package:url_launcher/url_launcher.dart';

class ScanQR extends StatefulWidget {
  ScanQR({Key key}) : super(key: key);

  @override
  _ScanQRState createState() => _ScanQRState();
}

String qrData = "No data found!";
var data;
bool hasdata = false;

class _ScanQRState extends State<ScanQR> {
  @override
  Widget build(BuildContext context) {
    return Hero(
        tag: "QRをスキャン",
        child: Scaffold(
          appBar: AppBar(
            title: Text("QRスキャナー"),
          ),
          body: Container(
            width: double.infinity,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Flexible(
                      child: Text(
                        "URLにアクセス: ${(qrData)}",
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontSize: 20,
                        ),
                      ),
                    ),
                    IconButton(
                      icon: Icon(Icons.launch_outlined),
                      onPressed: hasdata
                          ? () async {
                              if (await canLaunch(qrData)) {
                                await launch(qrData);
                              } else {
                                throw "Could not Launch";
                              }
                            }
                          : null,
                    ),
                  ],
                ),
                SizedBox(
                  height: 20,
                ),
                Container(
                  width: ((MediaQuery.of(context).size.width) / 2) - 45,
                  height: 35,
                  child: OutlineButton(
                    focusColor: Colors.red,
                    highlightColor: Colors.blue,
                    hoverColor: Colors.lightBlue[100],
                    borderSide: BorderSide(width: 3, color: Colors.blue),
                    shape: StadiumBorder(),
                    child: Text(
                      "QRコードを読み込む",
                      style: TextStyle(fontSize: 11),
                    ),
                    onPressed: () async {
                      String results = await Navigator.push(
                        context,
                        MaterialPageRoute(builder: (context) => ScanView()),
                      );
                      if (results != null) {
                        setState(() {
                          qrData = results;
                          hasdata = true;
                        });
                      }
                    },
                  ),
                )
              ],
            ),
          ),
        ));
  }
}

ここからは「super_qr_reader」と「url_launcher」を使用
動画内のコードを一部編集。

【1】OnPressedから「super_qr_reader」のスキャン部分の「ScanView()」だけをもってきて、
取得したQRから取得したURLを、定義しといた「qrData」に代入⇒同じく定義しといた「hasdata」を、if文内でtrueに変更
(このへんは曖昧だけど、記述しなかったらランチャーが作動しなかったので、鍵のような役割かと思います。)

【2】「qrData」にURLが代入された後、「url_launcher」で遷移可能にする。
このへんは動画のコード丸パクリですが、「pub.dev」を見る限り、同じようなコードだったので
特にイジる必要はないかと

この二つのパッケージが偉大すぎる・・。

Chapter3 トップ画面の作成

いじれる自信がなかったので丸コピ
https://github.com/vijayinyoutube/QRScanner/tree/master/lib/QR%20Generator

強いて言うなら、海外の人が作成してるので、アイコンボタンやコメント部分は日本語に変更するなど

Chapter4 補足

「super_qr_reader」も作成者が海外の人のため、コメントを変更したい場合は、「scan_view」⇒「QrcodeReaderView」の順番でF4押していけばファイルに辿りつくので、編集可能です。

「"assets/tool_img.png"」の部分がギャラリーアクセス部分で、width/heightでサイズ変更可能
※そのあたりにコメントつける方法がわからないのでわかる方教えてほしいです

以上

参考文献

https://www.youtube.com/watch?v=Hq-Ciuc6k0Y
https://github.com/vijayinyoutube/QRScanner

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?