невозможно восстановить строки таблицы при изменении ориентации в Android

#android #kotlin #android-tablelayout #android-orientation

#Android #kotlin #android-tablelayout #android-ориентация

Вопрос:

Я вызвал addRow() 3 раза при onCreate, поэтому у пользователей будет 3 строки для начала. Но они могут добавлять или удалять строки по своему усмотрению. но при повороте экрана отображается только 3 строки. Если я удалю эти 3 строки вызова функции, она не отобразит никаких строк при повороте. Мне удалось восстановить все данные пользовательского интерфейса, кроме строк таблицы. Если у вас есть 2 строки, и вы поворачиваете, то автоматически добавляется 3-я строка. если их больше 3, отображаются только первые три. Я тоже указал идентификаторы. Это мое первое (своего рода) оригинальное приложение, и оно полностью завершено, за исключением этой проблемы. ОШИБКА — Исключение IndexOutOfBoundsException: Индекс: 5, Размер: 3. В приведенном ниже коде он не аварийно завершает работу, он просто не отображает строки. В моем полном приложении он вылетает при повороте, но ошибка, похоже, связана с «editTextCell», как в этом случае. Ниже приведен код настолько маленький, насколько я мог сделать, не теряя контекста этого. Я был бы очень признателен за любую помощь. Я серьезно не хочу фиксировать это только в портретном режиме.

 class MainActivity : AppCompatActivity() {
private var idNextCell = 1000
private var idNextRow = 0
private var idPlayerName = 2000
private var counter = 0
private var rowCounter = 0
private var colTotal = 0.0
private var removeTableRow: ArrayList<View> = ArrayList()
private val editTextPlayerNames: ArrayList<EditText> = ArrayList()
private var editTextCell: ArrayList<ArrayList<EditText>> = ArrayList()
private var colTotalList: ArrayList<Double> = arrayListOf()
private val colAverageList: ArrayList<Double> = arrayListOf()
private var scoreTable: TableLayout? = null
private var resultTable: TableLayout? = null
private var rowResult: TableRow? = null
private var noOfPlayers = 0

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    noOfPlayers = 2
    addPlayerNames()

    scoreTable = findViewById(R.id.score_table)
    scoreTable?.isStretchAllColumns = true
    scoreTable?.isShrinkAllColumns = true

    resultTable = findViewById<TableLayout>(R.id.table_result)
    resultTable?.isShrinkAllColumns = true
    resultTable?.isStretchAllColumns = true

    rowResult = TableRow(this)
    
    addRow()
    addRow()
    addRow()

    buttonAddRow.setOnClickListener {
        addRow()
    }
    buttonAdd.setOnClickListener {
        if (rowCounter >= 1) {
            addAllColumns()
            displayResult()
        }
    }
    buttonDelRow.setOnClickListener {
        if (counter >= 1) {
            for (i in removeTableRow.asReversed()) {
                scoreTable?.removeView(i)
                removeTableRow.remove(i)
                counter--
                break
            }
            for (col in 0 until noOfPlayers) {
                for (row in 0 until rowCounter) {
                    if (row == counter) {
                        editTextCell[row][col].text = null
                    }
                }
            }
            rowCounter--
            addAllColumns()
            displayResult()
            if (rowCounter == 0) {
                for (i in 0 until noOfPlayers) {
                    rowResult!!.removeAllViews()
                    resultTable?.removeView(rowResult)
                }
            }
        }
    }
}

private fun addPlayerNames() {
    val playerNamesTable = findViewById<TableLayout>(R.id.table_player)
    playerNamesTable.isStretchAllColumns = true
    playerNamesTable.isStretchAllColumns = true

    val rowPlayerNames = TableRow(this)
    val emptyTextView = TextView(this)
    rowPlayerNames.addView(emptyTextView)

    for (col in 0 until noOfPlayers) {
        val playerName = EditText(this)
        playerName.id = idPlayerName
        idPlayerName  
        playerName.hint = "name"
        editTextPlayerNames.add(playerName)
        rowPlayerNames.addView(playerName)
    }
    playerNamesTable.addView(
        rowPlayerNames,
        TableLayout.LayoutParams.MATCH_PARENT,
        TableLayout.LayoutParams.WRAP_CONTENT
    )
}

