Home > database >  How to start an activity from another acitivity when using databinding
How to start an activity from another acitivity when using databinding

Time:01-17

I am using data binding in my project but whenever i want to start a new activity from my current one, it throws an error. I tried all the methods i can find on stackoverflow but none of those are seem to be working for me.

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app.erp, PID: 12624
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app.erp/com.app.erp.teacher_view.ActivityAfterTeacherLoginNavigationTakeAttendance}: java.lang.NullPointerException: null cannot be cast to non-null type java.util.ArrayList<kotlin.String>{ kotlin.collections.TypeAliasesKt.ArrayList<kotlin.String> }
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3308)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3457)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2044)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:224)
    at android.app.ActivityThread.main(ActivityThread.java:7560)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
 Caused by: java.lang.NullPointerException: null cannot be cast to non-null type java.util.ArrayList<kotlin.String>{ kotlin.collections.TypeAliasesKt.ArrayList<kotlin.String> }
    at com.app.erp.teacher_view.ActivityAfterTeacherLoginNavigationTakeAttendance.onCreate(ActivityAfterTeacherLoginNavigationTakeAttendance.kt:86)
    at android.app.Activity.performCreate(Activity.java:7894)
    at android.app.Activity.performCreate(Activity.java:7881)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3283)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3457) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2044) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:224) 
    at android.app.ActivityThread.main(ActivityThread.java:7560) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

My Activity -

class ActivityAfterTeacherLoginNavigation : AppCompatActivity() {
private val fragmentViewModel : ActivityAfterTeacherLoginNavigationViewModel by viewModels()
private val db = FirebaseFirestore.getInstance()
private lateinit var teacherAttendanceArrayListRecyclerView: ArrayList<FragmentTeacherAttendanceLogRecyclerViewDataClass>
private lateinit var binding: ActivityAfterTeacherLoginNavigationBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = DataBindingUtil.setContentView(this, R.layout.activity_after_teacher_login_navigation)
    binding.addAttendance = this
    teacherAttendanceArrayListRecyclerView = arrayListOf<FragmentTeacherAttendanceLogRecyclerViewDataClass>()

    val navController = findNavController(R.id.fragmentContainerView)
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView)!!
    val navigator = KeepStateNavigator(this, navHostFragment.childFragmentManager, R.id.fragmentContainerView)
    navController.navigatorProvider  = navigator
    navController.setGraph(R.navigation.teacher_activity_bottom_navigation)
    binding.bottomNavigationView.setupWithNavController(navController)

    navController.addOnDestinationChangedListener { _, destination, _ ->
        when ((destination as FragmentNavigator.Destination).className) {
            FragmentTeacherAttendanceLog::class.qualifiedName -> {
                binding.fab.show()
                binding.fab.text = "Add Attendance"
            }
            else -> {
                binding.fab.hide()
            }
        }
    }

    loadTeacherInfo()
    loadBatchData()
    getAttendanceData()

}
    fun navigateToTakeAttendance(view: View) {
    startActivity(Intent(this@ActivityAfterTeacherLoginNavigation, ActivityAfterTeacherLoginNavigationTakeAttendance::class.java))
}

My XML file -

<layout 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">

<data>
    <variable
        name="addAttendance"
        type="com.app.erp.teacher_view.ActivityAfterTeacherLoginNavigation" />
</data>

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@ id/parentFrameLayout"
    tools:context=".teacher_view.ActivityAfterTeacherLoginNavigation">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <fragment
            android:id="@ id/fragmentContainerView"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
            android:id="@ id/fab"
            android:stateListAnimator="@null"
            app:elevation="0dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:onClick="@{addAttendance::navigateToTakeAttendance}"
            app:layout_anchor="@id/bottomNavigationView"
            app:icon="@drawable/ic_baseline_post_add_24"
            app:layout_anchorGravity="end"
            android:translationY="-20sp"
            android:layout_marginEnd="20sp"/>

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@ id/bottomNavigationView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:elevation="0dp"
            android:layout_gravity="bottom"
            app:labelVisibilityMode="selected"
            app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
            app:menu="@menu/teacher_activity_bottom_menu" />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@ id/secondaryFragmentContainerTeacher" />
</FrameLayout>

Let me know if any other information is required. I am new to Data binding and it's concepts so i apologize if my approach is not good.

The code of the activity i want to start

