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

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

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

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

Android Studio

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

Kotlin

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

Q&A

1回答

1782閲覧

【Android】recyclerview + roomで境界線を動的に表示したい

bunjin

総合スコア0

Android

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

Android Studio

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

Kotlin

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

0グッド

0クリップ

投稿2021/12/05 06:25

編集2021/12/05 06:27

前提

現在android studioでtodoリストを作っております。
仕様は次の通りになります。

  • roomに登録したtodoリストデータを、recyclerviewで一覧表示する(データは登録、更新、削除が別画面にて行える)
  • リスト行の左側にはチェックボックスが用意されており、チェックが入ると次を行う

①番号リスト文字をグレー化する
②取り消し線が表示される
③行を自動的に下部に移動する(チェックがついていない行とついている行でソートする)
④右下のFABボタンを押下する事でチェック状況をroomに更新する

アプリのイメージは次の通りになります。

todoリスト作成時
イメージ説明

チェック押下後

イメージ説明

実現したいこと

チェックがついていない行とついている行に、次のイメージのような境界線を
導入したいと考えております。
イメージ説明

リスト内にチェックが1つもついていない場合は境界線を表示せず、1つ以上チェックがついたら
境界線を表示させる処理を実現したいのですが、アイデアが思い浮かばず悩んでおります。

リストデータに境界線用のデータを追加し、todoデータ用レイアウトと境界線用レイアウトを表示させる方法を考えたのですが、
roomに更新・取得する際に次の処理を行うことに違和感を感じました。
①更新時に境界線用のデータを除外しなくてはならない
②取得時に境界線用のデータを作成しなくてはならない

アドバイスなど御座いましたら、ご教示頂けませんでしょうか。
宜しくお願い致します。

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

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

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

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

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

jimbe

2021/12/05 06:38

"違和感を感じている" コードやレイアウトをご提示頂けませんでしょうか。
hoshi-takanori

2021/12/05 09:08 編集

例えば 1 と 3 にチェックした場合、順番はそのままで 1 と 2 の間と 2 と 3 の間にそれぞれ境界線が入るのでしょうか? それとも、チェックのついてない 2 と、チェックされた 1 と 3 をグループ分けして、境界線は 1 本だけ?
bunjin

2021/12/05 15:24

>jimbeさん 早速のご回答ありがとうございます。 ごめんなさい、"違和感を感じている"コードについては実装手段を考えている段階に留まっており、まだ実装はしていないです... >hoshi-takanori ご回答ありがとうございます。 ごめんなさい、ソートについて説明が不十分でした。 1と3にチェックした場合ですが、例えば次の状態でリストがあるとします。 ----------------- □1 □2 □3 ----------------- ここで、1にチェックを入れると、チェックを入れたtodoが自動的に最下部にソートします。 ----------------- □2 □3 ☑1 ----------------- 更に、2にチェックを入れると、2が最下部にソートします。 ----------------- □3 ☑1 ☑2 ----------------- 実装では、各todoにソート番号を持たせて、第一ソートをチェックの有無、第二ソートをtodoのソート番号としてソートさせております。 チェックに設定したイベントハンドラーを用いて上記ソートを行い、ソート後のポジション番号をnotifyItemChangedメソッドに渡し、アニメーション表示で移動をさせています。 そのため、リストの上部にはチェック無し、下部にはチェック有りで表示される仕様となっております。 やりたい事は、チェック無しと有りの間に境界線を1本入れたいと考えております。先ほどの例でいうと、1のみチェックをいれた場合は ----------------- □2 □3 ーー境界線ーー ☑1 ----------------- 1と2にチェックを入れた場合は ----------------- □3 ーー境界線ーー ☑1 ☑2 ----------------- と表示されるように出来ればと考えております。
jimbe

2021/12/06 05:43

> "違和感を感じている"コードについては実装手段を考えている段階に留まっており 感覚だけで躊躇していても埒が明きません。ご提示の「イメージ」はどのように作成されたのでしょうか。 とにかく書いてみてそれをご提示頂いた上で「これはどうにかならないものか」というご質問のほうが具体的かつ修正等の提案も受け易いと思うのですが、如何でしょうか。
guest

回答1

0

表示だけのことですので、リストデータを弄る必要はありません。
complete と表示したい position のデータを求められたら complete のレイアウトデータを返すようにし、 それ以降のデータを求められたら position-1 の位置の実際のデータを返すだけです。


Room は関係しなくても良さそうですので、表示部分だけテキトウに作って見ました。
(単に kotlin も Room も不慣れ(or ほぼ分からない)なだけですが...)

kotlin

