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?

Flutter備忘録

Last updated at Posted at 2024-11-26

はじめに

今回、Flutterでとあるアプリを開発していきたいのでそれらの備忘録をこちらにまとめていきます。

警告
あくまで備忘録のサンプルコードなので実行は自己責任でお願いします。

サンプルコードはWebベースでも走らせることができその際に前回でも利用した
Dartpadが便利なのでぜひご利用しながら試してみてください

Flutterをする上でDartに関する知識が必要になってきますのでその基礎などをまとめているのでぜひこちらもご覧下さい

また非常に有意義な資料がこちらにもあるので参考にしてみてください

アプリ開発における基礎知識

ウィジェット(widget)

アプリケーションを開発していくにあたってよく「ウィジェット」という言葉を耳にします。

ウィジェット

アプリの特に重要なデータや機能を「ひと目で」確認できるようにし、そうしたデータや機能にユーザーのホーム画面から直接アクセスできるようにするもの

上記のような解説でAndroid Studio公式さんは言ってます(詳しくはリンク参照で)
画面に表示されているUIの部品だと考えてもらってもいいっぽい


Stateless(ステートレス)とStateful(ステートフル)

Stateless → 初期化などしたら基本的に 変更がないもの

  • 使いどころ:静的なUIなどの部分(基本一度定義されたら変更のないもの)
  • 例: ボタンの色や固定された背景色など

Stateful → 変更などを 動的に 管理できるもの

  • 使いどころ:ユーザーなどの動作によって 変化があるところ
  • 例 : カウンターやユーザーの情報など

大きな違いとして「状態の変化」があるか無いか

本編

開発環境

今回使用している開発環境
OS:Windows11 Pro
IDE:VScode
Flutterバージョン:3.24.5
エミュレーター:Pixel 9 Pro XL API

ウィジェット各種について

表示についての基礎

今回はサンプル画面このようなサンプル画面を表示されるようなものを作るとします。
(文章はGPT大先生より)

Android

簡単にこれでやっていることの説明

  • サンプルプログラムを削除して、アプリのど真ん中に長い文章を6行で表示させるようにしている。

ここで使用しているウィジェット

  • CenterWidget
  • ChildWidget
  • TextWidget
  • TextStyleWidget

ウィジェットはある程度メソッドと考えてもOK
イメージとしては 引数として 要素を受け渡していっている
それらが 一つになり一つの画面 を生み出している。


ウィジット説明
CenterWidget → 中央に配置するものを定義
ChildWidget  → センターの子ウィジェットにとなりそこに要素を入れる
TextWidget  → テキストを配置するためのウィジェット
TextStyleWidget  → テキストの大きさなどを指定
引数として maxLines(何行で表示するか) を6行にして
overflow もし文字列が横幅を越したとき ellipis(訳:省略) として「...」を表示する。
また、フォントの色を黒色,大きさを16と定義している。

コード例
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

// Class MyHomePageState 
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: const Center(
        child: Text(
          'Flutterは、Googleが提供するモバイルアプリケーションフレームワークであり、単一のコードベースからAndroidおよびiOS用の高品質なアプリを構築できます。このテキストは長い文章の例として追加していますが、maxLinesプロパティによって行数が制限され、overflowプロパティで適切に処理されます。',
          maxLines: 6,  // 6行に設定
          overflow: TextOverflow.ellipsis, // 3点リーダーで省略
          style: TextStyle(
            fontSize: 16, // フォントサイズ
            color: Colors.black, // テキストの色
          ),// textStyle
        ), // child
      ), // center
    ); // Scaffold 
  } // build
} // class

上記の例のように色々ととウィジットによって管理でき,カスタマイズできるので皆さんも調べて試してみてください~

他詳細は以下の資料を見てください

Containerで遊んでみる(興味ある方のみどうぞ笑)

Containerウィジェットを利用することによって色々と表示で遊べます(下記のリンク参照)

https://api.flutter.dev/flutter/widgets/Container-class.html

ここに乗っているサンプルをもとにサンプルを上げて遊んでみたいと思います。(遊び心大事)

長方形の中にテキストを入れ込む(コンテナーで体裁管理)

実際のエミュレーターの画面

コード例

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      // アプリのボディ部分
      body: Center( // 真ん中に
        child: Container( // コンテナーとして
          padding: const EdgeInsets.all(20), // 余白を追加
          decoration: BoxDecoration(
            shape: BoxShape.rectangle, // 長方形を指定
            borderRadius: BorderRadius.circular(12), // 角を丸くする
            color: Colors.blue, // 背景色
          ),
          child: const Text( // コンテナーの子ウィジェットとしてテキスト定義
            "コンテナーで遊ぼう",
            style: TextStyle(
              color: Colors.white, // テキストの色
              fontSize: 18, // フォントサイズ
            ),
          ),
        ),
      ),
    );
  }
}

こんな感じで表示を遊ぶこともできます。
楽しくなってきたでしょう。

画像表示系

image.networkウィジェット

画像のリンクからアプリに表示させることができるもである。
今回はとても美味しかった、骨付き肉を堂々と画面中央に表示したいと思います。

