kotlin.KotlinNullPointerException at com.example.myapplication.ui.home.HomeFragment - android

I'm trying to manipulate elements from xml of a fragment, but all tries I did, result in some error. When I use root!!.qr_code.visibility = View.INVISIBLE, I got this:
What is wrong with my elements reference?
FATAL EXCEPTION: main
Process: com.example.test, PID: 26445
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.myapplication.MainActivity}: kotlin.KotlinNullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Caused by: kotlin.KotlinNullPointerException
at com.example.myapplication.ui.home.HomeFragment.setElementVisibility(HomeFragment.kt:49)
at com.example.myapplication.MainActivity.onCreate(MainActivity.kt:72)
My HomeFragment: (called from onCreate in MainActivity)
package com.example.myapplication.ui.home
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.example.myapplication.R
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.view.*
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
private var root: View? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreate(savedInstanceState);
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel::class.java)
root = inflater.inflate(R.layout.fragment_home, container, false)
//The findViewById appears as unresolved reference.
qrcode = findViewById(R.id.qr_code) as LinearLayout
return root
}
fun setElementVisibility(permissionData: Boolean, serialData: Boolean){
//also I tried:
//qr_code.visibility = View.INVISIBLE
//which gives me the same error from above
if(!serialData){
root!!.qr_code.visibility = View.VISIBLE
root!!.failed_layout.visibility = View.VISIBLE
root!!.success_layout.visibility = View.INVISIBLE
} else if(!permissionData){
root!!.qr_code.visibility = View.INVISIBLE
root!!.failed_layout.visibility = View.VISIBLE
root!!.success_layout.visibility = View.INVISIBLE
} else if(permissionData && serialData){
root!!.qr_code.visibility = View.INVISIBLE
root!!.failed_layout.visibility = View.INVISIBLE
root!!.success_layout.visibility = View.VISIBLE
}
}
}
MainActivity call to HomeFragment:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_home), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
val homeFragment: HomeFragment = HomeFragment()
homeFragment.setElementVisibility(true, true)//this parameters won't be statics
}
My xml of fragment:
<?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"
tools:context=".ui.home.HomeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/success_layout"
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginVertical="50dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="#+id/success_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="0dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="0dp"
android:ems="8"
android:gravity="center"
android:text="#string/success_msg"
android:textAlignment="center"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="#+id/failed_layout"
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginVertical="50dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="#+id/failed_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="0dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="0dp"
android:ems="8"
android:gravity="center"
android:text="#string/failed_msg"
android:textAlignment="center"
android:textColor="#color/design_default_color_error"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="#+id/qr_code"
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginVertical="50dp"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="#+id/openScanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/take_scan_qr_code" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

findViewById()is a method of the View object.
Try this :
qrcode = root.findViewById(R.id.qr_code) as LinearLayout

try this a quick solution, more details at last
class HomeFragment : Fragment(R.layout.fragment_home) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?){
super.onViewCreated(view, savedInstanceState)
setElementVisibility()
}
fun setElementVisibility(){
qr_code.visibility = View.INVISIBLE
failed_layout.visibility = View.VISIBLE
success_layout.visibility = View.INVISIBLE
}
}
So u r getting unresolve reference because as answered by bruno findviewbyId() is applied to View object. so u can use his method.
In my method u will call the function only after the view is created i.e. onViewCreated(). so u can now call directly. I called the view in fragment constructor itself. This is short and easy.
Thanks for more go through documentation.

You can't just init val homeFragment: HomeFragment = HomeFragment() and access it's view from Activity. You need to attach Fragment to activity. This is official example of usage and integration of fragments

Related

Recycleviewer item got doubled when returning back from fragment

