Android 多行求和:请求代码缩短
Android Multi-row summation: Request for code shortening
我有一个有 15 行的 table。每行有三列和一个总计列。我想获得每行的总数、总计和总体平均值。
用户可能不会为所有行输入数据,并且用户可能会跳过一行。
所以代码检查用户是否在每行的三个字段之一中输入了数据。
- 如果该行为空,则忽略它。
- 如果某些字段已填满,请告诉用户填写该行的其余部分。
- 如果一行中的所有字段都已填满,则对其所有字段求和并增加分隔符。
为简洁起见,我只粘贴了第 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()
}
table:
这是我能想到的最好的。如果没有其他建议,我就这样吧。
提前致谢!
**编辑:感谢** https://whosebug.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)
}
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 上显示错误。我们还没有在这里显示吐司错误。
calculateTotalResult()
遍历所有行并获得总结果。在此步骤后,我们仅显示一个 Toast 错误(如果需要)。
代码为伪代码,未经测试
我有一个有 15 行的 table。每行有三列和一个总计列。我想获得每行的总数、总计和总体平均值。
用户可能不会为所有行输入数据,并且用户可能会跳过一行。
所以代码检查用户是否在每行的三个字段之一中输入了数据。
- 如果该行为空,则忽略它。
- 如果某些字段已填满,请告诉用户填写该行的其余部分。
- 如果一行中的所有字段都已填满,则对其所有字段求和并增加分隔符。
为简洁起见,我只粘贴了第 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()
}
table:
这是我能想到的最好的。如果没有其他建议,我就这样吧。
提前致谢!
**编辑:感谢** https://whosebug.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)
}
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 上显示错误。我们还没有在这里显示吐司错误。
calculateTotalResult()
遍历所有行并获得总结果。在此步骤后,我们仅显示一个 Toast 错误(如果需要)。
代码为伪代码,未经测试