Passing values from one fragment to another - android-fragments

I'm working in Kotlin and using retrofit. I have a recycler view, which consists of cards. Each card has a typeName and an image associated to it which for now I have added statically using dataclass. Now, I need to pass the typeName only from the CategoryFragment to the LocationFragment once the user clicks on a particular card. And at the LocationFragment I want to check the latitude, longitude and typeName from the database if it already exists.
Here's my code for the dataclass of Category:
data class Category_dataclass ( val category_image : Int , val typeName: String)
Here's my code for the CategoryFragment:
package com.example.atry.MakeComplaint
import android.content.Context
import android.net.Uri
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.atry.History.Complaints
import com.example.atry.History.MyComplainRecyclerViewAdapter
import com.example.atry.R
import kotlinx.android.synthetic.main.existing_complaint_popup.*
class CategoryFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val v = inflater.inflate(R.layout.fragment_category, container, false)
val recyclerView = v.findViewById(R.id.category_list) as RecyclerView
recyclerView.apply {
layoutManager = GridLayoutManager(context!!, 2)
}
//creating an arraylist to store category using the data class user
val category = ArrayList<Category_dataclass>()
//adding some dummy data to the list of categories
category.add(Category_dataclass((R.drawable.trash) , "Water"))
category.add(Category_dataclass((R.drawable.fire) , "Sewerage"))
category.add(Category_dataclass((R.drawable.dustbin) , "load"))
//creating our adapter
val adapter = CategoryRecyclerViewAdapter(category)
//now adding the adapter to recyclerview
recyclerView.adapter = adapter
// Inflate the layout for this fragment
return v
}
}
Here's the CategoryRecyclerViewAdapter:
package com.example.atry.MakeComplaint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.example.atry.History.ComplaintDetailsFragment
import com.example.atry.History.Complaints
import com.example.atry.MakeComplaint.Category_dataclass
import com.example.atry.MakeComplaint.CategoryRecyclerViewAdapter
import com.example.atry.R
import java.util.*
import kotlin.collections.ArrayList
class CategoryRecyclerViewAdapter(val categoryList: ArrayList<Category_dataclass>) : RecyclerView.Adapter<CategoryRecyclerViewAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryRecyclerViewAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.fragment_category_single, parent, false)
return ViewHolder(v)
}
//this method is binding the data on the list
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(categoryList[position])
holder.mView.setOnClickListener{view->
val lFragment = LocationFragment()
val oldFragment = CategoryFragment()
val manager = (holder.mView.context as AppCompatActivity).supportFragmentManager
val transaction = manager.beginTransaction()
transaction.replace(
R.id.first_screen_of_makecomplaint,
lFragment
) // give your fragment container id in first parameter
transaction.show(lFragment)
transaction.hide(oldFragment)
transaction.isAddToBackStackAllowed
transaction.addToBackStack(oldFragment.fragmentManager.toString()) // if written, this transaction will be added to backstack
transaction.commit()
}
}
//this method is giving the size of the list
override fun getItemCount(): Int {
return categoryList.size
}
inner class ViewHolder(val mView : View) : RecyclerView.ViewHolder(mView) {
fun bindItems(cat:Category_dataclass) {
val imageViewName = mView.findViewById(R.id.category_image) as ImageView
val textViewtext = mView.findViewById(R.id.category_text) as TextView
imageViewName.setImageResource(cat.category_image)
textViewtext.text = cat.typeName
}
}
}
And this is my retrofit:
//to check existing complaint
#GET("api/existingComplain")
#FormUrlEncoded
fun checkExistingComplain(#Query("typeName") typeName:String,
#Query("longitude") longitude:String,
#Query("latitude") latitude:String):Observable<Observables.checkExistingResult>
I've created and object where i stored the dataclass which will return the following:
data class checkExistingResult(val description:String , val Complain:String)
if the typeName and location already exists in the database I want the description and Complain to be displayed on a material styled dialog.

You can try this:
1st Step:-
val dashboard = "Dashboard"
take variable like this you can take it's name as your fragment name so page name you can check like this MainActivity().dashboard
Now, 2nd Step:-
create one class and write function like this in that class
fun openPage(
activity: Activity,
pagename: String?, model: PaymentDetails
) {
when (pagename) {
MainActivity().dashboard -> {
val mfragment = DashboardFragment()
(activity as MainActivity).fragmentManager.beginTransaction()
.replace(R.id.nav_host, mfragment).commit()
val a = Bundle()
a.putSerializable("model", model)
mfragment.arguments = a
}
}
}
take key value pair as I take my whole model and key is model in my code you can write any thing.
3rd Step:-
Make your model Serializable
4th Step:- When you are adding your values into model add details and add your model for method in which you want to use these values like following
val payment = PaymentDetails(
type,
price,
name,
id,
)
paymentData!!.add(payment)
CustomMethods().openPagePaymentDetails(
activity!!,
MainActivity().sessionPaymentFragment, payment
)
5th Step:-
Declare and initialise your object with type of your model like following:
//Declare
private var model: PaymentDetails? = null
//initialise
model = arguments!!.getSerializable("model") as PaymentDetails?
And now finally you can access value of previous fragment into your next fragment like this,
var type: String
type = model!!.type
Note:- please do no forgot to make your model class Serializable
Hope so it will help you.

Related

I am trying to edit a thought in my thoughts app. I am not able to update it

package com.example.demo
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.firestore.FirebaseFirestore
import kotlinx.android.synthetic.main.activity_update_thought.*
class UpdateThoughtActivity : AppCompatActivity() {
private lateinit var thoughtDocumentId: String
lateinit var commentDocId: String
lateinit var thoughtTxt: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_update_thought)
thoughtDocumentId = intent.getStringExtra(THOUGHT_DOC_ID_EXTRA)!!
commentDocId = intent.getStringExtra(COMMENT_USER_ID_EXTRA)!!
thoughtTxt = intent.getStringExtra(COMMENT_TXT_EXTRA)!!
updateThoughtTxt.setText(thoughtTxt)
}
fun updateThoughtClicked(view: View) {
FirebaseFirestore.getInstance().collection(THOUGHTS_REF).document(thoughtDocumentId)
.update(THOUGHT_TXT, updateThoughtTxt.text.toString())
.addOnSuccessListener {
hideKeyboard()
finish()
}
.addOnFailureListener { exception ->
Log.e("Exception", "Could not update thought: ${exception.localizedMessage}")
}
}
private fun hideKeyboard() {
val inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (inputManager.isAcceptingText) {
inputManager.hideSoftInputFromWindow(currentFocus!!.windowToken,0)
}
}
}
Here I am trying to update the thought. I am not able to update it.When I click on update button during runtime. I see this error.
E Could not update thought: NOT_FOUND: No document to update: projects/fir-ee876/databases/(default)/documents/thoughts/null
I did for comments activity the same thing. It works fine. I am getting problem only for this.
Can you please help me with this?
I am trying to edit the thought and when I click on edit option it navigates to a new activity. In the new activity I want to update the thought and click on update button.When I click on that button the thought must be updated and must be displayed. When I tried this I am getting this error.
E Could not update thought: NOT_FOUND: No document to update: projects/fir-ee876/databases/(default)/documents/thoughts/null