The problem here is when I'm returning from my support fragment to home fragment back every time my items in the recycle viewer got doubled. Each time i am shifting fragment to fragment my recycle viewer item in the homefragment got doubled. But when, I reopen the app its all got corrected but when i click on another fragment and come back the item in recycle viewer in home fragment got doubled. Kindly help me
// **HomeFragment.kt**
package com.service.bookitapp
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 kotlinx.android.synthetic.main.fragment_home.*
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
class HomeFragment : Fragment() {
private var param1: String? = null
private var param2: String? = null
private val arrCategory = ArrayList<CategoryModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_home, container, false)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView =view.findViewById<RecyclerView>(R.id.recyclerCategory)
arrCategory.add(CategoryModel(R.drawable.electrician,"Electrician"))
arrCategory.add(CategoryModel(R.drawable.plumber,"Plumber"))
arrCategory.add(CategoryModel(R.drawable.acservice,"AC Service"))
arrCategory.add(CategoryModel(R.drawable.carpentry,"Carpentry"))
arrCategory.add(CategoryModel(R.drawable.drop,"Pick up & Drop"))
arrCategory.add(CategoryModel(R.drawable.painting,"Painting"))
arrCategory.add(CategoryModel(R.drawable.waterfilter,"Water Filter Repair"))
arrCategory.add(CategoryModel(R.drawable.packer,"Pack and Move"))
recyclerView.layoutManager = GridLayoutManager(context,3)
val recyclerAdapter = context?.let { RecycleCategoryAdapter(it,arrCategory) }
recyclerView.adapter = recyclerAdapter
}
}
// **fragment_home.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FAF9F6"
android:padding="5dp"
android:orientation="vertical"
tools:context=".HomeFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="UselessParent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/welcome_user"
android:textColor="#color/teal_200"
android:textSize="28sp"
android:padding="8dp"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:src="#drawable/profile"
android:padding="4dp"
android:contentDescription="#string/app_name" />
</RelativeLayout>
<RelativeLayout
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/catg"
android:textStyle="bold"
android:textColor="#6E16e8"
android:layout_alignParentStart="true"
android:textSize="22sp"/>
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="370dp"
android:id="#+id/recyclerCategory">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/offers"
android:textStyle="bold"
android:layout_marginBottom="5dp"
android:textColor="#6E16e8"
android:textSize="22sp"/>
<HorizontalScrollView
android:layout_margin="8dp"
android:layout_width="350dp"
android:layout_height="200dp"
tools:ignore="UselessParent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="350dp"
android:layout_height="wrap_content"
android:src="#drawable/plumbingservice"
android:contentDescription="#string/elect" />
<ImageView
android:layout_width="350dp"
android:layout_height="wrap_content"
android:contentDescription="#string/elect"
android:src="#drawable/cleanview" />
<ImageView
android:layout_width="360dp"
android:layout_height="wrap_content"
android:contentDescription="#string/elect"
android:src="#drawable/elecview" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</LinearLayout>
The followig are the images
first solution, before add first item in list, call clear
arrCategory.clear()
second solution, populate your list in onCreate method of your fragment
Have you tried moving this
private val arrCategory = ArrayList<CategoryModel>(),
locally inside onViewCreated() ?
like this
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView =view.findViewById<RecyclerView>(R.id.recyclerCategory)
val arrCategory = ArrayList<CategoryModel>() // <-- like this?
arrCategory.add(CategoryModel(R.drawable.electrician,"Electrician")
...
...
...
or you can simply initialize the list like this, removing all of it out of the onCreate()
private val arrCategory = arrayListOf<CategoryModel>(
CategoryModel(R.drawable.electrician,"Electrician"),
CategoryModel(R.drawable.plumber,"Plumber"),
CategoryModel(R.drawable.acservice,"AC Service"),
CategoryModel(R.drawable.carpentry,"Carpentry"),
CategoryModel(R.drawable.drop,"Pick up & Drop"),
CategoryModel(R.drawable.painting,"Painting"),
CategoryModel(R.drawable.waterfilter,"Water Filter Repair"),
CategoryModel(R.drawable.packer,"Pack and Move")
)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView =view.findViewById<RecyclerView>(R.id.recyclerCategory)
recyclerView.layoutManager = GridLayoutManager(context,3)
val recyclerAdapter = context?.let { RecycleCategoryAdapter(it,arrCategory) }
recyclerView.adapter = recyclerAdapter
}

RecyclerView showing only 1st item, when tying to set dynamic height

