Android: добавьте новый элемент в список и отобразите его с помощью адаптера RecyclerView с помощью Kotlin

У меня есть фрагмент, который имеет RecyclerView. Когда пользователь нажимает кнопку (ДОБАВИТЬ НОВЫЙ ПУНКТ) во фрагмент, приложение переносит пользователя (через намерение) в форму, чтобы заполнить некоторые данные.

Когда я нажимаю (ДОБАВИТЬ ПУНКТ), он должен добавить данные в список массивов и завершить этот экран. После возврата к фрагменту эти данные должны быть добавлены в RecyclerView с помощью адаптера.

Это мой код:

Вот фрагмент:

private val REQUEST_CODE = 2

internal lateinit var adapter: ShipmentItemAdapter

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {

    return inflater!!.inflate(R.layout.fragment_step_three_shipment, container, false)
}

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    btnAddNewShipmentStep3.setOnClickListener {
        val intent = Intent(context, AddItemActivity::class.java)
        startActivityForResult(intent, REQUEST_CODE)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data);

    val items = ArrayList<ItemsItem>()

    if (requestCode == REQUEST_CODE) {

        adapter = ShipmentItemAdapter(context, items)

        if (resultCode == Activity.RESULT_OK) {
            itemsShipments.visibility = View.VISIBLE
            itemsShipments.layoutManager = LinearLayoutManager(context)
            itemsShipments.setHasFixedSize(true)
            itemsShipments.adapter = adapter

        } else if (resultCode == Activity.RESULT_CANCELED) {
            itemsShipments.visibility = View.GONE
        }
    }
}

А вот и активность:

class AddItemActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_add_item_form)

    linPackageAddShipment.setOnClickListener {
        edtPackageAddShipment.requestFocus()
    }

    linPiecesAddShipment.setOnClickListener {
        edtPiecesAddShipment.requestFocus()
    }

    linWeightAddShipment.setOnClickListener {
        edtWeightAddShipment.requestFocus()
    }

    linDescriptionAddShipment.setOnClickListener {
        edtDescriptionAddShipment.requestFocus()
    }


    btnAddItemAddShipment.setOnClickListener {
        val errors = collectData()

        collectData()

        if (errors.isEmpty()) {

            val intent = Intent()
            setResult(Activity.RESULT_OK, intent)
            finish()

        } else {
            val errorBody = errors.map { getString(it) }.joinToString("\n") { it }
            MaterialDialog.Builder(this)
                    .title("Oops")
                    .content(errorBody)
                    .positiveText(R.string.ok)
                    .positiveColor(ContextCompat.getColor(this, R.color.colorPrimary))
                    .onAny({ dialog, _ -> dialog.dismiss() })
                    .show()
        }
    }
  }

  private fun collectData(): ArrayList<Int> {
    val errors = ArrayList<Int>()
    val item = ItemsItem()

    if (edtPackageAddShipment.text.toString().isEmpty()) {
        errors.add(R.string.packages_must_not_be_empty)

    } else {
        item.numberOfPackages = edtPackageAddShipment.text.toString().toInt()
    }

    if (edtPiecesAddShipment.text.toString().isEmpty()) {
        errors.add(R.string.pieces_must_not_be_empty)

    } else {
        item.numberOfPieces = edtPiecesAddShipment.text.toString()
    }

    if (edtWeightAddShipment.text.toString().isEmpty()) {
        errors.add(R.string.weight_must_not_be_empty)

    } else {
        item.weightUnit = edtWeightAddShipment.text.toString().toInt()
    }

    if (edtHeightAddShipment.text.toString().isEmpty()) {
        errors.add(R.string.height_must_not_be_empty)

    } else {
        item.height = edtHeightAddShipment.text.toString()
    }

    if (edtWidthAddShipment.text.toString().isEmpty()) {
        errors.add(R.string.width_must_not_be_empty)

    } else {
        item.width = edtWidthAddShipment.text.toString()
    }
    if (edtLengthAddShipment.text.toString().isEmpty()) {
        errors.add(R.string.length_must_not_be_empty)

    } else {
        item.length = edtLengthAddShipment.text.toString()
    }

    if (edtDescriptionAddShipment.text.toString().isEmpty()) {
        errors.add(R.string.description_must_not_be_empty)

    } else {
        item.description = edtDescriptionAddShipment.text.toString()
    }

    CreateNewShipmentActivity.mainShipment.shipmentObj.items?.add(item)

    return errors
  }

  override fun onBackPressed() {
    setResult(Activity.RESULT_CANCELED)
    super.onBackPressed()
  }
}