Kotlin ChatApp doesnt show messages

I simply followed this video: https://www.youtube.com/watch?v=8Pv96bvBJL4&ab_channel=GeeksforGeeks
Untill the end it was working fine. At the end, chat application started to crash when you try to text someone. I simply added push() method.
Now it stopped crashing but I am not able to see the messages. Firebase`s database is perfectly fine but I couldnt make it seen in the app. Sorry for the inexperience. I am new in Kotlin and this is the first time I am a asking a question. Thanks for all of the support.
Here is the code of Chat Activity (In my opinion messageList never adds a thing.. So messages arent showed in the app. But added to database perfectly):
package com.biointel.biointelchatapplication
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.EditText
import android.widget.ImageView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import com.google.firebase.ktx.Firebase
class ChatActivity : AppCompatActivity() {
private lateinit var chatRecyclerView: RecyclerView
private lateinit var messageBox: EditText
private lateinit var sendButton: ImageView
private lateinit var messageAdapter: MessageAdapter
private lateinit var messageList: ArrayList<Message>
private lateinit var mDbRef: DatabaseReference
var receiverRoom: String? = null
var senderRoom: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
val name = intent.getStringExtra("name")
val receiverUid = intent.getStringExtra("uid")
val senderUid = FirebaseAuth.getInstance().currentUser?.uid
mDbRef = FirebaseDatabase.getInstance().getReference()
senderRoom = receiverUid + senderUid
receiverRoom = senderUid + receiverUid
supportActionBar?.title = name
chatRecyclerView = findViewById(R.id.chatRecyclerView)
messageBox = findViewById(R.id.messageBox)
sendButton = findViewById(R.id.sentButton)
messageList = ArrayList()
messageAdapter = MessageAdapter(this,messageList)
chatRecyclerView.layoutManager = LinearLayoutManager(this)
chatRecyclerView.adapter = messageAdapter
// Logic for adding to recyclerView
mDbRef.child("chats").child(senderRoom!!).child("messages").push()
.addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
//messageList.clear()
for(postSnapshot in snapshot.children){
val message = postSnapshot.getValue(Message::class.java)
messageList.add(message!!)
}
messageAdapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
}
})
sendButton.setOnClickListener{
// adding the message to database
val message = messageBox.text.toString()
val messageObject = Message(message, senderUid)
mDbRef.child("chats").child(senderRoom!!).child("messages")
.setValue(messageObject).addOnSuccessListener {
mDbRef.child("chats").child(receiverRoom!!).child("messages")
.setValue(messageObject)
}
messageBox.setText("")
}
}
}

unresolved reference in Firestore UI and display it

am using Firebase UI for displaying data in recyler view from Firestore.And i wanna that this query will display on my app but i can't add this reference. Can anyone please guide me on this?
i do my app witch a tutorial but its expired and i try to do and lern a lot of my self but with this i cant do enything
MainACtivity.kt
package com.example.nfc
import android.content.Intent
import android.os.Bundle
import android.view.*
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
data class User(
val displayName: String = "",
val emojis: String = ""
)
class UserViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
class MainActivity : AppCompatActivity() {
private val db = Firebase.firestore
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
auth = Firebase.auth
// Query the users collection
val query = db.collection("users")
val options = FirestoreRecyclerOptions.Builder<User>().setQuery(query, User::class.java)
.setLifecycleOwner(this).build()
val adapter = object: FirestoreRecyclerAdapter<User, UserViewHolder>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = LayoutInflater.from(this#MainActivity).inflate(android.R.layout.simple_list_item_2,parent,false)
return UserViewHolder(view)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: User) {
val tvName: TextView=holder.itemView.findViewById(android.R.id.text1)
val tvEmojis: TextView=holder.itemView.findViewById(android.R.id.text2)
tvName.text = model.displayName
tvEmojis.text = model.emojis
}
}
uzytkownicy.adapter = adapter
uzytkownicy.layoutManager = LinearLayoutManager(this)
//end
val addButton = findViewById(R.id.addButton)as Button
addButton.setOnClickListener{
val intent = Intent(this, addtrasa::class.java)
startActivity(intent)
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/szarytlo"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvUsers"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
and thats my error
enter image description here
You do not assign an object to uzytkownicy anywhere in your MainActivity, so it is not clear to the compiler what type of object it is meant to be. From the context of the code, it looks like you mean for it to be a RecyclerView, and you probably want to use the one in activity_main.xml. If so, you would need to assign it as such:
val uzytkownicy: RecyclerView = findViewById(R.id.rvUsers)
Then you can go ahead and use that reference to set the adapter and layout manager as you're already attempting to do.

button click inside an item in recyclerview refreshes entire activity

I'm implementing a RecyclerView which has items which have a delete button, the data comes from Firebase and the delete button changes a "saved" value in firebase. this recyclerview is present in the third menu of the bottom navigation bar of the main activity.
When I click on the delete button, the entire activity restarts and the activity starts with the first menu of the bottom navigation bar
How do I stop this restarting action?
I'm attaching the RecyclerView adapter code below:
package com.demo.ash.demoapp
import android.content.Intent
import android.os.Environment
import android.support.v7.widget.RecyclerView
import android.transition.TransitionManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import kotlinx.android.synthetic.main.offline_client.view.*
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONObject
import java.io.File
/**
* Created by ashwin on 3/5/2018.
*/
class OfflineClientAdapter(val list: MutableList<Client>, val clientIDList:MutableList<String>): RecyclerView.Adapter<OfflineClientViewHolder>() {
lateinit var vg: ViewGroup
override fun getItemCount(): Int {
return list.size
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): OfflineClientViewHolder {
val layoutInflator = LayoutInflater.from(parent?.context)
vg = parent!!
val cellForRow = layoutInflator.inflate(R.layout.offline_client, parent, false)
return OfflineClientViewHolder(cellForRow, "")
}
override fun onBindViewHolder(holder: OfflineClientViewHolder?, position: Int) {
val row = list.get(position)
holder?.view?.NameView?.text = row.cname
holder?.view?.PhnumView?.text = row.cphonenum
holder?.clientID = clientIDList[position]
var encodedimage = IOHelper.stringToBitmap(row.cimage)
holder?.view?.client_image?.setImageBitmap(encodedimage)
val user = FirebaseAuth.getInstance().currentUser
var database = FirebaseDatabase.getInstance().getReference("Users").child(user?.phoneNumber)
.child("Clients").child(clientIDList[position])
holder?.view?.delete_client?.setOnClickListener {
val path = Environment.getExternalStorageDirectory()
val dir = File(path.toString() + "/pranjal/saved_clients.txt")
var clients = IOHelper.stringFromFile(dir)
var t = JSONObject(clients)
t.remove(clientIDList[position])
database.child("saved").setValue(false)
}
}
}
class OfflineClientViewHolder(val view: View, var clientID: String): RecyclerView.ViewHolder(view) {
init{
view.setOnClickListener {
val intent = Intent(view.context, OfflinePatientListActivity::class.java)
intent.putExtra("clientID",clientID)
view.context.startActivity(intent)
}
}
}
If you don't want to start an activity on button click, why do you have this code?
view.context.startActivity(intent)
?
When I click on the delete button, the entire activity restarts and the activity starts with the first menu of the bottom navigation bar
It kinda sounds like your Application is crashing. Unless you are doing something that would unintentionally (or intentionally?) restart said Activity.
It looks like you are changing the adapters data (deleting it) without calling the necessary methods to alert the adapter and recylerview that it needs to update its data. Make sure you call the necessary .notify...() methods after updating the data.
If the delete button is a part of the recylerview, make sure that you are taking it into account in the appropriate callbacks / code.
I’d make sure there aren’t any crashes going on in your
.delete_client?.setOnClickListener { ... }code.
Also make sure you aren’t accessing a null list in the other callbacks.
Hope this helps!

JavaFX 8: Property bindings for custom objects

I have a custom object hold by a ObjectProperty instance which should be bound to the StringProperty of a javafx.scene.text.Text.
If I do the obvious thing and use text.textProperty().bind(..); the object property gets bound and the Text actually displays content (I believe the result of toString).
But I do need to modify the String which is actually displayd in text.
Where can I modify what value is actually provided to the binding?
== EDIT ==
Following the first anwer I created this simple test application:
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class BindingsTest {
public static void main(String... args) {
final ObjectProperty<Foo> foo = new SimpleObjectProperty<>();
foo.set(Foo.FOO);
final StringProperty textProperty = new SimpleStringProperty();
textProperty.bind(Bindings.createStringBinding(() -> foo.get().name().toLowerCase()));
System.out.println(textProperty.get());
foo.set(Foo.BAR);
System.out.println(textProperty.get());
}
private enum Foo {
FOO, BAR
}
}
Both outputs are 'foo' whereas I expected the second one to be 'bar'. So after all probably Bindings.createStringBinding(..) is not what I am looking for?
You are looking for Bindings.createStringBinding().
final ObjectProperty<CustomObject> objProperty;
text.textProperty.bind(Bindings.createStringBinding(() -> {
final CustomObject value = objProperty.getValue();
return value != null ? value.toString().toUpperCase() : "";
}, objProperty));

Resources