private fun addRow() {
    for (row in 0 until 1) {
        editTextCell.add(rowCounter, ArrayList<EditText>())  // error appears at this line
        val nextRow = TableRow(this)
        nextRow.id = idNextRow
        idNextRow  
        removeTableRow.add(nextRow)
        val round = TextView(this)
        round.text = "R${  counter}"
        nextRow.addView(round)

        for (col in 0 until noOfPlayers) {
            val nextCell = EditText(this)
            nextCell.id = idNextCell
            idNextCell  
            nextCell.hint = "0"
            nextRow.addView(nextCell)
            editTextCell[rowCounter].add(nextCell)
        }
        scoreTable?.addView(
            nextRow,
            TableLayout.LayoutParams.WRAP_CONTENT,
            TableLayout.LayoutParams.WRAP_CONTENT
        )
        rowCounter  
    }
}

private fun addAllColumns() {
    colTotalList.clear()
    colAverageList.clear()
    // to add all column values
    for (col in 0 until noOfPlayers) {
        for (row in 0 until rowCounter) {
            if (editTextCell[row][col].text.isEmpty()) {
                colTotal  = 0.0
            } else {
                colTotal  = editTextCell[row][col].text.toString().toDouble()
            }
        }
        colTotalList.add(colTotal)
        colTotal = 0.0
    }
}

private fun displayResult() {
    rowResult!!.removeAllViews()
    resultTable?.removeView(rowResult)
    val result = TextView(this)
    result.text = "Total"
    rowResult?.addView(result)

    //to display  column total
    for (value in 0 until colTotalList.size) {
        val colTotalTV = TextView(this)
        if (colTotalList.sum() != 0.0) {
            colTotalTV.text = colTotalList[value].toLong().toString()
        }
        colTotalTV.gravity = Gravity.CENTER
        rowResult?.addView(colTotalTV)
    }
    if (rowCounter >= 1) {
        resultTable?.addView(
            rowResult,
            TableLayout.LayoutParams.MATCH_PARENT,
            TableLayout.LayoutParams.WRAP_CONTENT
        )
    }
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    rowCounter = savedInstanceState.getInt("rowCounter")
    val ctListSize = savedInstanceState.getInt("ctListSize")
    val avgListSize = savedInstanceState.getInt("avgListSize")
    val ctList = savedInstanceState.getDoubleArray("coltotalList")
    val avgList = savedInstanceState.getDoubleArray("averageList")

    if (ctList != null amp;amp; avgList != null) {
        for (col in 0 until ctListSize) {
            colTotalList.add(col, ctList[col])
        }
        for (col in 0 until avgListSize) {
            colAverageList.add(col, avgList[col])
        }
    }
    if (rowCounter >= 1) {
        displayResult()
    }
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putInt("ctListSize", colTotalList.size)
    outState.putInt("avgListSize", colAverageList.size)
    outState.putInt("rowCounter", rowCounter)
    outState.putDoubleArray("coltotalList", colTotalList.toDoubleArray())
    outState.putDoubleArray("averageList", colAverageList.toDoubleArray())
}
 

}

Ответ №1:

По умолчанию при повороте экрана ваша активность прекращается и перезапускается. Чтобы убедиться, что данные не потеряны, вам необходимо правильно сохранить и восстановить свои данные, используя методы жизненного цикла. См. http://developer.android.com/reference/android/app/Activity.html#SavingPersistentState

Возможно, вы захотите использовать SharedPreferences, который сохраняет количество строк всякий раз, когда пользователь добавляет или удаляет их, и извлекает их в onCreate() или onConfigurationChanged() метод.

Комментарии:

1. Прочтите и это, в нем описаны некоторые параметры: developer.android.com/topic/libraries/architecture/… Возможно, сейчас самое время узнать о ViewModel s!