Issue
The button simply doesn't work in the app i tried useing the synthitec plugin, databinding, and even findviewbyId() but it simply doesn't work this is the Fragment class->
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import com.enternal.weapp.databinding.FragmentAddPostBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_add_post.*
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.coroutines.NonDisposableHandle.parent
class AddPostFragment : Fragment() {
private lateinit var auth: FirebaseAuth
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val vieww:View = inflater.inflate(R.layout.fragment_add_post, container, false)
val buttonpost = view.findViewById<Button>(R.id.post_button)
val binding = FragmentAddPostBinding.inflate(layoutInflater)
buttonpost?.setOnClickListener{
Toast.makeText(activity, "Clicked!", Toast.LENGTH_SHORT).show()
val title = binding.editTitle.text.toString()
val description = binding.editDescription.text.toString()
addPost(title, description)
}
return vieww
}
private fun addPost(title: String, description: String) {
val post = Post(title, description)
val userId= auth.currentUser?.uid
val ref= Firebase.database.getReference("/posts/$userId")
ref.setValue(post)
}
}
class Post(val title:String, val description:String)
And this is The layout file ->
<FrameLayout 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=".AddPostFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/edit_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:ems="10"
android:inputType="textPersonName"
android:minHeight="48dp"
android:text="Title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/edit_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="96dp"
android:ems="10"
android:inputType="textPersonName"
android:minHeight="48dp"
android:text="Description"
app:layout_constraintEnd_toEndOf="@+id/edit_title"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="@+id/edit_title"
app:layout_constraintTop_toBottomOf="@+id/edit_title" />
<Button
android:id="@+id/post_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="post"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/edit_description"
app:layout_constraintStart_toStartOf="@+id/edit_description"
app:layout_constraintTop_toBottomOf="@+id/edit_description"
app:layout_constraintVertical_bias="0.211" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
i even redid the whole app but it still doesn't work THERE IS NO ERRORS IN THE LOGCAT AND THE APP DOSENT CRASH I TRIED EVERYTHING PLEASE HELP!!!
Solution
You're calling findViewById()
on the nullable view
property of the fragment. There is no view
yet because you're still in the middle of creating the View in the onCreateView
function. You should call findViewById
on the view you inflated, vieww
.
However, you should be doing this in onViewCreated()
instead of onCreateView()
, which is the intended way to use the lifecycle stages. You can pass the layout ID in the super-constructor call to make this more concise.
Here are two different solutions:
// Without view binding:
class AddPostFragment : Fragment(R.layout.fragment_add_post) {
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
val buttonpost = view.findViewById<Button>(R.id.post_button)
buttonpost.setOnClickListener{
Toast.makeText(it.context, "Clicked!", Toast.LENGTH_SHORT).show()
val title = binding.editTitle.text.toString()
val description = binding.editDescription.text.toString()
addPost(title, description)
}
}
private fun addPost(title: String, description: String) {
// ...
}
}
// With view binding:
class AddPostFragment : Fragment(R.layout.fragment_add_post) {
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
val binding = FragmentAddPostBinding.bind(view)
binding.buttonpost.setOnClickListener{
Toast.makeText(it.context, "Clicked!", Toast.LENGTH_SHORT).show()
val title = binding.editTitle.text.toString()
val description = binding.editDescription.text.toString()
addPost(title, description)
}
}
private fun addPost(title: String, description: String) {
// ...
}
}
My recommendation is, if you expect a function to always be called, like setOnClickListener
, you should not put a null-safe ?.
call in front of it. Instead, rethink your strategy. If you are calling it on something nullable, but you expect it to always to work, that should be a sign that you are following the wrong approach. In this case, it would have indicated that you are calling it on the wrong property and/or at the wrong stage of the lifecycle.
Answered By - Tenfour04
Answer Checked By - Clifford M. (JavaFixing Volunteer)