LoginSignup
12
12

More than 1 year has passed since last update.

EditTextに入力された値を一括で取得できるようにする

Last updated at Posted at 2021-06-13

前提条件

SDKバージョン: 30
Androidバージョン: 9.0

一般的なEditTextに入力された値を取得する方法

おそらく皆さんこんな感じかと思います。

var name = binding.editTextName.text.toString()
var height = binding.editTextHeight.text.toString()
var weight = binding.editTextWeight.text.toString()

私の場合はViewBindingを使用しているのでこんな感じでよく書きますが、findViewById()Kotlin extensionを利用していたとしてもさほどやり方は変わらないかと思います。要するに、取得したいeditTextのidを一つ一つ取得して、そのeditTextに入力された文字を受け取り、String型に直すという流れですね。「Android editText 値 取得」などで検索するといくらでも出てきます。

さて、入力されるeditTextが10個になったらこの作業を10回するのでしょうか。100個になったら100回するのでしょうか。一気に取得したくないですか?

EditTextに入力された値を一回で全て取得する

まず今回実現したいことは、画面に入力された3つのeditTextを一気に取得してcsvファイルに書き込むぞ!という処理です!
画面はこんな感じです。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
    android:background="@color/background_color"
    tools:context=".InputDataActivity">

    <LinearLayout
        android:id="@+id/container_for_toolbar"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></LinearLayout>

    <LinearLayout
        android:id="@+id/container_for_edit_text"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <EditText
            android:id="@+id/edit_text_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="名前"
            android:inputType="textPersonName"
            android:textSize="24sp" />

        <EditText
            android:id="@+id/edit_text_height"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="身長"
            android:inputType="textPersonName"
            android:textSize="24sp" />

        <EditText
            android:id="@+id/edit_text_weight"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="体重"
            android:inputType="textPersonName"
            android:textSize="24sp" />

        <Button
            android:id="@+id/btn_send"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:text="送信する"
            android:textColor="#393e46"
            android:textSize="24sp"
            android:textStyle="bold"
            app:backgroundTint="@color/light_green"
            app:rippleColor="@color/dark_green" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

入力して、送信ボタンを押すと、入力された値が一気に取得されてCSVファイルに書き込まれます。

以下のように書くと実現できます

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // bindingの初期化とsetContentViewを行う
        binding = ActivityInputDataBinding.inflate(layoutInflater)
            .apply { setContentView(this.root) }

        // 送信ボタンをクリック
        binding.btnSend.setOnClickListener {
            // 引数にeditTextを格納しているコンテナのidを入れる
            val patientsDataList = getAllInputData(binding.containerForEditText)
            createFile(patientsDataList)
        }    
}


// ===== editTextに入力された値を全て取得する =====
    private fun getAllInputData(group: ViewGroup): MutableList<String> {
        val count = group.childCount
        var editDataList = mutableListOf<String>()
        for (i in 0 until count) {
            val view = group.getChildAt(i)
            if (view is EditText) {
                Log.d("TAG", view.text.toString())
                editDataList.add(i, view.text.toString())
            }
        }
        return editDataList
    }

// ===== ファイルを作成して書き込み =====
private fun createFile(patientsDataList: MutableList<String>) {
        // 出力ファイルの作成
        val file = File(applicationContext.filesDir, fileName)
        val fw = FileWriter(file, false)
        val pw = PrintWriter(BufferedWriter(fw))

        // ヘッダーの指定
        pw.print("名前")
        pw.print(",")
        pw.print("身長")
        pw.print(",")
        pw.print("体重")
        pw.println()

        // データを書き込む
        val listSize = patientsDataList.size
        for (i in 0 until listSize) {
            if(i == listSize-1) {
                pw.print(patientsDataList[listSize - 1])
                pw.println()
            } else {
                pw.print(patientsDataList[i])
                pw.print(",")
            }
        }
        // ファイルを閉じる
        pw.close()
    }

上記のように書くと、getAllInputData()メソッドにてeditTextに入力された値が一気に取得されて、Listに入ります。Listに入ったデータはcreateFile()メソッドに渡されて、csvファイルに書き込みが行われ、内部ストレージに保存されます。このようにしてeditTextに入力された文字を一気に取得し、メソッドに一気に渡して処理してあげることができます。

getAllInputData()での処理ですが、これは単純にeditTextをfor文で回して一つ一つ取得しているようなイメージです。試しにLog.d("TAG", view.text.toString())の部分にブレークポイントを貼って、LogcatでTAGと検索し、ログを逐一確認してみましょう。入力された値が一つ一つ取得されているのが確認できます。

比較

もし今回のこの処理ですが、getAllInputData()を作成せずに書いたらどうなるのでしょうか

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // bindingの初期化とsetContentViewを行う
        binding = ActivityInputDataBinding.inflate(layoutInflater)
            .apply { setContentView(this.root) }

        // 送信ボタンをクリック
        binding.btnSend.setOnClickListener {
            // この部分が増える
            var name = binding.editTextName.text.toString()
            var height = binding.editTextHeight.text.toString()
            var weight = binding.editTextWeight.text.toString()
            val patientsDataList = mutableListOf(name, height, weight)

            createFile(patientsDataList)
        }    
}

// ===== ファイルを作成して書き込み =====
private fun createFile(patientsDataList: MutableList<String>) {
        // 出力ファイルの作成
        val file = File(applicationContext.filesDir, fileName)
        val fw = FileWriter(file, false)
        val pw = PrintWriter(BufferedWriter(fw))

        // ヘッダーの指定
        pw.print("名前")
        pw.print(",")
        pw.print("身長")
        pw.print(",")
        pw.print("体重")
        pw.println()

        // データを書き込む
        val listSize = patientsDataList.size
        for (i in 0 until listSize) {
            if(i == listSize-1) {
                pw.print(patientsDataList[listSize - 1])
                pw.println()
            } else {
                pw.print(patientsDataList[i])
                pw.print(",")
            }
        }
        // ファイルを閉じる
        pw.close()
    }

どうでしょうか。増えるのはこの4行です

// この部分が増える
var name = binding.editTextName.text.toString()
var height = binding.editTextHeight.text.toString()
var weight = binding.editTextWeight.text.toString()
val patientsDataList = mutableListOf(name, height, weight)

この4行が増えましたが、代わりにprivate fun getAllInputData(...)の処理が消えたので一見こっちの方が処理があっさりして見えますね。でも、今回は取得するeditTextがたったの3つでしたのでスッキリ見えますがこれが100個になったらどうでしょう。100個分取得しないとダメです。

// この部分が増える
var name = binding.editTextName.text.toString()
var height = binding.editTextHeight.text.toString()
var weight = binding.editTextWeight.text.toString()
val patientsDataList = mutableListOf(name, height, weight)

つまりこのコードが100行になります。

一方getAllInputData()を使用する場合はeditTextがいくら増えようがcontainer_for_edit_textのコンテナにeditTextが入っている限りは一回で取得できます。つまり途中でeditTextの数を増やしてもコードを変更する必要はないのです。

追記

コメントでのご指摘を受けてeditTextに入力された値を一気に取得するコードを以下のように修正しました。

    // ===== editTextに入力された値を全て取得する =====
    private fun getAllInputData(group: ViewGroup): MutableList<String> {
        var editDataList = mutableListOf<String>()

        group.children.forEachIndexed { i, view ->
            if (view is EditText) {
                Log.d("TAG", view.text.toString())
                editDataList.add(i, view.text.toString())
            }
        }
        return editDataList
    }
12
12
2

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
12
12