1package com.teratail.q372341 2 3import android.os.Bundle 4import android.view.LayoutInflater 5import android.view.View 6import android.view.ViewGroup 7import android.widget.CheckBox 8import android.widget.TextView 9import androidx.appcompat.app.AppCompatActivity 10import androidx.lifecycle.MutableLiveData 11import androidx.lifecycle.ViewModel 12import androidx.lifecycle.ViewModelProvider 13import androidx.recyclerview.widget.LinearLayoutManager 14import androidx.recyclerview.widget.RecyclerView 15 16class MainActivity : AppCompatActivity() { 17 override fun onCreate(savedInstanceState: Bundle?) { 18 super.onCreate(savedInstanceState) 19 setContentView(R.layout.activity_main) 20 21 val adapter = ToDoAdapter() 22 val recyclerView = findViewById<RecyclerView>(R.id.recyclerview) 23 recyclerView.adapter = adapter 24 recyclerView.layoutManager = LinearLayoutManager(this) 25 26 val todoViewModel = ViewModelProvider(this).get(ToDoViewModel::class.java) 27 todoViewModel.readAllData.observe(this, { todo -> adapter.setData(todo) }) 28 29 todoViewModel.add(ToDo(1, false, "todo 1")) 30 todoViewModel.add(ToDo(2, true, "todo 2")) 31 todoViewModel.add(ToDo(3, false, "todo 3")) 32 } 33} 34 35data class ToDo( 36 val id: Int, 37 val complete: Boolean, 38 val text: String 39) 40 41class ToDoAdapter: RecyclerView.Adapter<ToDoAdapter.ToDoViewHolder>() { 42 private var todoList = emptyList<ToDo>() 43 private val layouts = arrayOf(R.layout.recyclerview_item, R.layout.recyclerview_separator) 44 45 class ToDoViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) { 46 val checkBox: CheckBox? 47 val textView: TextView? 48 init { 49 checkBox = itemView.findViewById(R.id.checkBox) 50 textView = itemView.findViewById(R.id.textView) 51 } 52 } 53 54 override fun getItemViewType(position: Int) = if(position == separateIndex()) 1 else 0 55 56 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = 57 ToDoViewHolder(LayoutInflater.from(parent.context).inflate(layouts[viewType], parent, false)) 58 59 override fun getItemCount() = todoList.size + if(separateIndex() >= 0) 1 else 0 60 61 override fun onBindViewHolder(holder: ToDoViewHolder, position: Int) { 62 val separateIndex = separateIndex() 63 if(position == separateIndex) return //セパレータに表示するデータは無い 64 65 val pos = position - if(position > separateIndex) 1 else 0 66 val todo = todoList[pos] 67 holder.checkBox?.isChecked = todo.complete 68 holder.textView?.text = todo.text 69 } 70 71 fun setData(todoList: List<ToDo>) { 72 this.todoList = todoList.sortedWith(compareBy<ToDo> { it.complete }.thenBy { it.id }) 73 notifyDataSetChanged() 74 } 75 76 private fun separateIndex() = todoList.indexOfFirst { it.complete } 77} 78 79class ToDoViewModel() : ViewModel() { 80 private var allData : MutableList<ToDo> = mutableListOf() 81 val readAllData = MutableLiveData<List<ToDo>>(allData) 82 83 fun add(todo: ToDo) { 84 allData.add(todo) 85 readAllData.value = allData //LiveData発火 86 } 87}

res/layout/activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <androidx.recyclerview.widget.RecyclerView 11 android:id="@+id/recyclerview" 12 android:layout_width="0dp" 13 android:layout_height="0dp" 14 app:layout_constraintBottom_toBottomOf="parent" 15 app:layout_constraintLeft_toLeftOf="parent" 16 app:layout_constraintRight_toRightOf="parent" 17 app:layout_constraintTop_toTopOf="parent" /> 18 19</androidx.constraintlayout.widget.ConstraintLayout>

res/layout/recyclerview_item.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 android:layout_width="match_parent" 6 android:layout_height="wrap_content"> 7 8 <CheckBox 9 android:id="@+id/checkBox" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 app:layout_constraintLeft_toLeftOf="parent" 13 app:layout_constraintTop_toTopOf="parent" /> 14 15 <TextView 16 android:id="@+id/textView" 17 android:layout_width="0dp" 18 android:layout_height="wrap_content" 19 app:layout_constraintLeft_toRightOf="@id/checkBox" 20 app:layout_constraintRight_toRightOf="parent" 21 app:layout_constraintBaseline_toBaselineOf="@id/checkBox" /> 22 23</androidx.constraintlayout.widget.ConstraintLayout>

res/layout/recyclerview_separator.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:app="http://schemas.android.com/apk/res-auto" 5 android:layout_width="match_parent" 6 android:layout_height="wrap_content"> 7 8 <TextView 9 android:layout_width="0dp" 10 android:layout_height="wrap_content" 11 android:text="Complete" 12 android:layout_marginTop="5dp" 13 android:layout_marginBottom="10dp" 14 android:paddingLeft="5dp" 15 android:background="@drawable/upperline" 16 app:layout_constraintLeft_toLeftOf="parent" 17 app:layout_constraintRight_toRightOf="parent" 18 app:layout_constraintTop_toTopOf="parent" /> 19 20</androidx.constraintlayout.widget.ConstraintLayout>

res/drawable/upperline.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 3 4 <item> 5 <shape android:shape="rectangle"> 6 <solid android:color="#FFFFFF"/> 7 <stroke android:width="1dp" android:color="#AAAAAA" /> 8 </shape> 9 </item> 10 11 <item android:top="1dp"> 12 <shape android:shape="rectangle"> 13 <solid android:color="#FFFFFF"/> 14 </shape> 15 </item> 16</layer-list>

投稿2021/12/05 19:15

編集2021/12/06 05:38
jimbe

総合スコア13209

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問