質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

3726閲覧

ListViewを再描画したい

退会済みユーザー

退会済みユーザー

総合スコア0

Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2021/11/26 06:27

編集2021/11/26 07:04

前提・実現したいこと

ListViewの再描画

現在、ListViewを使用したシンプルなメモアプリを作成しています。
やりたいこととしましては、ListViewを長押し(長押しの実装はできております)して、編集を行い、上書きをしたいと思っております。それと合わせて複数行を表示出来るようにしたいと思っております。後一度ListViewに記載したものは、削除するまでアプリを閉じても表示しておきたいです。
今現在実装出来ていることは、皆様の助けもあり、ListViewに追加と同時にrealmに保存と、
タップの際にアラートダイアログを表示し、削除するかしないかの選択はできております。
最終的には、複数行表示し、Todoアプリを作りたいと考えております。

該当のソースコード

MainActivity

1class MainActivity : AppCompatActivity() { 2 override fun onCreate(savedInstanceState: Bundle?) { 3 super.onCreate(savedInstanceState) 4 setContentView(R.layout.activity_main) 5 6 val et_name : EditText = findViewById(R.id.et_name) 7 val bt_add : Button = findViewById(R.id.bt_add) 8 val bt_delete : Button = findViewById(R.id.bt_delete) 9 val lv : ListView = findViewById(R.id.lv) 10 11 val adapter = ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1, 12 mutableListOf()) 13 lv.adapter = adapter 14 15 //Realmを使う時に必要 16 val realm = Realm.getDefaultInstance() 17 18 //bt_addを押すとet_nameに入力した内容をDBに保存とListViewに表示する処理を記載する 19 bt_add.setOnClickListener { 20 if ( et_name.text.toString().isEmpty()){ 21 AlertDialog.Builder(this) 22 .setTitle("未入力") 23 .setMessage("名前を入力して下さい") 24 .setPositiveButton("OK",null) 25 .show()//et_nameが未入力の場合、アラートダイアログで表示 26 }else{ 27 realm.beginTransaction()//Realmのはじまり 28 try { 29 val user = realm.createObject(user::class.java) 30 user.setName(et_name.text.toString())//DBに書き込み 31 et_name.text.clear()//DBに書き込みしたらEditTextの文字をクリアする 32 Toast.makeText(applicationContext,"登録しました",Toast.LENGTH_SHORT).show()//トーストで表示 33 realm.commitTransaction() 34 adapter.add(user.getName())//et_nameの内容をListViewに追加する 35 }catch (e:RealmException){} 36 } 37 } 38 39 //ListViewをタップするとアラートダイアログを表示して、削除するかしないか判断する 40 //合わせてDBに登録されているデータも一緒に削除する 41 lv.setOnItemClickListener { parent, view, position, id -> 42 AlertDialog.Builder(this) 43 .setTitle("削除しますか??") 44 //Yesを押下した時の処理 45 //タップされたところの名前を削除とDBの削除 46 .setPositiveButton("Yes", DialogInterface.OnClickListener { dialog, which -> 47 //ListViewのタップした行のDBを削除する処理 48 realm.beginTransaction() 49 val delete = 50 adapter.getItem(id.toInt())//このコードでListViewの~行目のタップした文字を取得 //getItemIdだと何番目のListviewか取得できる 51 val realm_delete = realm.where(user::class.java).equalTo("name", delete) 52 .findAll()//ここで検索をかけて、realm_deleteに格納する(削除対象を取得) 53 realm_delete.deleteFirstFromRealm() 54 realm.commitTransaction() 55 et_name.text.clear() 56 //ListViewのタップした行を削除する処理 57 adapter.remove(adapter.getItem(id.toInt())) 58 adapter.notifyDataSetChanged() 59 Toast.makeText(applicationContext, "削除しました", Toast.LENGTH_SHORT).show() 60 }) 61 .setNegativeButton("No", DialogInterface.OnClickListener { dialog, which -> 62 Toast.makeText(applicationContext, "キャンセルしました", Toast.LENGTH_SHORT).show() 63 }) 64 .show() 65 } 66 //DBとListViewの項目全削除用 67 bt_delete.setOnClickListener { 68 AlertDialog.Builder(this) 69 .setTitle("項目の全削除") 70 .setMessage("項目を全て削除しますか?") 71 .setPositiveButton("削除",DialogInterface.OnClickListener { dialog, which -> 72 realm.beginTransaction() 73 realm.where(user::class.java).findAll().deleteAllFromRealm() 74 realm.commitTransaction() 75 adapter.remove(adapter.clear().toString()) 76 Toast.makeText(applicationContext,"全ての項目を削除しました",Toast.LENGTH_SHORT).show() 77 }) 78 .setNegativeButton("キャンセルする",null) 79 .show() 80 } 81 82 //項目の編集 83 //ListViewを長押しするとアラートダイアログを表示し、そこで入力した内容を上書きする 84 lv.setOnItemLongClickListener { parent, view, position, id -> 85 val et = EditText(this) 86 val item_word = adapter.getItem(id.toInt()) 87 et.setText(item_word)//編集画面を出したときに、入力してある文字をetに表示しておく 88 AlertDialog.Builder(this) 89 .setTitle("項目の編集") 90 .setMessage("編集しよう!!") 91 .setView(et) 92 .setPositiveButton("編集する",DialogInterface.OnClickListener { dialog, which -> 93 //ここに編集するコードを書きたい 94 Toast.makeText(applicationContext,"${item_word}",Toast.LENGTH_SHORT).show() 95 }).show() 96 true 97 } 98 } 99}

MainActivityXML

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 tools:context=".MainActivity"> 8 9 10 <EditText 11 android:id="@+id/et_name" 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:ems="10" 15 android:inputType="textPersonName" 16 android:hint="name" 17 app:layout_constraintStart_toStartOf="parent" 18 app:layout_constraintTop_toTopOf="parent" /> 19 20 <Button 21 android:id="@+id/bt_add" 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content" 24 android:text="add" 25 app:layout_constraintEnd_toEndOf="parent" 26 app:layout_constraintTop_toBottomOf="@+id/et_name" /> 27 28 <ListView 29 android:id="@+id/lv" 30 android:layout_width="409dp" 31 android:layout_height="636dp" 32 android:layout_marginStart="1dp" 33 android:layout_marginTop="1dp" 34 android:layout_marginEnd="1dp" 35 app:layout_constraintEnd_toEndOf="parent" 36 app:layout_constraintStart_toStartOf="parent" 37 app:layout_constraintTop_toBottomOf="@+id/bt_add" /> 38 39 <Button 40 android:id="@+id/bt_delete" 41 android:layout_width="wrap_content" 42 android:layout_height="wrap_content" 43 android:text="delete" 44 app:layout_constraintEnd_toStartOf="@+id/bt_add" 45 app:layout_constraintTop_toBottomOf="@+id/et_name" /> 46 47</androidx.constraintlayout.widget.ConstraintLayout>

user

1package com.example.realm_listview_app 2 3import io.realm.Realm 4import io.realm.RealmObject 5 6open class user : RealmObject(){ 7 private var name : String = "" 8 9 fun setName(name:String){ 10 this.name = name 11 } 12 13 fun getName():String{ 14 return name 15 } 16 17}

試したこと

初心者なりに考えたのは、編集が終わった後に、一旦その長押しした行番号を取得して、その行番号に追加なら出来るのではないかと思ったのですが、うまく出来ませんでした(私の知識不足だと思います)。
複数行はMapofを使えばいけると思ったのですが、追加がうまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

Android Studio Arctic Fox | 2020.3.1 Patch 1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

※動作は確認していません!

初期データの読み込みであれば、 adapter を作る際に findAll で読み込みしては如何でしょうか。

kotlin

1 //Realmを使う時に必要 2 val realm = Realm.getDefaultInstance() // <- 前に移動 3 4 val list = mutableListOf(realm.where(user::class.java).findAll()) 5 val adapter = ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1, list) 6 lv.adapter = adapter

また、レイアウトの ListView の設定を変えないと表示されないかもしれません。
(layout_width,layout_height の変更、layout_constraintBottom_toBottomOf 追加)

xml

1 <ListView 2 android:id="@+id/lv" 3 android:layout_width="0dp" 4 android:layout_height="0dp" 5 android:layout_marginStart="1dp" 6 android:layout_marginTop="1dp" 7 android:layout_marginEnd="1dp" 8 app:layout_constraintBottom_toBottomOf="parent" 9 app:layout_constraintEnd_toEndOf="parent" 10 app:layout_constraintStart_toStartOf="parent" 11 app:layout_constraintTop_toBottomOf="@+id/bt_add" />

前のご質問の回答の https://github.com/Jimbe-github/teratail-q370729 のレイアウトを使って、Realm( と RealmBaseAdapter) で動作するものになりましたので、ご提示させていただきます。

kotlin

1import androidx.appcompat.app.AppCompatActivity 2import android.os.Bundle 3import android.view.View 4import android.view.ViewGroup 5import android.widget.* 6import androidx.appcompat.app.AlertDialog 7import io.realm.Realm 8 9import io.realm.RealmBaseAdapter; 10import android.view.LayoutInflater 11import io.realm.RealmObject 12 13import io.realm.annotations.PrimaryKey 14 15open class Memo : RealmObject() { 16 @PrimaryKey 17 var name:String = "" 18 var age:Int = 0 19 var text:String = "" 20} 21 22class MainActivity : AppCompatActivity() { 23 //lateinit var dba: DatabaseAccesser 24 private lateinit var realm: Realm 25 26 override fun onCreate(savedInstanceState: Bundle?) { 27 super.onCreate(savedInstanceState) 28 setContentView(R.layout.activity_main) 29 30 val et_name : EditText = findViewById(R.id.et_name) 31 val bt_add : Button = findViewById(R.id.bt_add) 32 val bt_delete : Button = findViewById(R.id.bt_delete) 33 val lv : ListView = findViewById(R.id.lv) 34 35 //dba = SQLiteDatabaseAccesser(this) 36 realm = Realm.getDefaultInstance(); 37 38 val adapter = RealmMemoAdapter(realm) 39 lv.adapter = adapter 40 41 //bt_addを押すとet_nameに入力した内容をDBに保存とListViewに表示する処理を記載する 42 bt_add.setOnClickListener { 43 if(et_name.text.toString().isEmpty()){ 44 AlertDialog.Builder(this) 45 .setTitle("未入力") 46 .setMessage("名前を入力して下さい") 47 .setPositiveButton("OK",null) 48 .show()//et_nameが未入力の場合、アラートダイアログで表示 49 }else{ 50 val name = et_name.text.toString() 51 adapter.add(name, 0, "") 52 et_name.text.clear()//DBに書き込みしたらEditTextの文字をクリアする 53 Toast.makeText(applicationContext, "登録しました", Toast.LENGTH_SHORT).show()//トーストで表示 54 } 55 } 56 57 //ListViewをタップするとアラートダイアログを表示して、削除するかしないか判断する 58 //合わせてDBに登録されているデータも一緒に削除する 59 lv.setOnItemClickListener { _, _, position, _ -> 60 AlertDialog.Builder(this) 61 .setTitle("削除しますか??") 62 .setPositiveButton("Yes") { _, _ -> 63 //Yesを押下した時の処理 64 //タップされたところのメモの削除 65 adapter.remove(position) 66 et_name.text.clear() 67 //Toast.makeText(applicationContext,"削除しました",Toast.LENGTH_SHORT).show() 68 } 69 .setNegativeButton("No") { _, _ -> 70 Toast.makeText(applicationContext, "キャンセルしました", Toast.LENGTH_SHORT).show() 71 } 72 .show() 73 } 74 //これは予備コード 75 //DB全削除用 76 bt_delete.setOnClickListener { 77 realm.executeTransactionAsync { 78 it.where(Memo::class.java).findAll().deleteAllFromRealm() 79 } 80 } 81 } 82 83 override fun onDestroy() { 84 super.onDestroy() 85 //dba.destroy() 86 realm.close() 87 } 88} 89 90class RealmMemoAdapter(val realm:Realm) : RealmBaseAdapter<Memo>(null) { 91 init { 92 adapterData = realm.where(Memo::class.java).findAll() 93 } 94 class ViewHolder(view: View) { 95 var nameText: TextView 96 var ageText: TextView 97 var textText: TextView 98 init { 99 nameText = view.findViewById(R.id.nameText) as TextView 100 ageText = view.findViewById(R.id.ageText) as TextView 101 textText = view.findViewById(R.id.textText) as TextView 102 } 103 } 104 105 override fun getView(position: Int, view: View?, parent: ViewGroup?): View { 106 val v = view ?: 107 LayoutInflater.from(parent!!.context).inflate(R.layout.row_layout,null).apply { 108 tag = ViewHolder(this) 109 } 110 111 val vh = v.tag as ViewHolder 112 val memo:Memo = adapterData!!.get(position) 113 vh.nameText.text = memo.name 114 vh.ageText.text = memo.age.toString() 115 vh.textText.text = memo.text 116 117 return v 118 } 119 120 fun add(name:String, age:Int, text:String) { 121 realm.executeTransactionAsync( 122 Realm.Transaction { 123 it.createObject(Memo::class.java, name).apply { 124 this.age = age 125 this.text = text 126 } 127 }, 128 Realm.Transaction.OnSuccess { 129 notifyDataSetChanged() 130 } 131 ) 132 } 133 134 fun remove(position:Int) { 135 adapterData!!.get(position).let { 136 val name = it.name 137 realm.executeTransactionAsync( 138 Realm.Transaction { 139 it.where(Memo::class.java).equalTo("name", name).findFirst()?.deleteFromRealm() 140 }, 141 Realm.Transaction.OnSuccess { 142 notifyDataSetChanged() 143 } 144 ) 145 } 146 } 147}

投稿2021/11/26 08:25

編集2021/11/27 12:29
jimbe

総合スコア13209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/11/26 17:38

なお、前のご質問 https://teratail.com/questions/370729 の回答に載せましたコードは ListView のサンプルとして作成したもので、 GitHub のコード・レイアウトでプロジェクトを構成・実行して頂ければ、ちゃんと動作致します。 登録したものは次のアプリ起動時にも表示されますし、複数登録すれば複数表示され、削除すれば当然次の起動時には削除されています。 アプリの起動時に Adapter は データベースからのデータを読み込んで ListView に組み込まれることで初期表示を行い、 ListView やボタンの操作で Adapter 内のデータを更新するとデータベースを更新すると同時に ListView にも通知しています。 データベース毎の違いは多少あっても、 ListView と Adapter の関係やデータベース読み込み・更新のタイミング等は同じになるはずですので、参考にして頂けると幸いです。
退会済みユーザー

退会済みユーザー

2021/11/29 02:41

jimbe様 いつも回答有難うございます。 貴重なお時間でrealmでの表示も作成して頂き有難うございます。 本当に有難うございます。 まずjimbe様が追加で記載して頂いたコードをまず理解出来るように勉強致します。 アプリを起動した時の表示ですが、realmでfindallで読み込みすると、いつもなのですが他の文字も表示されてしまいます(user:[]みたいな感じです) まだまだ勉強することがたくさんありますので、勉強しながらjimbe様が記載して頂いたコード理解出来るように致します! 本当いつも有難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問