今回作成するもののイメージ

以下元画像(これ実は羊肉です笑)
ご自由にお使いください


それでは気を取り直して
Image.network について

このウィジェットでは引数として以下のものを設定できます(一部抜粋)

  • src → 画像のアドレスを指定(リンク)
  • width / height → double型で認識されて縦幅、横幅を指定できる
  • fit → アスペクト比(縦横比)を変えてもはみ出さないようにする(親ウィジェット内で表示する)ための引数
コード例
mian.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Image.network(
          'https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/ff9dc245-ae03-5537-0b2d-9c83fc2b8053.png',
          width: 300, // 画像の幅を指定
          height: 250, // 画像の高さを指定
          fit: BoxFit.cover, // 親要素に合わせて表示
        ),
      ),
    );
  }
}


imgage.networkウィジェットはここまでです。

(ChatGPTに聞いたら画像ロードを判定させてロードのUIを表示させるとかできるらしい)


Image.assetウィジェット

今回のウィジェットはローカルファイルから画像を表示するウィジェットです。

今回は画像を変えてこれをローカルファイルから参照して画面中央に堂々と表示するようにしてみる

今回期待する画面


やり方

①プロジェクトフォルダの中にassets(任意で可能)フォルダを作成して画像を入れる

pubspec.yaml にパスを通す
プロジェクトフォルダの一番上の階層に入っています。

pubspec.yamlに設定を記述していきます。

pubsepec.yaml
# To add assets to your application, add an assets section, like this:
  assets: # 最初ここはコメントになっている
  # 相対パスを記述
  - assets/S__53043236.jpg # ここは自分で記述
  # - images/a_dot_burr.jpeg
  # - images/a_dot_ham.jpeg

コメントでも書いてますが「assets」はコメントになっておりコメントを外してあげて相対パスを記述してあげることにより使用できるようになります。

③実際にウィジェットを利用してみる

コード例
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Image.asset(
          'assets/S__53043236.jpg',
          width: 300, // 画像の幅を指定
          height: 250, // 画像の高さを指定
          fit: BoxFit.cover, // 親要素に合わせて表示
        ),
      ),
    );
  }
}

これで画像表示系は終わりです。

Paddingウィジェット

子ウィジェットにPadding(余白)を追加するウィジェットです。
子としてTextを持ちます

画面遷移イメージ

以下は、2つの画面を横並びに表示し、遷移の流れを示したものです。

変更前 変更後
現在の画面 次の画面

このようにして子ウィジェットにあたる「 Text 」に余白を持たせることのウェイジェットになっています。

実際のコード例
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Container(
        color: Colors.green,
        child: Padding(
          padding: const EdgeInsets.all(24.0), // パディングを追加
          child: const Text(
            "なんか色々と長めの文章を書いてみます。文章力がないのでなかなか文章が思いつかないですが頑張って文字書いてます。最近、美味しいシュークリーム屋さんを発見してテンションが結構上がってます。やったねー!",
            style: TextStyle(
              color: Colors.white, // 文字色を白に設定
              fontSize: 16, // フォントサイズを設定
            ),
          ),
        ),
      ),
    );
  }
}

paddingウィジェットの引数設定について(ChatGPTより)

引数呼び出しの際は名前付き引数となっており,明示的に引き渡す引数名を書く必要がある。
また、引数を一つだけでも指定は可能。

メソッド 説明 使用例
EdgeInsets.all 全方向(上下左右)に同じ余白を設定する EdgeInsets.all(8.0)
EdgeInsets.only 特定の方向(left, top, right, bottom)に余白を設定する EdgeInsets.only(left: 8.0)
EdgeInsets.symmetric 水平方向(horizontal)または垂直方向(vertical)に均等な余白を設定する EdgeInsets.symmetric(horizontal: 16.0)
EdgeInsets.fromLTRB 左(left)、上(top)、右(right)、下(bottom)の4方向それぞれに余白を設定する。 EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 16.0)

ColoredBoxウィジェット

指定したウィジェットの範囲をカラーボックスで囲むことのできるウィジェット

こんな感じで表示できるようになる

ちなにみPaddingウィジェットの子要素としても埋め込める

こんな感じで色々と遊べます。

コード例(Paddingを含んだバージョン)
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: ColoredBox(
        color: Colors.red, 
        child: Padding(

          padding: EdgeInsets.all(20),
          child: const Text(
            "テスト的な文章",
            style: TextStyle(
              color: Colors.white, 
              fontSize: 20, 
            ) // Padding  
          ),//TextStyle
        ), // Text
      ), // ColoredBox
    );
  }
}

色などの設定で使えるメソッド(Colorクラスのメソッド)

メソッド名 説明
fromARGB(int a, int r, int g, int b) ARGB(アルファ、赤、緑、青)で色を生成します。a は透明度、r は赤、g は緑、b は青の設定ができる
withOpacity(double opacity) 色の不透明度を変更した新しい色を返します。opacity は 0.0 から 1.0 の範囲で指定できる。
computeLuminance() 色の明るさ(輝度)を計算し、0.0(暗い)から 1.0(明るい)の範囲で返す
toString() 色を文字列として返す

