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)
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("")
}
}
}
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.
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().
I have an activity which has only one listview. I have set the listview onClick Listener which is supposed to open a new fragment depending in which list item was clicked, I've checked but cant understand why the List item clicks cannot work
Below is the code foe that activity
package com.jp.kabs.mybills;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
import adapters.NavDrawerAdapter;
import models.NavDrawerItemModel;
/**
* Created by Kabunyi on 27/05/2015.
*/
public class MainActivity extends ActionBarActivity {
private ListView lstMain;
private String[] menuItems;
private TypedArray menuIcons;
private NavDrawerAdapter adapter;
private ArrayList<NavDrawerItemModel> navDrawerItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connnectToXML();
lstMain.setOnItemClickListener(new DrawerItemsClickListener());
//fetch resources
// load slide menu items
menuItems = getResources().getStringArray(R.array.nav_drawer_items);
// nav drawer icons from resources
menuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
addStuffToArrayList();
}
private void connnectToXML(){
lstMain = (ListView)findViewById(android.R.id.list);
}
private void addStuffToArrayList(){
navDrawerItems = new ArrayList<NavDrawerItemModel>();
// adding nav drawer items to array
// Home
navDrawerItems.add(new NavDrawerItemModel(menuItems[0], menuIcons.getResourceId(0, -1)));
// Find People
navDrawerItems.add(new NavDrawerItemModel(menuItems[1], menuIcons.getResourceId(1, -1)));
// Photos
navDrawerItems.add(new NavDrawerItemModel(menuItems[2], menuIcons.getResourceId(2, -1)));
// Communities, Will add a counter here
navDrawerItems.add(new NavDrawerItemModel(menuItems[3], menuIcons.getResourceId(3, -1), true, "22"));
// Pages
navDrawerItems.add(new NavDrawerItemModel(menuItems[4], menuIcons.getResourceId(4, -1)));
// What's hot, We will add a counter here
//navDrawerItems.add(new NavDrawerItemModel(navMenuTitles[5], navMenuIcons.getResourceId(5, -1), true, "50+"));
// Recycle the typed array
menuIcons.recycle();
// setting the nav drawer list adapter
adapter = new NavDrawerAdapter(navDrawerItems, getApplicationContext());
lstMain.setAdapter(adapter);
}
//method to display a view fragment of choice
private void displayView(int position){
//update the main content by replacing fragments
Fragment frag = null;
switch (position){
case 0:
frag = new AddMyBillsFragment();
AddMyBillsFragment selectedBillerToEasyPayFrag = new AddMyBillsFragment();
getSupportFragmentManager().
beginTransaction().
replace(R.id.my_layout, selectedBillerToEasyPayFrag, "BillerToEasyPayDetails").addToBackStack(null).commit();
break;
case 1:
frag = new ViewMyBillsFragment();
break;
case 2:
frag = new PayMyBillsFragment();
break;
case 3:
frag = new EasyPayFragment();
break;
case 4:
frag = new MyBillAlertsFragment();
break;
default:
break;
}
if(frag !=null){
//FragmentManager fm = getSupportFragmentManager();
//fm.beginTransaction().replace(R.id.frame_container, frag).commit();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.my_layout, frag).commit();
//update selected items and title then close drawer
lstMain.setItemChecked(position, true);
lstMain.setSelection(position);
setTitle(menuItems[position]);
//}else{
Log.e("MenuActivity", "Error in creating fragment");
}
}
//class to handle drawer list item clicks
private class DrawerItemsClickListener implements ListView.OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
displayView(position);
}
}
}
Kindly assist
Code for activity main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>