【问题标题】:Android Multi-row summation: Request for code shorteningAndroid 多行求和:请求代码缩短
【发布时间】:2020-07-09 18:23:55
【问题描述】:

我有一个十五行的表。每行有三列和一列。我想获得每行的总数、总计和总体平均值。

用户可能不会为所有行输入数据,用户可能会跳过一行。

因此代码会检查用户是否在每一行的三个字段之一中输入了数据。

  1. 如果该行是空白的,请忽略它。
  2. 如果某些字段已填写,请告诉用户填写该行的其余部分。
  3. 如果一行中的所有字段都已填满,则将其所有字段相加并增加分隔符。

为简洁起见,我只粘贴了第 1 行和第 2 行的代码,但它显示了我想要实现的目标:

代码:

var a1 = 0
var a2 = 0
var total = 0
var divider = 0


// Row 1
if (b1p1.text.isNotEmpty() or b2p1.text.isNotEmpty() or b3p1.text.isNotEmpty()) {
    var y = 0
    listOf(b1p1, b2p1, b3p1).forEach {
        if (it.text.isEmpty()) {
            it.error = "Fill up empty fields!"
            y = 1
        }
    }

    if (y == 0) {
        divider++
        listOf(b1p1, b2p1, b3p1).forEach {
            a1 += it.text.toString().toInt()
        }
        total1.text = a1.toString()
        total += a1
        e2 = 1
    } else {
        Toast.makeText(activity, "Error", Toast.LENGTH_SHORT).show()
    }
}

// Row 2
if (b1p2.text.isNotEmpty() or b2p2.text.isNotEmpty() or b3p2.text.isNotEmpty()) {
    var y = 0
    listOf(b1p2, b2p2, b3p2).forEach {
        if (it.text.isEmpty()) {
            it.error = "Fill up empty fields!"
            y = 1
        }
    }

    if (y == 0) {
        divider++
        listOf(b1p2, b2p2, b3p2).forEach {
            a2 += it.text.toString().toInt()
        }
        total2.text = a2.toString()
        total += a2
    } else {

        Toast.makeText(activity, "Error", Toast.LENGTH_SHORT).show()
    }
}

if (e2 == 1) {

    grandTotalTextView.text = total.toString()

    average = total.toDouble()/divider

    val decimalFormatter = DecimalFormat("#,###.##")

    averageTextView.text = decimalFormatter.format(average).toString()

    cyeSingleton.anct3b = decimalFormatter.format(average).toString()

} else {

    Toast.makeText(activity, "Error 2", Toast.LENGTH_SHORT).show()
}

桌子:

这是我能想到的最好的。如果没有其他建议,我会接受的。

提前致谢!

**编辑:感谢**https://stackoverflow.com/users/3736955/jemshit-iskenderov

data class TotalResult(val divider:Int, val allTotal:Int, val showError:Boolean)

private fun calculateTotalResult(allTextViews:List<List<TextView>>, totalTextViews:List<TextView>): TotalResult {
    var divider = 0
    var allTotal = 0
    var showError=false

    allTextViews.forEachIndexed{index, rowTextViews->
        val rowResult = calculateRowResult(rowTextViews as List<EditText>, totalTextViews[index])
        if(!rowResult.ignoreRow){
            if(rowResult.allFieldsFilled){
                divider+=1
                allTotal+=rowResult.rowTotal
            }else{
                showError = true
            }
        }
    }

    Toast.makeText(
        activity,
        "$divider, $allTotal, $showError", Toast.LENGTH_SHORT)
        .show()

    return TotalResult(divider, allTotal, showError)

}

data class RowResult(val ignoreRow:Boolean, val allFieldsFilled:Boolean, val rowTotal:Int)

private fun calculateRowResult(rowTextViews:List<EditText>, totalTextView:TextView): RowResult {
    val ignore = rowTextViews.filter{it.text.isBlank()}.count() == rowTextViews.size
    if(ignore)
        return RowResult(true, false, 0)

    var emptyFieldCount = 0
    var total = 0
    rowTextViews.forEach {textView ->
        if (textView.text.isEmpty()) {
            textView.error = "Fill up empty fields!"
            emptyFieldCount +=1
        }else{
            val fieldValue:Int? = textView.text.toString().toIntOrNull() // or toIntOrElse{0}
            if(fieldValue!=null) total+=fieldValue
        }
    }

    if(emptyFieldCount==0)
        totalTextView.text = total.toString()

    return RowResult(false, emptyFieldCount==0, total)
}

【问题讨论】:

    标签: android android-studio kotlin optimization nested-if


    【解决方案1】:
    fun main(){
      val totalResult = calculateTotalResult(
        allTextViews = listOf(
            listOf(t11,t12,t13),
            listOf(t21,t22,t23)
        ),
        totalTextViews = listOf(totalView1, totalView2)
      )
    
      // single Toast error
      if(totalResult.showError){
          // showToast(error)
      }
    
      // use totalResult.divider, totalResult.allTotal
    }
    
    data class TotalResult(val divider:Int, val allTotal:Int, val showError:Boolean)
    
    fun calculateTotalResult(allTextViews:List<List<TextView>>, totalTextViews:List<TextView>){
      var divider = 0
      var allTotal = 0
      var showError=false
    
      allTextViews.forEachIndexed{index, rowTextViews->
          val rowResult = calculateRowResult(rowTextViews, totalTextViews[index])
          if(!rowResult.ignore){
            if(rowResult.allFieldsFilled){
                divider+=1
                allTotal+=rowResult.rowTotal
            }else{
                showError = true
            }
          }
      }
    
      return TotalResult(divider, allTotal, showError)
    }
    
    data class RowResult(val ignoreRow:Boolean, val allFieldsFilled:Boolean, val rowTotal:Int)
    
    fun calculateRowResult(rowTextViews:List<TextView>, totalTextView:TextView): RowResult {
        val ignore = rowTextViews.filter{it.isBlank()}.count() == rowTextViews.size
        if(ignore)
          return RowResult(true, false, 0)
    
        var emptyFieldCount = 0
        var total = 0
        rowTextViews.forEach {textView ->
            if (textView.text.isEmpty()) {
                textView.error = "Fill up empty fields!"
                emptyFieldCount +=1
            }else{
                val fieldValue:Int? = textView.text.toString().toIntOrNull() // or toIntOrElse{0}
                if(fieldValue!=null) total+=fieldValue
            }
        }
    
        if(emptyFieldCount==0)
          totalTextView.text = total.toString()
    
        return RowResult(false, emptyFieldCount==0, total)
    }
    

    提取了calculateTotalResult()calculateRowResult(),因此多行和多列不需要重复相同的代码。

    calculateRowResult() 处理 TextView 的单行。我不得不迭代rowTextViews 两次,一次计算忽略,如果不忽略,另一次在 TextView 上显示错误。我们还没有在此处显示 Toast 错误。

    calculateTotalResult() 遍历所有行并获得总结果。在此步骤之后,我们仅显示一个 Toast 错误(如果需要)。

    代码是伪代码,未经测试。

    【讨论】:

    • 哇,谢谢伙计!抱歉,花了很长时间才回复您(当时正在煮脆皮帕塔,脸上溅了一些热油)。通过一些调整,我设法将您的代码应用到我的项目中。如果可能的话,你能不能让它在 Kotlin 中成为类,这样它就可以被其他片段重用?你帮了大忙。谢谢!
    • @KellinStrook 只是放入 SomeCalculator.kt 文件,没有任何类声明并在任何地方使用函数
    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2013-02-28
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多