I'm trying to set the dynamic height for my recycler view, because I have the Add button below it, that adds a new item to the list.
I'm using Constraint Layout in my parent fragment. I followed this advice, and when I add first item, it shows up and the ADD button slides down as expected, but the problem is that when I add the second one it just doesn't appear.
Here is the layout of my parent fragment:
<?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="wrap_content"
tools:context=".SecondFragment">
<Button
android:id="#+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="444dp"
android:text="#string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/cancel_button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addItemActionButton" />
<Button
android:id="#+id/cancel_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="76dp"
android:text="#string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="#id/cancel_button"
app:layout_constraintTop_toBottomOf="#+id/addItemActionButton"
app:layout_constraintVertical_bias="1.0" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="372dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#id/addItemActionButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.41"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.065" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/addItemActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="492dp"
android:clickable="true"
android:src="#android:drawable/ic_input_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/recyclerView"
tools:ignore="SpeakableTextPresentCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
And here's the one for the recycler item layout:
<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:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="288dp"
android:layout_height="51dp"
android:layout_marginBottom="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.024">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/item"
android:layout_width="300dp"
android:layout_height="71dp"
android:hint="#string/item" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Here's my fragment code:
package com.example.progresstracker
import android.os.Bundle
import android.util.Log
import android.util.Log.INFO
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.progresstracker.databinding.FragmentSecondBinding
/**
* A simple [Fragment] subclass as the second destination in the navigation.
*/
class SecondFragment : Fragment() {
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>? = null
private var _binding: FragmentSecondBinding? = null
private var items: ArrayList<String> = ArrayList()
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentSecondBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recyclerView.apply {
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
// set the custom adapter to the RecyclerView
adapter = RecyclerAdapter(items)
}
// linearLayoutManager = LinearLayoutManager(context)
// binding.recyclerView.layoutManager = linearLayoutManager
binding.cancelButton.setOnClickListener {
findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
}
binding.addItemActionButton.setOnClickListener {
items.add("Testing..")
adapter = RecyclerAdapter(items)
adapter?.notifyItemInserted(items.size - 1)
binding.recyclerView.adapter = adapter
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
And the adapter:
package com.example.progresstracker
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class RecyclerAdapter(private val items: ArrayList<String>) : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var item: TextView
init {
item = itemView.findViewById(R.id.item)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item_row, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.item.text = items[position]
}
override fun getItemCount(): Int {
return items.size
}
}

Databinding in OnActivityResult

First, I want to tell you that I'm a beginner in coding in Kotlin and this is my first App. Shortly, a part of my App consist in a bluetooth interface and I've decided to use the functionality of databinding instead of the FindViewById.
I want to change the text of the ID status_bluetooth in Fragment_bluetooth when the user click the switch but my app crashes when I try to binding my Views inside OnActivityResult and I don't know why (in the other cases it works). Thanks in advance.
Here the code:
1).kt
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import com.example.drinkbf.databinding.FragmentBluetoothBinding
class ConnectivityBluetooth : Fragment() {
data class Statusbluetooth(
var status: String = ""
)
lateinit var bAdapter: BluetoothAdapter
private lateinit var STATUS: Statusbluetooth
private val REQUEST_CODE_ENABLE_BT: Int = 1
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
val binding = DataBindingUtil.inflate<FragmentBluetoothBinding>(
inflater, R.layout.fragment_bluetooth, container, false
)
bAdapter = BluetoothAdapter.getDefaultAdapter()
if (bAdapter.isEnabled) {
STATUS = Statusbluetooth("Bluetooth is available")
binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_on)
} else {
STATUS = Statusbluetooth("Bluetooth isn't available")
binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_off)
}
binding.bluetoothSwitch.setOnClickListener {
if (bAdapter.isEnabled) {
bAdapter.disable()
STATUS = Statusbluetooth("Bluetooth isn't available")
binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_off)
Toast.makeText(requireActivity(), "Bluetooth is disabled", Toast.LENGTH_SHORT)
.show()
} else {
val intent = Intent(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
startActivityForResult(intent, REQUEST_CODE_ENABLE_BT)
}
}
binding.statusB = STATUS
return binding.root
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?){
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_ENABLE_BT) {
if (resultCode == Activity.RESULT_OK) {
}
//I don't know how can i binding here, for example : STATUS = Statusbluetooth("Bluetooth is available")
// binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_on)
}
//binding.statusB = STATUS
}
}
XML file (Fragment_bluetooth)
<?xml version="1.0" encoding="utf-8"?>
<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="statusB"
type="com.example.drinkbf.ConnectivityBluetooth.Statusbluetooth" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout_editor_absoluteY="81dp">
<TextView
android:id="#+id/status_bluetooth"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:gravity="center"
android:text="#={statusB.status}"
app:layout_constraintBottom_toTopOf="#+id/BluetoothImage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/BluetoothImage"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="100dp"
android:contentDescription="#string/icona_bluetooth_OFF"
android:padding="5dp"
app:layout_constraintBottom_toTopOf="#+id/bluetooth_switch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/discoverable_switch" />
<Switch
android:id="#+id/bluetooth_switch"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:contentDescription="#string/attiva_disattivaSWITCH"
android:gravity="start"
android:text="#string/on_off_switch"
android:textAlignment="gravity"
app:layout_constraintBottom_toTopOf="#+id/discoverable_switch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.504"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/BluetoothImage"
tools:ignore="UseSwitchCompatOrMaterialXml" />
<Switch
android:id="#+id/discoverable_switch"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:contentDescription="#string/discoverable"
android:gravity="start"
android:text="#string/discoverable"
android:textAlignment="gravity"
app:layout_constraintBottom_toTopOf="#+id/textView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/bluetooth_switch"
tools:ignore="UseSwitchCompatOrMaterialXml" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="#string/paired_devices_text"
app:layout_constraintBottom_toTopOf="#+id/paired_devices"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/discoverable_switch" />
<TextView
android:id="#+id/paired_devices"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>
Errors that appear in androidruntime:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.drinkbf, PID: 12743
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=null} to activity {com.example.drinkbf/com.example.drinkbf.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized
at android.app.ActivityThread.deliverResults(ActivityThread.java:5041)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5084)
at android.app.ActivityThread.-wrap20(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized
at com.example.drinkbf.ConnectivityBluetooth.onActivityResult(ConnectivityBluetooth.kt:66)
at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:170)
at android.app.Activity.dispatchActivityResult(Activity.java:7701)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5037)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5084) 
at android.app.ActivityThread.-wrap20(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053) 
at android.os.Handler.dispatchMessage(Handler.java:108) 
at android.os.Looper.loop(Looper.java:166) 
at android.app.ActivityThread.main(ActivityThread.java:7529) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 
Make binding a global variable, initialize it in onCreateView, that way you can use binding variable through out the class.
That is:
private lateinit var binding:FragmentBluetoothBinding // global variable
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
// Initialize it here
binding =
DataBindingUtil.inflate<FragmentBluetoothBinding>(
inflater, R.layout.fragment_bluetooth, container, false
)
return binding.root
}
override fun onActivityResult() {
binding // It's valid here
}