class ActivityAfterTeacherLoginNavigationTakeAttendance : AppCompatActivity() {
private val db = FirebaseFirestore.getInstance()
private val fragmentViewModel: ActivityAfterTeacherLoginNavigationTakeAttendanceViewModel by viewModels()
private lateinit var title: TextView
private lateinit var binding: ActivityAfterTeacherLoginNavigationTakeAttendanceBinding

private lateinit var tempArrayListSemesterInfo: ArrayList<String>

@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = DataBindingUtil.setContentView(this, R.layout.activity_after_teacher_login_navigation_take_attendance)
    

    binding.title.text = "Attendance Details"

    binding.proceedBut.setOnClickListener {
        checkInput()
    }

    supportFragmentManager.popBackStack()

    binding.semesterSelect.setOnClickListener{
        if(binding.batchSelect.text.toString().isBlank()){
            binding.batchSelect.setError("Please select Batch first",null)
            binding.batchSelect.requestFocus()
        }
    }

    binding.dateSelect.setText(getCurrentDate(),null)
    binding.timeSelect.setText(getCurrentTime(),null)
    fragmentViewModel.teacherCodeData.value = intent.getStringExtra("teacherCodeTxt").toString()
    binding.teacherCode.setText(intent.getStringExtra("teacherCodeTxt").toString(),null)
    fragmentViewModel.teacherNameData.value = intent.getStringExtra("teacherTxt").toString()
    binding.teacherSelect.setText(intent.getStringExtra("teacherTxt").toString(),null)
    val batchArrayList: ArrayList<String> = intent.getStringArrayListExtra("batchTxt") as ArrayList<String>
    val batchArrayAdapter = ArrayAdapter<String>(this,
        R.layout.exposed_dropdown_menu_item_layout,batchArrayList)
    binding.batchSelect.setAdapter(batchArrayAdapter)
    val courseArrayList: ArrayList<String> = intent.getStringArrayListExtra("courseTxt") as ArrayList<String>
    val courseArrayAdapter = ArrayAdapter<String>(this,
        R.layout.exposed_dropdown_menu_item_layout,courseArrayList)
    binding.courseSelect.setAdapter(courseArrayAdapter)

    tempArrayListSemesterInfo = arrayListOf<String>()
    binding.batchSelect.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
        if(binding.batchSelect.text.isNotEmpty()){
            binding.batchSelect.error = null
        }
        binding.semesterSelect.text.clear()
        tempArrayListSemesterInfo.clear()
        val selectedItem = parent.getItemAtPosition(position).toString()

        db.collection("BatchInfo").whereEqualTo("Name",selectedItem)
            .addSnapshotListener(object: EventListener<QuerySnapshot> {
                @SuppressLint("NotifyDataSetChanged")
                override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
                    if(error != null){
                        Log.e("Firestore Error",error.message.toString())
                        return
                    }
                    for(dc : DocumentChange in value?.documentChanges!!){
                        if(dc.type == DocumentChange.Type.ADDED){
                            tempArrayListSemesterInfo.addAll(dc.document.data.getValue("Semester") as Collection<String>)
                            val addStudentSemesterSelectAdapter = ArrayAdapter(this@ActivityAfterTeacherLoginNavigationTakeAttendance,
                                R.layout.exposed_dropdown_menu_item_layout, tempArrayListSemesterInfo)
                            binding.semesterSelect.setAdapter(addStudentSemesterSelectAdapter)
                        }
                        break
                    }

                }
            })
    }

    binding.courseSelect.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
        if (binding.courseSelect.text.isNotEmpty()) {
            binding.courseSelect.error = null
        }
        val selectedItem = parent.getItemAtPosition(position).toString()
        db.collection("CourseInfo").whereEqualTo("CourseName",selectedItem).get()
            .addOnCompleteListener { itAlt ->
                if(itAlt.isSuccessful){
                    for (doc in itAlt.result!!){
                        binding.courseCode.setText(doc.data.getValue("CourseCode").toString(),null)
                    }
                }
            }
    }

    binding.proceedBut.setOnClickListener {
        checkInput()
    }
}
}

CodePudding user response:

Inside the loop you are trying to read a value that might be null value?.documentChanges . So you must use safe cast operator

add ? after as

for(dc : DocumentChange in value?.documentChanges!!){
        if(dc.type == DocumentChange.Type.ADDED){
            tempArrayListSemesterInfo.addAll(dc.document.data.getValue("Semester") as? Collection<String>)
            val addStudentSemesterSelectAdapter = ArrayAdapter(this@ActivityAfterTeacherLoginNavigationTakeAttendance,
                R.layout.exposed_dropdown_menu_item_layout, tempArrayListSemesterInfo)
            binding.semesterSelect.setAdapter(addStudentSemesterSelectAdapter)
        }
        break
    }
  •  Tags:  
  • Related