■ はじめに
https://dk521123.hatenablog.com/entry/2013/10/10/005010
の続き。今回は、ListView を使用する。(特にアダプタ周り)
■ 初期設定
例1での準備
build.gradle (Project:XXXX)
buildscript { dependencies { classpath 'com.android.tools.build:gradle:4.0.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "io.realm:realm-gradle-plugin:6.0.2" } }
build.gradle (Module:app)
apply plugin: 'kotlin-kapt' apply plugin: 'realm-android' dependencies { // RealmBaseAdapter 使用時 implementation 'io.realm:android-adapters:2.1.1' }
https://realm.io/docs/java/latest/#adapters
例2:Ankoを用いる場合
* Realm (DB) と Anko (ページ移動) を追加する => Realm と Anko については、以下の関連記事を参照のこと
./build.gradle
buildscript { ext.kotlin_version = '1.2.50' ext.anko_version = '0.10.5' // ★ Add ★ // ... 略 ... dependencies { classpath 'com.android.tools.build:gradle:3.1.4' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "io.realm:realm-gradle-plugin:5.4.1" // ★ Add ★ }
./app/build.gradle
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' // ★ Add ★ apply plugin: 'realm-android' // ★ Add ★ // ... 略 ... dependencies { // ... 略 ... implementation "org.jetbrains.anko:anko:$anko_version" // ★ Add ★ implementation 'io.realm:android-adapters:2.1.1' // ★ Add:今回で初めて追加 ★
■ サンプル
例1:Kotlin
[1] ListView を追加し、プロパティを変更する + id : 任意の文字列(今回は「wordListView」) + padding : 16dp [2] ListView の各行のレイアウトを追加するために [app]-[res]-[layout] を選択し、 右クリックし、[New]-[Layout Resource File]を選択し 以下を入力し「OK」ボタン押下 + File Name : 任意の文字列(今回は「word_row.xml」) + Root element : TextView [3] [app]-[res]-[layout] 配下にある[2]のファイルをダブルクリックし 以下のプロパティを入力する + id : 任意の文字列(今回は「wordItem」)
EnglishWord.kt
import io.realm.RealmObject import io.realm.annotations.PrimaryKey import io.realm.annotations.Required import java.util.* open class EnglishWord : RealmObject() { @PrimaryKey var id: String = UUID.randomUUID().toString() @Required var english: String = "" var japanese: String = "" var memo: String = "" }
MainAdapter.kt
import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.ArrayAdapter import android.widget.Toast import io.realm.Realm import io.realm.RealmResults import io.realm.Sort import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { private lateinit var realm: Realm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Realm.init(this) realm = Realm.getDefaultInstance() addFloatingActionButton.setOnClickListener { val intentToMoveAddPage = Intent( this, AddActivity::class.java) startActivity(intentToMoveAddPage) } // ListView の Clickイベント wordListView.setOnItemClickListener { adapterView, _, position, _ -> val listViewValue = adapterView.getItemAtPosition(position) as String Toast.makeText(this, "$listViewValue", Toast.LENGTH_SHORT).show() } } // 再開時の呼び出されるイベント override fun onResume() { super.onResume() val englishWordList = readAll() wordListView.adapter = ArrayAdapter<String>( this@MainActivity, R.layout.word_row, englishWordList.map { "${it.english}:\n${it.japanese}" } ) } fun readAll(): List<EnglishWord> { return realm.copyFromRealm( realm.where(EnglishWord::class.java) .findAll() .sort("english", Sort.ASCENDING)) } }
AddActivity.kt
import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Toast import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where import kotlinx.android.synthetic.main.activity_add.* import java.util.* class AddActivity : AppCompatActivity() { private lateinit var realm: Realm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_add) Realm.init(this) realm = Realm.getDefaultInstance() // Add addButton.setOnClickListener { try { realm.executeTransaction { val englishWord = realm.createObject(EnglishWord::class.java!!, UUID.randomUUID().toString()) englishWord.english = enEditText.text.toString() englishWord.japanese = jpEditText.text.toString() englishWord.memo = memoEditText.text.toString() val intentToMoveMainPage = Intent( this, MainActivity::class.java) startActivity(intentToMoveMainPage) } } catch (ex: Exception) { Toast.makeText(this, "Error...", Toast.LENGTH_SHORT).show() ex.printStackTrace() } } } }
例2:Ankoを用いる場合
をベースにする。 「DemoApplication.kt」「AndroidManifest.xml」「Comment.kt」は、 同じなので、上記の関連記事を参照。
CommentListViewAdapter.kt
import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import io.realm.OrderedRealmCollection import io.realm.RealmBaseAdapter class CommentListViewAdapter(data: OrderedRealmCollection<Comment>?) : RealmBaseAdapter<Comment>(data) { inner class ViewHolder(cell: View) { val id = cell.findViewById<TextView>(android.R.id.text1) val title= cell.findViewById<TextView>(android.R.id.text2) } override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val view: View val viewHolder: ViewHolder when (convertView) { null -> { val layoutInflater = LayoutInflater.from(parent?.context) view = layoutInflater.inflate(android.R.layout.simple_list_item_2, parent, false) viewHolder = this.ViewHolder(view) view.tag = viewHolder } else -> { view = convertView viewHolder = view.tag as ViewHolder } } adapterData?.run { val comment = get(position) viewHolder.id.text = comment.id.toString() viewHolder.title.text = comment.title } return view } }
ListViewActivity.kt
import android.support.v7.app.AppCompatActivity import android.os.Bundle import io.realm.Realm import kotlinx.android.synthetic.main.activity_list_view.* import org.jetbrains.anko.startActivity class ListViewActivity : AppCompatActivity() { private lateinit var realm: Realm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_list_view) this.realm = Realm.getDefaultInstance() val comments = realm.where(Comment::class.java).findAll().sort("id", Sort.ASCENDING) this.listView.adapter = CommentListViewAdapter(comments) this.listView.setOnItemClickListener { parent, view, position, id -> val comment = parent.getItemAtPosition(position) as Comment this.startActivity<EditCommentActivity>("comment_id" to comment.id) } } override fun onDestroy() { super.onDestroy() this.realm.close() } }
EditCommentActivity.kt
import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.view.View import android.widget.Toast import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where import kotlinx.android.synthetic.main.activity_edit_comment.* class EditCommentActivity : AppCompatActivity() { private lateinit var realm: Realm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) this.setContentView(R.layout.activity_edit_comment) this.realm = Realm.getDefaultInstance() val commentId = intent?.getLongExtra("comment_id", -1L) if (commentId != -1L) { val comment = realm.where<Comment>() .equalTo("id", commentId).findFirst() this.resultIdTextView.text = comment?.id.toString() this.resultTitleEditText.setText(comment?.title) this.resultDetailEditText.setText(comment?.detail) this.deleteButton.visibility = View.VISIBLE } else { this.deleteButton.visibility = View.INVISIBLE } this.saveButton.setOnClickListener { it: View? -> when (commentId) { -1L -> { try { realm.executeTransaction { val maxId = realm.where<Comment>().max("id") val targetId = (maxId?.toLong() ?: 0L) + 1L val comment = realm.createObject<Comment>(targetId) comment.title = this.resultTitleEditText.text.toString() comment.detail = this.resultDetailEditText.text.toString() Toast.makeText(this, "追加しました. ID : " + targetId.toString(), Toast.LENGTH_SHORT).show() } } catch (ex: Exception) { ex.printStackTrace() } } else -> { try { realm.executeTransaction { val comment = realm.where<Comment>() .equalTo("id", commentId).findFirst() comment?.title = resultTitleEditText.text.toString() comment?.detail = resultDetailEditText.text.toString() Toast.makeText(this, "修正しました.", Toast.LENGTH_SHORT).show() } } catch (ex: Exception) { ex.printStackTrace() } } } } this.deleteButton.setOnClickListener { realm.executeTransaction { realm.where<Comment>().equalTo("id", commentId)?.findFirst()?.deleteFromRealm() Toast.makeText(this, "削除しました.", Toast.LENGTH_SHORT).show() } } } override fun onDestroy() { super.onDestroy() realm.close() } }
参考文献
https://qiita.com/orimomo/items/bc1f2065f44104176f7f
関連記事
画面コンポーネント / ListView ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2013/10/10/005010
画面コンポーネント / RecyclerView ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/07/21/000000
DB を使用する ~ Realm 編 ~
https://dk521123.hatenablog.com/entry/2018/09/01/213649
Kotlin / Realm で英単語帳を作る
https://dk521123.hatenablog.com/entry/2020/07/20/232009
Realm に関するトラブル
https://dk521123.hatenablog.com/entry/2020/07/24/000000