Kotlin program throwing a nullPointerException when setting a clickListener to a button defined in an inflated XML, not sure where to go

I'm attempting to teach myself Android Development and Kotlin, and I've been stuck on this issue for a while. Because I'm relatively new, I'm almost certain it's just something I don't understand, and would really appreciate any help. parameterize_button is defined in the fragment_dashboard XML file. This XML is inflated within DashboardFragment.kt, but it still throws:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.caelussidekick, PID: 15355
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.caelussidekick.ui.dashboard.DashboardFragment.onCreateView
Here's my XML, and I know it is parameterize_button because I haven't set any onClickListeners to any of the other buttons.
<?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"
tools:context=".ui.dashboard.DashboardFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/parameterize_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/parameters_buttion" />
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/outputs_header"
android:textAlignment="center"
android:textSize="20sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/dv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/empty_string"
android:textAlignment="textEnd" />
<TextView
android:id="#+id/dv_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/dv"
android:textAlignment="textStart" />
<Button
android:id="#+id/dv_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/dv_button" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/isp_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/empty_string"
android:textAlignment="textEnd"
android:textSize="14sp" />
<TextView
android:id="#+id/isp_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/isp"
android:textAlignment="textStart" />
<Button
android:id="#+id/isp_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/isp_button" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
And here's my DashboardFragment.kt. This is part of the default bottom navigation activity in Android Studio, which is why a lot of the code is commented out.
package com.example.caelussidekick.ui.dashboard
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.example.caelussidekick.R
import androidx.appcompat.app.AppCompatActivity
import android.net.Uri
import kotlinx.android.synthetic.main.fragment_dashboard.*
class DashboardFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// dashboardViewModel =
// ViewModelProviders.of(this).get(DashboardViewModel::class.java)
val output = inflater.inflate(R.layout.fragment_dashboard, container, false)
// val textView: TextView = root.findViewById(R.id.text_dashboard)
// dashboardViewModel.text.observe(viewLifecycleOwner, Observer {
// textView.text = it
// })
this.parameterize_button.setOnClickListener{
val intent = Intent(activity, ParamActivity::class.java)
startActivity(intent)
}
return output
}
}
Thanks for any help! I'm honestly at a loss. I've looked on stackoverflow extensively, and have tried moving the button to the main activity, using nullable modifiers, and making it a field in the class, but nothing has worked.
Synthetic view bindings are not valid until onCreateView() returns - it doesn't know about your output inflated View until it is actually set as the view on the Fragment.
Therefore you can move your code to onViewCreated(), which is the method that happens immediately after onCreateView() (you should generally not be doing anything but inflating your view in onCreateView()):
class DashboardFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_dashboard, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
this.parameterize_button.setOnClickListener{
val intent = Intent(activity, ParamActivity::class.java)
startActivity(intent)
}
}
}
var parametrizedbtn = view.findViewById<Button>(R.id.parameterize_button)
parmetrizedbtn.setOnClickLIstener{
val intent = Intent(view.context,ParamActivity::class.java)
startActivity(intent)
}
may work for your

