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.
Related
I've been working recently in one of my projects in Android (kotlin), and in my LogIn page I was trying to implement the Google Sign In, for my surprise I was able to log in, but I can never see the typical pop up window that pops when you press the button to sign in (in my android app), it directly redirects me into gmail sign in in the browser, and then that's how I'm able to sign in, but never get to see the pop up.
I've tried changing some of the deprecated function, but never got anything (startActivityForResult)!
`This is my code:
package com.example.googlesignin
import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.Toast import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInAccount import com.google.android.gms.auth.api.signin.GoogleSignInOptions import com.google.android.gms.common.api.ApiException import com.google.android.material.snackbar.Snackbar import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.GoogleAuthProvider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.tasks.await import kotlinx.coroutines.withContext
const val REQUEST_CODE_SIGNIN = 21 class MainActivity : AppCompatActivity() {
lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
auth = FirebaseAuth.getInstance()
val googleButton = findViewById<Button>(R.id.googleButton)
googleButton.setOnClickListener {
val options = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id_googleSignIn))
.requestEmail()
.build()
val signInClient = GoogleSignIn.getClient(this,options)
signInClient.signInIntent.also {
this.startActivityForResult(it, REQUEST_CODE_SIGNIN)
}
}
}
private fun googleAuthForFirebase(account: GoogleSignInAccount) {
val credentials = GoogleAuthProvider.getCredential(account.idToken,null)
CoroutineScope(Dispatchers.IO).launch {
try
{
auth.signInWithCredential(credentials).await()
withContext(Dispatchers.Main)
{
Toast.makeText(this#MainActivity,"Successfully Logged In",Toast.LENGTH_LONG).show()
}
}catch (e: java.lang.Exception)
{
withContext(Dispatchers.Main)
{
Toast.makeText(this#MainActivity,e.message,Toast.LENGTH_LONG).show()
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == REQUEST_CODE_SIGNIN)
{
val account = GoogleSignIn.getSignedInAccountFromIntent(data).result
account?.let {
googleAuthForFirebase(it)
}
}
}
}
PD: I have only this activity and I have the xml of main_activity containing only one button to sign in. And I've done all the correct steps linking my project to firebase, if not I wouldn't be able to log in with my gmail account, but no pop up window.
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("")
}
}
}
I was developing an Kotin App which make use of Navigation component to moves between the diferents screen of the App.
My problems comes when I try to separate the root_navigation.xml of the main_navigation.xml
The main structure of my app is a splashScreen which send you to LoginScreen, where you can authenticated which firebase via Googe Provider or email/password provider.
The HGoogle Authentication works fine, and send you to the HomeFragment of the App, but the Authentication with email/password rise the above title error.
The code of my navigation files are the following
mobile_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="#+id/mobile_navigation"
app:startDestination="#+id/nav_login">
<fragment
android:id="#+id/nav_login"
android:name="com.example.appadoskotlin2.ui.login.LoginFragment"
android:label="Login"
tools:layout="#layout/fragment_login">
<action
android:id="#+id/navigation_login_to_navigation_home"
app:destination="#id/nav_home"/>
</fragment>
<fragment
android:id="#+id/nav_home"
android:name="com.example.appadoskotlin2.ui.home.HomeFragment"
android:label="#string/menu_home"
tools:layout="#layout/fragment_home">
<action
android:id="#+id/navigation_home_to_navigation_item_home"
app:destination="#id/navigation_item_home"/>
</fragment>
<fragment
android:id="#+id/navigation_item_home"
android:name="com.example.appadoskotlin2.ui.home.ItemServiceFragment"
android:label="Servicios"
tools:layout="#layout/item_list">
<argument
android:name="item"
app:argType="com.example.appadoskotlin2.data.Service"/>
</fragment>
<fragment
android:id="#+id/nav_contract"
android:name="com.example.appadoskotlin2.ui.contract.ContractFragment"
android:label="#string/menu_contract"
tools:layout="#layout/fragment_contract">
<action
android:id="#+id/navigation_contract_to_navigation_item_contract"
app:destination="#id/navigation_item_contract"/>
</fragment>
<fragment
android:id="#+id/navigation_item_contract"
android:name="com.example.appadoskotlin2.ui.home.ItemServiceFragment"
android:label="Servicios"
tools:layout="#layout/item_list">
</fragment>
<fragment
android:id="#+id/nav_publish"
android:name="com.example.appadoskotlin2.ui.publish.PublishFragment"
android:label="#string/menu_publish"
tools:layout="#layout/fragment_publish">
<action
android:id="#+id/navigation_publish_to_navigation_item_publish"
app:destination="#id/navigation_item_publish"/>
</fragment>
<fragment
android:id="#+id/navigation_item_publish"
android:name="com.example.appadoskotlin2.ui.publish.ItemPublishFragment"
android:label="Servicios"
tools:layout="#layout/item_list">
</fragment>
</navigation>
root_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="#+id/root_navigation"
app:startDestination="#+id/navigation_splash">
<activity
android:id="#+id/navigation_splash"
android:name="com.example.appadoskotlin2.SplashActivity"
android:label="activity_splash"
tools:layout="#layout/activity_splash" >
<action
android:id="#+id/action_navigation_splash_to_navigation_login"
app:destination="#id/navigation_login" />
</activity>
<activity
android:id="#+id/navigation_login"
android:name="com.example.appadoskotlin2.MainActivity"
android:label="activity_login"
tools:layout="#layout/activity_main" >
<action
android:id="#+id/action_navigation_login_to_navigation_main"
app:destination="#id/navigation_main" />
</activity>
<activity
android:id="#+id/navigation_main"
android:name="com.example.appadoskotlin2.MainActivity"
android:label="MainActivity"
tools:layout="#layout/activity_main"/>
</navigation>
And the code of my LoginFragment and MainActivty of the App are these:
MainActivity.kt
package com.example.appadoskotlin2
import android.os.Bundle
import android.view.Menu
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.navigation.NavigationView
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.drawerlayout.widget.DrawerLayout
import androidx.appcompat.app.AppCompatActivity
import com.example.appadoskotlin2.databinding.ActivityMainBinding
import com.example.appadoskotlin2.ui.home.HomeFragment
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarMain.toolbar)
binding.appBarMain.fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_content_main)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(R.id.nav_login,
R.id.nav_home, R.id.nav_contract, R.id.nav_publish), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
LoginFragment.kt
package com.example.appadoskotlin2.ui.login
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.Navigation
import com.example.appadoskotlin2.R
import com.example.appadoskotlin2.databinding.FragmentLoginBinding
import com.example.appadoskotlin2.ui.diologs.LoginDialog
import com.example.appadoskotlin2.ui.diologs.RegisterDialog
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.material.button.MaterialButton
import com.google.firebase.FirebaseApp
import com.google.firebase.auth.FirebaseAuth
class LoginFragment: Fragment() {
private val RC_SIGN_IN = 123
private lateinit var navController : NavController
private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!!
private var firebaseAuth: FirebaseAuth? = null
private var mGoogleSignIn: GoogleSignInClient? = null
private var btn_google: MaterialButton? = null
private var btn_register: MaterialButton? = null
private var btn_login: MaterialButton? = null
private var diolog_register: RegisterDialog? = null
private var diolog_login: LoginDialog? = null
//TODO("Configurar firebase y linkear la vista")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
_binding = FragmentLoginBinding.inflate(inflater, container, false)
val root: View = binding.root
initView(root)
initListeners()
return root
}
private fun initListeners() {
val loginActivity: LoginFragment = this
btn_google?.setOnClickListener(View.OnClickListener {
createRequest()
signIn()
})
btn_register?.setOnClickListener(View.OnClickListener {
diolog_register = RegisterDialog(firebaseAuth, loginActivity)
fragmentManager?.let { it1 -> diolog_register!!.show(it1, "RegisterDiolog") }
})
btn_login?.setOnClickListener(View.OnClickListener {
diolog_login = LoginDialog(firebaseAuth, this.context)
fragmentManager?.let { it1 -> diolog_login!!.show(it1, "LoginDiolog") }
})
}
fun initView(root: View){
btn_google = root.findViewById(R.id.btn_google)
btn_register = root.findViewById(R.id.btn_register)
btn_login = root.findViewById(R.id.btn_login)
context?.let { FirebaseApp.initializeApp(it) }
firebaseAuth = FirebaseAuth.getInstance()
}
private fun signIn() {
val signInIntent = mGoogleSignIn!!.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
showHome()
}
private fun showHome() {
navController = Navigation.findNavController(this.requireView())
navController.navigate(R.id.navigation_login_to_navigation_home)
Toast.makeText(context, "Login completed successfully", Toast.LENGTH_SHORT).show()
}
private fun createRequest() {
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken("786240463795-o92gljk39cmdd0pra162arebskntkdu5.apps.googleusercontent.com")
.requestEmail()
.build()
mGoogleSignIn = GoogleSignIn.getClient(this.activity, gso)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
As I say everythings works fine until I try to separate the navigation in those two files, in order to differentiate between the LoginNavigation, and the Naviation inside the App once the user is logged.
I don't know if the fact of the LoginScreen be a fragment have something related which the problem.
I hope you can help, and if it's like this take thanks in advance !
[EDIT]
Added the navigation.xml as I changed it after several tips:
Still through the same error.
mobile_navigation.xml
root_navigation.xml
Make sure you implement the navigation graph right way. use fragments.
root_navigation.xml
mobile_navigation.xml
add here your desired fragments you want to navigate from login.
(I suggest use login fragment in splash screen for your app launch. and other fragments implement through main activity)
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.
Hello i have an issue with MapBox SDK for android , i use kotlin language in my project and the Viewmap value always came with problem. I'm new in kotlin so maybe i skip something.
i make bottom_navigation_bar so i use fragment to navigate in my application.
my fragment class were i use my variable
package com.example.parky.parky_android
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.view.ContextThemeWrapper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import com.mapbox.mapboxsdk.constants.Style
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
class ItemFourFragment : Fragment() {
private lateinit var mapView: MapView
fun onCreate(savedInstanceState: Bundle?, context: Context, inflater: LayoutInflater, container: ViewGroup?) {
super.onCreate(savedInstanceState)
// Mapbox Access token
Mapbox.getInstance(context, getString(R.string.token_mapbox))
val view = inflater.inflate(R.layout.activity_main, container ,false)
mapView = view.findViewById(R.id.mapview)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync({
it.setStyle(Style.SATELLITE)
// Customize map with markers, polylines, etc.
})
}
override fun onStart() {
super.onStart()
mapView.onStart()
}
override fun onResume() {
super.onResume()
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView.onPause()
}
override fun onStop() {
super.onStop()
mapView.onStop()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapView.onSaveInstanceState(outState)
}
override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}
override fun onDestroy() {
super.onDestroy()
mapView.onDestroy()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_item_four, container, false)
}
companion object {
fun newInstance(): ItemFourFragment {
val fragment = ItemFourFragment()
return fragment
}
}
}
And my xml files where i display it :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ItemFiveFragment">
<com.mapbox.mapboxsdk.maps.MapView
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
mapbox:mapbox_cameraTargetLat="41.885"
mapbox:mapbox_cameraTargetLng="-87.679"
mapbox:mapbox_styleUrl="#string/mapbox_style_satellite"
mapbox:mapbox_cameraTilt="20"
mapbox:mapbox_cameraZoom="12"/>
</RelativeLayout>
and finally the log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.parky.parky_android, PID: 30820
kotlin.UninitializedPropertyAccessException: lateinit property mapView has not been initialized
at com.example.parky.parky_android.ItemFourFragment.onStart(ItemFourFragment.kt:42)
at android.support.v4.app.Fragment.performStart(Fragment.java:2372)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1467)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Do you have any idea what the problem is ?
Thanks for your time.
So here:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_item_four, container, false)
}
You're returning a view that will be attached to the Fragment and actually displayed.
Here:
fun onCreate(savedInstanceState: Bundle?, context: Context, inflater: LayoutInflater, container: ViewGroup?) {
super.onCreate(savedInstanceState)
// Mapbox Access token
Mapbox.getInstance(context, getString(R.string.token_mapbox))
val view = inflater.inflate(R.layout.activity_main, container ,false)
mapView = view.findViewById(R.id.mapview)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync({
it.setStyle(Style.SATELLITE)
// Customize map with markers, polylines, etc.
})
}
You're inflating a new view that is never being attached to anything. It's also inflating a separate layout, activity_main.xml, which I assume does not include a MapView.
Instead, you should resolve your MapView within onViewCreated(), after you've returned your inflated view in onCreateView():
override fun onViewCreated(View view, Bundle savedState) {
mapView = view.findViewById(R.id.mapview).apply {
onCreate(savedState)
getMapAsync { map ->
map.setStyle(Style.SATELLITE)
}
}
}
You also should not use lateinit var for this property, as you're not guaranteed to have a view created (e.g. onCreateView() may never be invoked). One instance of this is if your Fragment is on the backstack and not user visible. On a configuration change or recreation of the Activity, the Fragment on the backstack will go through onCreate(), but will not create a view. In this case, you would run into a crash in onStart() attempting to reference mapView that has not been initialized.
Instead, leave it nullable, and perform the operations with mapView?.doThing().