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

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

ただいまの
回答率

89.10%

onSaveInstanceでTextViewを保存する方法

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 66

Shibou

score 6

画面の縦横を変更して画面を再構築するときに
TextViewを保存したいのですが、どうすればできるのかわかりません。
putIntでIDを保存できればonRestoreInstanceでfindViewByIdを使って
Viewを取得できるのではないかとも思いましたが、

Smart cast to 'TextView' is impossible,because 'chooseTextView' is a mutable property that could have been changed by this time
となってしまいうまくいきませんでした。

解決策を教えていただければ幸いです。

package com.example.theplanning1

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.TextView
import com.example.theplanning.CalendarMaker
import kotlinx.android.synthetic.main.calendar.*

class MainActivity : AppCompatActivity() {
    //CalendarMaker
    lateinit var calendarMaker: CalendarMaker

    //TextViewのIDが入った配列(6行7列)
    private lateinit var dateViews: MutableList<MutableList<TextView>>

    //今日の年月
    var year = 0
    var month = 0

    //今日の日付
    var today = 0

    //選択されているTextView(これを保存したい)
    var chooseTextView: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //CalendarMakerの取得
        calendarMaker = CalendarMaker()
        //年月日を取得する
        year = calendarMaker.nowYear
        month = calendarMaker.nowMonth
        today = calendarMaker.nowDay

        //TableLayoutのTextViewを取得する
        dateViews = mutableListOf(
            mutableListOf(one_one, one_two, one_three, one_four, one_five, one_six, one_seven),
            mutableListOf(two_one, two_two, two_three, two_four, two_five, two_six, two_seven),
            mutableListOf(
                three_one,
                three_two,
                three_three,
                three_four,
                three_five,
                three_six,
                three_seven
            ),
            mutableListOf(
                four_one,
                four_two,
                four_three,
                four_four,
                four_five,
                four_six,
                four_seven
            ),
            mutableListOf(
                five_one,
                five_two,
                five_three,
                five_four,
                five_five,
                five_six,
                five_seven
            ),
            mutableListOf(six_one, six_two, six_three, six_four, six_five, six_six, six_seven)
        )
        //最初は今日の日付のカレンダーを表示する
        year_month.text = getString(R.string.year_month).format(year, month + 1)
        //日付TextViewに日付とClickListenerをセットする
        updateTextView()
    }

    //日付TextViewの更新
    private fun updateTextView() {
        //表示年月の変更
        year_month.text = getString(R.string.year_month).format(calendarMaker.displayYear, calendarMaker.displayMonth + 1)
        //表示月の日付が格納されたListを取得する
        val dateList = calendarMaker.getList()
        //dateListから何番目の文字列を取り出すか
        var dateCount = 0
        //日付TextViewにClickListenerを設定する
        for (row in dateViews) {
            for (date in row) {
                //背景をリセットする
                date.setBackgroundColor(Color.WHITE)

                date.text = dateList[dateCount]
                //日付が入らなかった場合
                if (date.text.toString() == "") {
                    date.isClickable = false
                    //6行目の日曜日が空欄だった場合
                    if (date == six_one) {
                        //6行目を不可視化
                        lastWeek.visibility = View.GONE
                        //ループ終了
                        break
                    } else {
                        //
                        lastWeek.visibility = View.VISIBLE
                    }
                }//日付入りの場合
                else {
                    //ClickListenerを登録する
                    date.setOnClickListener {
                        //日付の選択がされていた場合
                        if (chooseTextView != null) {
                            //選択されていたのが今日の日付の場合
                            if (todayOrElse(chooseTextView!!)) {
                                //今日の日付用の背景に戻す
                                chooseTextView!!.setBackgroundResource(R.drawable.today)
                            } else {
                                //今日以外の日付用の背景に戻す
                                chooseTextView!!.setBackgroundColor(Color.WHITE)
                            }
                        }
                        //選択した日付を記録する
                        chooseTextView = it as TextView

                        //今日の日付がクリックされた場合
                        if (todayOrElse(chooseTextView!!)) {
                            //背景を変更する
                            it.setBackgroundResource(R.drawable.today_and_choose_day)
                        } else {
                            //背景を変更する
                            it.setBackgroundResource(R.drawable.choose_day)
                        }
                        //RecyclerViewを作り直す

                    }//end ClickListener
                    //今日の日付の場合(背景を今日の日付用のものに変える)
                    if (todayOrElse(date)) date.setBackgroundResource(R.drawable.today)
                }
                //カウントを1追加
                dateCount++
            }
        }
    }
    //月を一つ前にする
    fun onPreviousMonth(view: View){
        //選択日をリセット
        chooseTextView = null
        //CalendarMakerを前の月に更新
        calendarMaker.previous()
        //TextViewの更新
        updateTextView()
    }
    //月を一つ進める
    fun onNextMonth(view: View){
        //選択日をリセット
        chooseTextView = null
        //CalendarMakerを次の月に更新
        calendarMaker.nextMonth()
        //TextViewの更新
        updateTextView()
    }
    //今日の日付のTextViewかどうか
    fun todayOrElse(date: TextView): Boolean {
        //今日の年月
        val chooseYearMonth = getString(R.string.year_month).format(year, month + 1)
        //表示されている年月日が選択されているTextViewの年月日と等しいかどうか
        if (date.text.toString() == today.toString() &&
            year_month.text.toString() == chooseYearMonth
        ) {
            return true
        }
        return false
    }
    //画面を破棄したときのデータ保存処理
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        //CalendarMakerを保存する
        outState.putParcelable("CalendarMaker",calendarMaker)
    }
    //画面を再構築したときのデータ取得処理
    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)

        savedInstanceState.run {
            //CalendarMakerを取得
            calendarMaker = getParcelable("CalendarMaker")!!
        }
        //TextViewの更新
        updateTextView()
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • hoshi-takanori

    2020/07/02 19:39

    TextView そのものは保存できません。TextView に表示されている内容を保存すればいいのでは。

    キャンセル

まだ回答がついていません

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

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる