Home > Back-end >  Kotlin - RecyclerView Adding items to the list and displaying them
Kotlin - RecyclerView Adding items to the list and displaying them

Time:08-18

I am new to the kotlin language and i try to write an "finance" app in which you can add some of your spendings and sum them etc..

I wrote 2 activities (first acitivty - MainActivity where you can see your spendings and current balance) and the second one where you can add new spending (category, type and amount)... and it should work fine, but somehow it does not. When im adding the new spending (it shows in the mainActivity) but when i try to add another one it just changes the first one instead of showing both. If i can a little help with it.. i'd love that. I know there are a lot of things that's just not well written, but i'm still newbie.

    MainActivity.kt
package com.example.financestation

import android.content.ClipData
import android.content.Intent
import android.os.Bundle
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView


class MainActivity : AppCompatActivity() {


    private fun SettingsActivity() {

    }


    private fun NextActivity() {
        val intent = Intent(this, AddingSpendings::class.java)
        startActivity(intent)
    }


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

        val add_spending_button = findViewById<ImageButton>(R.id.add_button)
        val current_balance = findViewById<TextView>(R.id.current_balance_number)
        val settingsbutton = findViewById<ImageButton>(R.id.settings_button)
        val recyclerview = findViewById<RecyclerView>(R.id.recyclerview)
        val message = intent.getStringExtra("COST")
        val cat = intent.getStringExtra("CATEGORY")
        val type = intent.getStringExtra("TYPE")


        // this creates a vertical layout Manager
        recyclerview.layoutManager = LinearLayoutManager(this)

        // ArrayList of class ItemsViewModel
        val data = ArrayList<ItemsViewModel>()

        // This will pass the ArrayList to our Adapter
        val adapter = CustomAdapter(data)
        // Setting the Adapter with the recyclerview
        recyclerview.adapter = adapter

        if (message != null && cat != null && type == "Income") {
            current_balance.text ="$$message"
            data.add(ItemsViewModel(R.drawable.add_icon, "$$message", "$cat"))
        }

        else if (message != null && cat != null && type == "Outcome") {
            current_balance.text = "$$message"
            data.add(ItemsViewModel(R.drawable.substract_icon, "$$message", "$cat"))
        }

        add_spending_button.setOnClickListener {
            NextActivity()
        }

        settingsbutton.setOnClickListener {
            SettingsActivity()
        }
    }
}

and the CustomAdapter.kt

 package com.example.financestation
    
    import android.content.ClipData
    import androidx.appcompat.app.AppCompatActivity
    
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import android.widget.ImageView
    import android.widget.TextView
    import androidx.recyclerview.widget.RecyclerView
    import org.w3c.dom.Text
    
    class CustomAdapter(private val mList: List<ItemsViewModel>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
    
        // create new views
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            // inflates the card_view_design view
            // that is used to hold list item
            val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.card_view_design, parent, false)
            return ViewHolder(view)
        }
    
        // binds the list items to a view
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    
            val ItemsViewModel = mList[position]
    
            // sets the image to the imageview from our itemHolder class
            holder.imageView.setImageResource(ItemsViewModel.image)
    
            // sets the text to the textview from our itemHolder class
            holder.textView.text = ItemsViewModel.cost.toString()
    
            // sets the category text to the textview from our itemholder class
            holder.textView2.text = ItemsViewModel.category
        }
    
        // return the number of the items in the list
        override fun getItemCount(): Int {
            return mList.size
    
        }
    
        // Holds the views for adding it to image and text
        class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
            val imageView: ImageView = itemView.findViewById(R.id.imageview)
            val textView: TextView = itemView.findViewById(R.id.textView)
            val textView2: TextView = itemView.findViewById(R.id.categories)
        }

And the AddingSpending.kt (Second activity)

package com.example.financestation

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.get
import kotlin.math.cos


class AddingSpendings : AppCompatActivity() {

    private fun mainactivity() {
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
    }

    private lateinit var cost: EditText

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

        val intent = Intent(this, MainActivity::class.java)
        val home_button = findViewById<ImageButton>(R.id.home_button)
        val itemaddbutton = findViewById<Button>(R.id.add_item_button)
        val categoryspinner = findViewById<Spinner>(R.id.categoryspinner)
        val typespinner = findViewById<Spinner>(R.id.typespinner)
        val categories = resources.getStringArray(R.array.Category)
        val types = resources.getStringArray(R.array.Income_Outcome)
        cost = findViewById(R.id.cost)

        fun gettingCategory() {
            categoryspinner.onItemSelectedListener = object :
                AdapterView.OnItemSelectedListener {
                override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
                    var cat : String = categories[p2]
                    intent.putExtra("CATEGORY", cat)
                }

                override fun onNothingSelected(p0: AdapterView<*>?) {
                    Toast.makeText(this@AddingSpendings, "Nie wybrano żadnej kategorii", Toast.LENGTH_SHORT)
                }
            }
        }

        fun gettingtype() {
            typespinner.onItemSelectedListener = object :
                AdapterView.OnItemSelectedListener {
                override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {

                    var type : String = types[p2]
                 intent.putExtra("TYPE", type)
                }

                override fun onNothingSelected(p0: AdapterView<*>?) {
                    Toast.makeText(this@AddingSpendings, "Nie wybrano żadnej kategorii", Toast.LENGTH_SHORT)
                }
            }
        }

        // setting the spinners with lists
        if (categoryspinner != null) {
            val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, categories)
            categoryspinner.adapter = adapter
        }

        gettingCategory() // gets category from the spinner


            if (typespinner != null) {
                val adapter2 = ArrayAdapter(this, android.R.layout.simple_spinner_item, types)
                typespinner.adapter = adapter2
            }

        gettingtype() // gets type from spinner

            itemaddbutton.setOnClickListener {
                val message = cost.text.toString()
                intent.putExtra("COST", message)
                startActivity(intent)
            }


            home_button.setOnClickListener {
                mainactivity()
            }


        }


    }

CodePudding user response:

When you add data to adapter, make sure notify it after that. Try to adding this line

adapter.notifyItemInserted(data.size - 1)

let me know if it work

Edit

I see some of problems in your code:

You can't get new intent like that if your activity was in backstack, so i guess you've set your main activity to noHistory="true" in manifest?

And if you do like that your main activity will recreate every time you start it again. So the old data will be lost. Then just only one new data is display in adapter(which you say it is replaced).

To solve your problem, you need to remove the noHistory somewhere in your code. And then call override funtion onNewIntent(Intent intent) to get new data from intent when your main activity is in backstack.

Hope this will help to solve your problem.

CodePudding user response:

I was looking for that "noHistory" in my code, but i really didnt find it. below is my AndroidManifest code

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.financestation">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.FinanceStation"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".AddingSpendings">

        </activity>
    </application>
</manifest>
  • Related