I tried creating a simple database in which i can add a product. delete products, and search.
I followed a tutorial on a book as i am a beginner in kotlin and android studio.
Here is the Manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.RoomDemo"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
Here is my main activity :
package com.ebookfrenzy.roomdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import com.ebookfrenzy.roomdemo.ui.main.MainFragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
}
here is the fragmentmain.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.main.MainFragment">
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<TextView
android:id="#+id/productID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/product_id"
android:textSize="18sp" />
<TextView
android:id="#+id/text_not_assigned"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/not_assigned"
android:textSize="18sp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/product_name"
android:textSize="18sp" />
<EditText
android:id="#+id/productName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="none"
android:text=""
android:textSize="18sp"
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/product_quantity"
android:textSize="18sp" />
<EditText
android:id="#+id/productQuantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:textSize="18sp"
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" />
</TableRow>
</TableLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center_horizontal"
android:orientation="horizontal">
<Button
android:id="#+id/addButton"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/add"
android:textColor="#color/black" />
<Button
android:id="#+id/findButton"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Find"
android:textColor="#color/black" />
<Button
android:id="#+id/deleteButton"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/delete"
android:textColor="#color/black" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:baselineAligned="false" />
</LinearLayout>
</LinearLayout>
Finally, here is the logcat (only errors) :
2023-01-18 20:14:36.108 1950-1950/com.ebookfrenzy.roomdemo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ebookfrenzy.roomdemo, PID: 1950
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ebookfrenzy.roomdemo/com.ebookfrenzy.roomdemo.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3676)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
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:2308)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.NullPointerException
at com.ebookfrenzy.roomdemo.ui.main.MainFragment.getBinding(MainFragment.kt:32)
at com.ebookfrenzy.roomdemo.ui.main.MainFragment.listenerSetup(MainFragment.kt:65)
at com.ebookfrenzy.roomdemo.ui.main.MainFragment.onCreate(MainFragment.kt:44)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2981)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:474)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:257)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1758)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1670)
at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:317)
at com.ebookfrenzy.roomdemo.MainActivity.onCreate(MainActivity.kt:16)
at android.app.Activity.performCreate(Activity.java:8290)
at android.app.Activity.performCreate(Activity.java:8269)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3657)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
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:2308)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
as requested, here is the mainFragment file:
import androidx.lifecycle.ViewModelProvider
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import com.ebookfrenzy.roomdemo.ProductRepository
import com.ebookfrenzy.roomdemo.MainActivity
import com.ebookfrenzy.roomdemo.ProductDao
import com.ebookfrenzy.roomdemo.ui.main.ProductListAdapter
import android.view.ViewGroup
import com.ebookfrenzy.roomdemo.R
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.ebookfrenzy.roomdemo.Product
import androidx.fragment.app.viewModels
import java.util.*
import com.ebookfrenzy.roomdemo.databinding.FragmentMainBinding
//preparation du main fragment
class MainFragment : Fragment() {
private var adapter: ProductListAdapter? = null
companion object {
fun newInstance() = MainFragment()
}
val viewModel: MainViewModel by viewModels()
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
// si ya une erreur c'est ici
private fun recyclerSetup(){
adapter = ProductListAdapter(R.layout.product_list_item)
binding.recyclerView.layoutManager = LinearLayoutManager(context)
binding.recyclerView.adapter = adapter
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
listenerSetup()
observerSetup()
recyclerSetup()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
return binding.root
}
private fun clearFields() {
binding.productID.text = ""
binding.productName.setText("")
binding.productQuantity.setText("")
}
//ajout de bouton listeners
private fun listenerSetup() {
binding.addButton.setOnClickListener {
val name = binding.productName.text.toString()
val quantity = binding.productQuantity.text.toString()
if (name != "" && quantity != "") {
val product = Product(name, Integer.parseInt(quantity))
viewModel.insertProduct(product)
clearFields()
} else {
binding.productID.text = " Infos Incompletes "
}
}
binding.findButton.setOnClickListener {
viewModel.findProduct(binding.productName.text.toString())
}
binding.deleteButton.setOnClickListener {
viewModel.deleteProduct(
binding.productName.text.toString()
)
clearFields()
}
}
private fun observerSetup() {
viewModel.getAllProducts()
?.observe(this, Observer { products -> products?.let { adapter?.setProductList(it) } })
viewModel.getSearchResults().observe(this, Observer { products ->
products?.let {
if(it.isNotEmpty()){
binding.productID.text = String .format(Locale.US, "%d", it[0].id)
binding.productName.setText(it[0].productName)
binding.productQuantity.setText(String.format(Locale.US,"%d",it[0].quantity))
}
else {
binding.productID.text = "No Match"
}
}
})
}
}
Thanks a lot for taking the time to help me !
i just tried to run the app on the android studio emulator and it displayed an error message saying : "RoomDemo keeps stoping" right after i launched the app. RoomDemo is the name of my app
The problem can be seen in the logcat extract.
Caused by: java.lang.NullPointerException
at com.ebookfrenzy.roomdemo.ui.main.MainFragment.getBinding(MainFragment.kt:32)
This makes it look like getBinding returns null at line 32 in MainFragment. You didn't post the code for MainFragment. Add this to the question for further assistance.
EDIT : Adding further information below now that MainFragment has been added to the question.
In onCreate you are doing things that will try to use the binding. But the binding hasn't been assigned yet, this happens inside onCreateView.
There is a lifecycle method for onViewCreated which will be called after onCreateView has returned. You can guarantee at this point binding will have been assigned and so invoking the various functions that are called inside onCreate in onViewCreated will prevent the null pointer exception.
You should read up on android lifecycle for an Activity, and Fragments. This will help you understand why you had the problem.
Related
Fragment onClick fails with below error
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
at android.view.View.performClick(View.java:7357)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
at android.view.View.performClickInternal(View.java:7334)
at android.view.View.access$3600(View.java:808)
at android.view.View$PerformClick.run(View.java:28200)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7478)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7357)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
at android.view.View.performClickInternal(View.java:7334)
at android.view.View.access$3600(View.java:808)
at android.view.View$PerformClick.run(View.java:28200)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7478)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
Caused by: java.lang.NullPointerException: farenheitView must not be null
at com.example.MainActivity.celsiusFunction(MainActivity.kt:68)
MainActivity:
class MainActivity : AppCompatActivity(), PostAdapter.OnPostClickListener {
private lateinit var binding: ActivityMainBinding
val dummyList = createMockData()
val adapter = PostAdapter(dummyList, this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val tempConverter = TempConverterFragment()
val recyclerView = RecyclerViewFragment()
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
val uploaderView = UploaderFragment(this)
setFragmentView(recyclerView)
binding.bottomNavBar.setOnNavigationItemSelectedListener {
when(it.itemId){
R.id.listView -> setFragmentView(recyclerView)
R.id.tempConverterView -> setFragmentView(tempConverter)
R.id.videoUploaderView -> setFragmentView(uploaderView)
}
true
}
}
private fun setFragmentView(fragment: Fragment){
supportFragmentManager.beginTransaction().apply {
replace(R.id.main_fragment_view, fragment)
//Will return to previous page when tap "Back Button" on the phone
addToBackStack(null)
commit()
}
}
override fun onEditPost(position: Int){
val clickedPost = dummyList[position]
clickedPost.title = "Updated title"
clickedPost.body = "Updated body"
adapter.notifyItemChanged(position)
}
override fun onDeletePost(position: Int) {
dummyList.removeAt(position)
adapter.notifyItemRemoved(position)
}
fun celsiusFunction(view: View){
val farenheitView = view.findViewById<EditText>(R.id.userTemp)
val farenheitValue = farenheitView.text.toString()
if(!farenheitValue.isBlank()){
val celsiusCovertedValue = (farenheitValue.toDouble() - 32) * 5/9
val celsiusValue = String.format("%.2f", celsiusCovertedValue)
Toast.makeText(this,
"$farenheitValue fahrenheit is $celsiusValue degrees celsius",
Toast.LENGTH_LONG).show()
}else {
Toast.makeText(this, "You must enter a value to convert", Toast.LENGTH_LONG).show()
}
}
fun farenheitFunction(view: View){
val celsiusView = view.findViewById<EditText>(R.id.userTemp)
val celsiusValue = celsiusView.text.toString()
if(!celsiusValue.isBlank()){
val farenheitConvertedValue = celsiusValue.toDouble() * 9/5 + 32
val farenheitValue = String.format("%.2f", farenheitConvertedValue)
Toast.makeText(this,
"$celsiusValue degrees celsius is $farenheitValue farenheit",
Toast.LENGTH_LONG).show()
}else{
Toast.makeText(this, "You must enter a value to convert", Toast.LENGTH_LONG).show()
}
}
}
And here is my tempConverter class:
class TempConverterFragment: Fragment(){
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = inflater.inflate(R.layout.fragment_temp_converter, container, false)
return binding
}
}
Here is my MainActivity xml file:
<?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="com.example.MainActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<FrameLayout
android:id="#+id/main_fragment_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/bottomNavBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is where I implement my TempConverter function:
<?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="com.example.MainActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="487dp"
android:layout_height="320dp"
android:layout_marginBottom="16dp"
android:adjustViewBounds="true"
android:cropToPadding="false"
android:scaleType="fitXY"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="#drawable/termometer" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="62dp"
android:layout_marginLeft="62dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="76dp"
android:layout_marginRight="76dp"
android:text="Enter desired temperature to convert"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView" />
<EditText
android:id="#+id/userTemp"
style="#android:style/Widget.DeviceDefault.EditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="140dp"
android:layout_marginLeft="140dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="140dp"
android:layout_marginRight="140dp"
android:ems="10"
android:hint="Enter Temperature Here"
android:inputType="numberDecimal"
android:selectAllOnFocus="false"
android:singleLine="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView" />
<Button
android:id="#+id/celsiusButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="70dp"
android:layout_marginLeft="70dp"
android:layout_marginTop="32dp"
android:onClick="celsiusFunction"
android:text="to Celsius"
app:backgroundTint="#color/purple_200"
app:layout_constraintEnd_toStartOf="#+id/farenheitButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/userTemp" />
<Button
android:id="#+id/farenheitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="41dp"
android:layout_marginLeft="41dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="72dp"
android:layout_marginRight="72dp"
android:onClick= "farenheitFunction"
android:text= "to Farenheit"
app:backgroundTint="#color/teal_200"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/celsiusButton"
app:layout_constraintTop_toBottomOf="#+id/userTemp" />
</androidx.constraintlayout.widget.ConstraintLayout>
So my app layout have a BottomNavBar. And each Navbar have it's own fragment. One is a RecyclerView, a TempConverter view and ImageUploader view. How to implement the fragment activity correctly and what is wrong with my code?
from the logcat you can see that it says your farenheitView is null and that's waht causing the error. Now as per the xml and your MainActivity it's clear that you have your farenheitView in your fragment but you are trying to get that in your MainActivity which is the reason you are getting null value there.
Instead what you need to do is you need to have your functions of the fragments inside your fragment class only and not in your mainActivity class and you can call them wherever you need in that fragment.
Also I would suggest you to use bindings in your fragments as well as i can see you have already used that in your mainActivity.
You can learn more about Fragments here and here (Also there are tons of other blogs and tutorials out there).
Happy Coding !
I'm trying to make a quiz app where on the homepage you click the + button and it takes you to a new page where you input the title of the quiz. Once you click the check button it takes you back to the homepage and the new quiz in the form of a button is created there. However, when I try to use the id for the layout from my mainactivity it returns as null and when the app crashes when I click the check button. Does anyone have any idea how I can fix this?
Second activity:
package com.example.k_ari
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Gravity
import android.widget.Button
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.Toast
import com.google.android.material.floatingactionbutton.FloatingActionButton
class Page2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_page2)
val button = Button(this#Page2)
button.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
val txtt = findViewById<EditText>(R.id.txt)
val textmessage: String = txtt.text.toString()
button.setText(textmessage)
val message = "New quiz created"
val toast1= Toast.makeText(applicationContext, message, Toast.LENGTH_LONG)
toast1.setGravity(Gravity.CENTER, 0,0)
val layout = findViewById<LinearLayout>(R.id.mainlayout)
val btn = findViewById<FloatingActionButton>(R.id.floatingActionButton2)
btn.setOnClickListener{
layout.addView(button)
toast1.show()
val intent = Intent(this#Page2, MainActivity::class.java)
startActivity(intent)
}
}
}
Second activity xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="#+id/secondlayout"
android:orientation="vertical"
tools:context=".Page2">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#99141414"
android:backgroundTint="#180030"
android:gravity="center_horizontal"
android:padding="20dp"
android:text="Enter the title:"
android:textAlignment="center"
android:textColor="#DADADA"
android:textSize="35sp"
android:textStyle="bold"
android:translationX="50dp"
android:translationY="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.433"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.112" />
<EditText
android:id="#+id/txt"
android:layout_width="361dp"
android:layout_height="67dp"
android:autofillHints="title"
android:background="#99141414"
android:backgroundTint="#180030"
android:hint="title"
android:inputType="text"
android:padding="10dp"
android:textColor="#DADADA"
android:textColorHint="#9ADCDCDC"
android:textSize="28sp"
android:translationX="25dp"
android:translationY="170dp"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:contentDescription="#string/todo"
android:focusable="true"
android:translationX="300dp"
android:translationY="400dp"
app:backgroundTint="#180030"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
Main activity:
package com.example.k_ari
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val floatingActionButton = findViewById<FloatingActionButton>(R.id.btn)
floatingActionButton.setOnClickListener{
val intent = Intent(this, Page2::class.java)
startActivity(intent)
}
}
}
Main activity xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="#+id/mainlayout"
android:orientation="vertical"
android:layout_gravity="center"
tools:context=".MainActivity">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:backgroundTint="#250A43"
android:backgroundTintMode="add"
android:clickable="true"
android:contentDescription="#string/todo"
android:tint="#250A43"
android:translationX="280dp"
android:translationY="580dp"
app:backgroundTint="#250A43"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.56"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:rippleColor="#FFFFFF"
app:srcCompat="#android:drawable/ic_input_add"
android:focusable="true" />
</LinearLayout>
Logcat:
2020-12-23 15:32:03.599 1474-1474/com.example.k_ari E/Toast: setGravity() shouldn't be called on text toasts, the values won't be used
2020-12-23 15:32:05.482 1474-1474/com.example.k_ari E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.k_ari, PID: 1474
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.LinearLayout.addView(android.view.View)' on a null object reference
at com.example.k_ari.Page2$onCreate$1.onClick(Page2.kt:35)
at android.view.View.performClick(View.java:8178)
at android.view.View.performClickInternal(View.java:8147)
at android.view.View.access$3700(View.java:888)
at android.view.View$PerformClick.run(View.java:30233)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8414)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:596)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
You cannot access a View from the Activity that does not hold it.
to handle data between activities like this, you should read about ViewModel and/or SharedPreferences
https://developer.android.com/topic/libraries/architecture/viewmodel
https://developer.android.com/reference/android/content/SharedPreferences
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
}
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
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