Вот адаптер:

class ShipmentItemAdapter internal constructor(private val context: Context, private val items: List<ItemsItem>) : RecyclerView.Adapter<ShipmentItemAdapter.MyViewHolder>() {

  private val inflater: LayoutInflater = LayoutInflater.from(context)


  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val view = inflater.inflate(R.layout.item_shipment_package, parent, false)

    return MyViewHolder(view).listen { pos, type ->
        val item = items[pos]
        val intent = Intent(context, AddItemActivity::class.java)
        startActivity(context, intent, null)
    }
  }


  override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    holder.namePackageShipmentPackage.text = items[position].description
    holder.quantityPackageShipmentPackage.text = items[position].description
    holder.dimensionPackageHeightShipmentPackage.text = items[position].description
    holder.dimensionPackageWidthShipmentPackage.text = items[position].description
    holder.dimensionPackageLengthShipmentPackage.text = items[position].description

  }

  override fun getItemCount(): Int {
    return items.size
  }

  inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    var namePackageShipmentPackage: AppCompatTextView = itemView.findViewById(R.id.namePackageShipmentPackage)
    var quantityPackageShipmentPackage: AppCompatTextView = itemView.findViewById(R.id.quantityPackageShipmentPackage)
    var dimensionPackageHeightShipmentPackage: AppCompatTextView = itemView.findViewById(R.id.dimensionPackageHeightShipmentPackage)
    var dimensionPackageWidthShipmentPackage: AppCompatTextView = itemView.findViewById(R.id.dimensionPackageWidthShipmentPackage)
    var dimensionPackageLengthShipmentPackage: AppCompatTextView = itemView.findViewById(R.id.dimensionPackageLengthShipmentPackage)


  }

  private fun <T : RecyclerView.ViewHolder> T.listen(event: (position: Int, type: Int) -> Unit): T {
    itemView.setOnClickListener {
        event.invoke(adapterPosition, itemViewType)
    }
    return this
  }

Это объектная модель:

class ShipmentObj {
    var items: ArrayList<ItemsItem?>? = null
}


data class ItemsItem(
    var numberOfPieces: String? = null,
    var length: String? = null,
    var description: String? = null,
    var numberOfPackages: Int? = null,
    var number: Int? = null,
    var width: String? = null,
    var height: String? = null,
    var weightUnit: Int? = null
)

Когда я пытаюсь добавить новый элемент, во фрагменте ничего не отображается! Я не знаю, где ошибка?

Благодарю.

1 ответ

Сначала вам нужно добавить в свой адаптер одну функцию для добавления новых элементов в массив, в вашем случае это "items: List":

Первый шаг:

  • В вашем адаптере ShipmentItemAdapter добавьте следующую забаву

fun addNewItem(itemsNew: List<ItemsItem>){
      items.clear() // ->> optional if you need have clear of object 
      items.addAll(itemsNew)       
      notifyDataSetChanged()
    }

затем в вашем фрагменте в onActivityResult, когда вы получаете Activity.RESULT_OK, вы можете добавить новый элемент

adapter.addNewItem(itemsNew)

В onActivityResult вы можете увидеть ошибку в вашем коде. Вы делаете что-то вроде этого

val items = ArrayList<ItemsItem>()
adapter = ShipmentItemAdapter(context, items)

Вы назначаете на адаптер пустой список предметов. И если я не ошибаюсь, вы также не передадите товар, который хотите отправить.

 if (errors.isEmpty()) {
        val intent = Intent()
        setResult(Activity.RESULT_OK, intent)
        finish()
 }

Вы заканчиваете упражнение, не пропустив ни одного элемента в результате. Предыдущее действие ничего не получает. Я не могу выполнить ваш код, потому что у меня нет всех элементов для его выполнения.

Другие вопросы по тегам