Integer cannot be cast to android.support.design.widget.FloatingActionButton

I am trying to access a Floating Action Button inside a fragment but for some reason, I cannot. I keep getting errors. I have tried everything and nothing seems to work. Here is the code inside my fragment:
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import com.ntx_deisgns.cyberchatter.cyberchatter.Message
import com.ntx_deisgns.cyberchatter.cyberchatter.R
import kotlinx.android.synthetic.main.groups.*
import kotlinx.android.synthetic.main.groups2.*
class groups2 : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// inflater.inflate(R.layout.groups2, container, false)
val fab = R.id.fab as FloatingActionButton
fab.setOnClickListener {
if (!mainActivityEditText.text.toString().isEmpty()){
sendData()
}else{
// Toast.makeText(this, "Please enter a message", Toast.LENGTH_SHORT).show()
}
}
return inflater.inflate(R.layout.groups2, container, false)
}
private fun sendData(){
val editText = groupInput
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("message")
myRef.setValue(Message(editText.text.toString()))
val mDatabase: DatabaseReference? = null
mDatabase?.
child("messages")?.
child(java.lang.String.valueOf(System.currentTimeMillis()))?.
setValue(Message(editText.text.toString()))
//clear the text
editText.setText("")
}
companion object {
fun newInstance(): groups2 = groups2()
}
}
What am I doing wrong? Why is it so hard to access a setOnClickListener within a fragment?
UPDATE:
Here's my groups2.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/groups2_relative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="60dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="55dp"
tools:context="com.ntx_deisgns.cyberchatter.cyberchatter.MainActivity">
<android.support.design.widget.FloatingActionButton
android:id="#+id/myFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_send_black_24dp"
android:tint="#android:color/white"
app:fabSize="mini" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="#id/myFab">
<EditText
android:id="#+id/groupInput"
android:layout_width="match_parent"
android:layout_height="57dp"
android:hint="Please enter your text here" />
</android.support.design.widget.TextInputLayout>
<ListView
android:id="#+id/list_of_messages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/myFab"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="16dp"
android:divider="#android:color/transparent"
android:dividerHeight="16dp" />
</RelativeLayout>
You need to inflate the view before calling findViewById on it. Accessing the floating action button before inflation is causing the null pointer exception.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//inflate and store view
val view = inflater.inflate(R.layout.groups2, container, false)
val fab = view.findViewById(R.id.fab) as FloatingActionButton
//If using kotlinx then above line is not needed
fab.setOnClickListener {
//do your thing...
}
return view
}

Categories

Resources