となっており、今回のColorBoxのcolor引数として上記のメソッドを渡してやると自由に変えることができる。

Alignウィジェット

上下左右の配置を設定できるウィジェット

場所の指定するテンプレ

main.dart
Align(
    alignment: Alignment.// 指定する設定
    child: Text("テキスト")

こんな書き方をする
設定できるものとして以下のようなものがある

メソッド/プロパティ 説明
Alignment.topLeft ウィジェットを左上に配置する。
Alignment.topCenter ウィジェットを上中央に配置する。
Alignment.topRight ウィジェットを右上に配置する。
Alignment.centerLeft ウィジェットを中央左に配置する。
Alignment.center ウィジェットを完全に中央に配置する。
Alignment.centerRight ウィジェットを中央右に配置する。
Alignment.bottomLeft ウィジェットを左下に配置する。
Alignment.bottomCenter ウィジェットを下中央に配置する。
Alignment.bottomRight ウィジェットを右下に配置する。
Alignment(x, y) ウィジェットを指定した位置に配置する。xyは-1.0から1.0の範囲で、-1.0は左や上、1.0は右や下を意味する。

使用例(画像)
今回はtopCenterメソッド利用してみた

コード例
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Align(
        alignment: Alignment.topCenter,
        child: Text(
          "テスト的な文章"
        ),
      ),
    );
  }
}

ボタン系ウィジェット

Textbuttonウィジェット

画面にボタンを追加するウィジェット

基本文法

TextButton(
    // ボタンが押されたとき
    onPressed:(){
    // ここに処理を記述
    
    },
    // ボタン押されていないとき
    child: // 任意のウィジェット
)

今回、出力する画面例はこちらです

ボタンが押されたらコンソールに「もう来ないからね~」
と表示されます。

コード例
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: TextButton(
          onPressed: () {
            // ボタンが押されたときの処理を記述
            print("もう来ないからね~");
          },
          child: const Text("ボタン押してね~"),
        ),
      ),
    );
  }
}

Elevatedbuttonウィジェット

同じボタン系のウィジェットであるが立体的に結構わかりやすく視覚的にボタンを追加できる

画面出力例

コード例
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor:
                const Color.fromARGB(255, 17, 244, 17), // ボタンの背景色を濃く設定
          ),
          onPressed: () {
            // ボタンが押されたときの処理
            print("もう来ないからね~");
          },
          child: const Text("ボタン押してね~"),
        ),
      ),
    );
  }
}

ボタンの丸みを調整できるためのウィジェットもあり

main.dart
child: ElevatedButton(
          style: ElevatedButton.styleFrom(
              backgroundColor:
                  // ボタンの背景色指定
                  const Color.fromARGB(255, 17, 244, 17), // ボタンの背景色を濃く設定
              // 角をどれだけ丸にするかの設定
              shape: RoundedRectangleBorder( 
                  borderRadius: BorderRadius.circular(8)
                  ) // RoundedRectangleBorder
                ), // style
            // ...続く
    

のようにするとボタンの丸みを調整できる

完全な丸にするとき

 style: ElevatedButton.styleFrom(
            backgroundColor: const Color.fromARGB(255, 17, 244, 17), // 背景色
            shape: const CircleBorder(), // 角を丸く設定
            padding: const EdgeInsets.all(70), // パディング
          ),

OutlineButtoneウィジェットについて

これもボタンの一種です
これもほぼ同じなので詳細は割愛します

Centerの子ウィジェットにOutlineButtonと書くだけで他同じです

画面出力だけを提示しておきます

AlrtDialogウィジェット

ダイアログを表示するウィジェットで大体なにかの処理の後なので
showDialog関数 」で呼び出すようにする

このウィジェットは3つの構成要素を持ち

title → ダイアログ表示時のタイトル
content → ダイアログ内で行処理などのウィジェット
action → ダイアログが表示されたあとどのような動作でなにをするか

基本文法

showDialog(context: context,builder: (context){
return AlertDialog(
    title:    // ダイアログのタイトル
    content:  // ダイアログ内の内容
    action:   //ダイアログ内の処理
);    

画面例(TextButtonウィジェットと組み合わせてます)

ボタン押下前 ボタン押下後
コード例
main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: TextButton(
          onPressed: () {
            // ボタンが押されたときの処理を記述

            print("もう来ないからね~");
            showDialog(
                context: context,
                builder: (context) {
                  return AlertDialog(
                    title: Text("○っち"),
                    content: Text("もう来ないからね~"),
                    actions: [
                      TextButton(
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          child: Text("close"))
                    ],
                  );
                });
          },
          child: const Text("ボタン押してね~"),
        ),
      ),
    );
  }
}

最後に

あまり綺麗ではない備忘録を最後までご閲覧いただきありがとうございました。

備忘録なのでどんどん更新していくと思いますのでご期待ください。

ご指摘や「これいいよ!」とかあればぜひコメントいただけると嬉しいです。

僕みたいな初学者の方の足しに少しでもなればいいと思います。

参考にさせていただいた記事,資料など

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?