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
}
Related
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.
I have faced the problem that my application will keep stopping when clicking search page fragments. I do not understand why this problem will happen? I directly used my other success code in another fragment but in this fragment suddenly appear this problem. Can somebody help me? Thank you for your help!!
My problem error :
java.lang.NullPointerException: Attempt to invoke virtual method
'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)'
on a null object reference at com.example.assignment_mad.Search_Page_Fragment.onViewCreated(Search_Page_Fragment.kt:153)
My main frgment ( Search_Page_Fragment ) :
package com.example.assignment_mad
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.fragment_notification_.*
class Search_Page_Fragment : Fragment() {
private lateinit var newRecyclerView: RecyclerView
private lateinit var newArrayList: ArrayList<Company_Search>
private lateinit var tempArrayList: ArrayList<Company_Search>
lateinit var imageId:Array<Int>
lateinit var job_name:Array<String>
lateinit var saveicon:Array<Int>
lateinit var company_name:Array<String>
lateinit var place:Array<String>
lateinit var salary:Array<String>
lateinit var news:Array<String>
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<Search_Page_Adapter.MyViewHolder>? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var views =inflater.inflate(R.layout.fragment_search__page_, container, false)
newRecyclerView=views.findViewById(R.id.recyclerView_Search)
// Inflate the layout for this fragment
return views
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
imageId= arrayOf(
R.drawable.company_logo_1,
R.drawable.company_logo_2,
R.drawable.company_logo_3,
R.drawable.company_logo_4,
R.drawable.company_logo_5,
R.drawable.company_logo_6,
R.drawable.company_logo_7,
R.drawable.company_logo_8,
R.drawable.company_logo_9,
R.drawable.company_logo_10
)
job_name= arrayOf(
"Engineer",
"Computer",
"Coder",
"Teacher",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer"
)
saveicon= arrayOf(
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24
)
company_name= arrayOf(
"Phonix Sdn Bhd",
"Computer Sdn Bhd",
"Coder",
"Teacher",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer"
)
place= arrayOf(
"Kuala Lumpur",
"Kuala Lumpur",
"Selangor",
"Rimbunan",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur"
)
salary= arrayOf(
"RM3000",
"RM4000",
"RM3500",
"RM2000",
"RM1000",
"RM3000",
"RM3000",
"RM3000",
"RM3000",
"RM3000",
)
news= arrayOf(
getString(R.string.news_a),
getString(R.string.news_b),
getString(R.string.news_c),
getString(R.string.news_d),
getString(R.string.news_e),
getString(R.string.news_f),
getString(R.string.news_g),
getString(R.string.news_h),
getString(R.string.news_i),
getString(R.string.news_j)
)
newArrayList= arrayListOf<Company_Search>()
tempArrayList= arrayListOf<Company_Search>()
getUserdata()
super.onViewCreated(itemView, savedInstanceState)
newRecyclerView.apply {
layoutManager= LinearLayoutManager(activity)
newRecyclerView.setHasFixedSize(true)
}
recyclerView.apply {
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager= LinearLayoutManager(activity)
// set the custom adapter to the RecyclerView
adapter = Search_Page_Adapter(newArrayList)
}
}
private fun getUserdata() {
for (i in imageId.indices){
val companySearch=Company_Search(imageId[i],job_name[i],saveicon[i],company_name[i],place[i],salary[i])
newArrayList.add(companySearch)
}
// tempArrayList.addAll(newArrayList)
//
// val adapter = Notification_Fragment(tempArrayList)
var adapter=Search_Page_Adapter(newArrayList)
newRecyclerView.adapter=adapter
adapter.setOnItemClickListener(object :Search_Page_Adapter.onItemClickListener{
override fun onItemClick(position: Int) {
Toast.makeText(context,"You clicked in item no . $position",Toast.LENGTH_SHORT).show()
val intent= Intent(context,Search_Page_Detail::class.java)
intent.putExtra("name",newArrayList[position].job_name)
intent.putExtra("imageId",newArrayList[position].titleImage)
intent.putExtra("news",news[position])
startActivity(intent)
}
})
}
}
The page adapter :
package com.example.assignment_mad
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.imageview.ShapeableImageView
class Search_Page_Adapter(private val companysList:ArrayList<Company_Search>):RecyclerView.Adapter<Search_Page_Adapter.MyViewHolder>() {
private var mListener:onItemClickListener?=null
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener){
mListener=listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView=LayoutInflater.from(parent.context).inflate(R.layout.list_item_search,parent,false)
return MyViewHolder(itemView,mListener)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem=companysList[position]
holder.titleImage.setImageResource(currentItem.titleImage)
holder.job_name.text=currentItem.job_name
holder.save_icon.setImageResource(currentItem.save_icon)
holder.company_name.text=currentItem.company_name
holder.place.text=currentItem.place
holder.salary.text=currentItem.salary
}
override fun getItemCount(): Int {
return companysList.size
}
//to insert the post detail
class MyViewHolder(itemView: View,listener: onItemClickListener?):RecyclerView.ViewHolder(itemView){
val titleImage:ShapeableImageView=itemView.findViewById(R.id.title_image2)
val job_name:TextView=itemView.findViewById(R.id.job_name)
val save_icon:ShapeableImageView=itemView.findViewById(R.id.save_icon)
val company_name:TextView=itemView.findViewById(R.id.company_name)
val place:TextView=itemView.findViewById(R.id.detail_place)
val salary:TextView=itemView.findViewById(R.id.detail_salary)
init {
itemView.setOnClickListener{
listener?.onItemClick(adapterPosition)
}
}
}
}
The xml file for Search_Page_Fragment :
<?xml version="1.0" encoding="utf-8"?>
<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"
android:background="#color/white"
tools:context=".Search_Page_Fragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search Job"
android:inputType="text"
android:minHeight="48dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/place_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Area, City or Town"
android:textSize="16sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/search_bar"
app:layout_constraintStart_toStartOf="parent"/>
<Spinner
android:id="#+id/spinner_job"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/place_name" />
<TextView
android:id="#+id/job_specialize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Job Specialize"
android:textSize="16sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/search_bar"
app:layout_constraintEnd_toEndOf="parent" />
<Spinner
android:id="#+id/spinner_place"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200dp"
app:layout_constraintTop_toBottomOf="#+id/job_specialize"
app:layout_constraintEnd_toEndOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView_Search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="108dp"
app:layout_constraintTop_toBottomOf="#+id/spinner_job"
tools:layout_editor_absoluteX="-16dp"
tools:listitem="#layout/list_item_search" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
The list_item_search_xml :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="8dp">
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/title_image2"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="#style/RoundCorner"
android:src="#drawable/company_logo_1"/>
<TextView
android:id="#+id/job_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/blue"
android:text="Gradute Engineer"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_image2"/>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:id="#+id/save_icon"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_image2"
android:layout_marginEnd="32dp"
app:shapeAppearanceOverlay="#style/RoundCorner"
android:src="#drawable/ic_baseline_bookmark_added_24"/>
<TextView
android:id="#+id/company_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Neric Compat"
android:textSize="18sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/job_name"/>
<TextView
android:id="#+id/detail_place"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Petaling Jaya"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/company_name"/>
<TextView
android:id="#+id/detail_salary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="MYR 3,700 - 4,300 /Month"
android:textSize="16sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/detail_place"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="8dp"
style="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/detail_salary"
android:background="#color/underline"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Your NullPointerException indicates that when this line of code is reached...
layoutManager= LinearLayoutManager(activity)
...that your newRecyclerView is null. Are you sure that you have the right resource ID here when you attempt to set it?
newRecyclerView=views.findViewById(R.id.recyclerView_Search)
Try using the debugger and set a breakpoint on these two lines to confirm is newRecyclerView is indeed null.
You must assign the RecyclerView a LayoutManager. Since you have both of them, place this line as the last statement of recyclerView.apply { … } block(s):
setLayoutManager(layoutManager)
// ↑↑↑↑↑↑↑↑↑↑↑↑↑
// Your LayoutManager
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 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 faced a strange problem : I can't add more than one object dynamically on a LinearLayout , if they were already things , that works, So That can display multiple views
I tried with different views , there is only problems when i try to push one after the other
(there is two buttons in index 0 and 1 to test for multiple objects on the layout)
CODE :
val view = layoutInflater.inflate(R.layout.sensor_item, container, false)
val view2 = layoutInflater.inflate(R.layout.nosensor_item, container, false)
val insertPoint = viewOfLayout.findViewById(R.id.box_Parent) as LinearLayout
insertPoint.addView(view, 2)
//insertPoint.addView(view2, 3) //works
This Works too :
//insertPoint.addView(view, 3)
insertPoint.addView(view2, 2) //works
This doesn't works :
insertPoint.addView(view, 2)
insertPoint.addView(view2, 3) //doesn't works
Full Code (fragments.kt):
package com.corrupted.radheat.TEMPER
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import kotlinx.android.synthetic.main.sensor_item.view.*
class EditFragment : Fragment() {
lateinit var option : Spinner
lateinit var result : TextView
private lateinit var viewOfLayout: View
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewOfLayout = inflater.inflate(R.layout.edit_fragment, container, false)
//create a view to inflate the layout_item (the xml with the textView created before)
val view = layoutInflater.inflate(R.layout.sensor_item, container, false)
val view2 = layoutInflater.inflate(R.layout.nosensor_item, container, false)
val insertPoint = viewOfLayout.findViewById(R.id.box_Parent) as LinearLayout
insertPoint.addView(view, 2)
insertPoint.addView(view2, 3)
option = view.spinner as Spinner
result = view.textView7 as TextView
val options = arrayOf("A","V")
option.adapter = ArrayAdapter<String>(activity,android.R.layout.simple_list_item_1,options)
option.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
result.text = "0"
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
result.text = options[position]
}
}
return viewOfLayout
}
class InfoFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.info_fragment, container, false)
}
}
class ParamsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.parameters_fragment, container, false)
}
}
Code of the fragment :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:id="#+id/box_Parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
Code of the added view :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:fillViewport="true"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
android:background="#color/background_Item_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView9"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:text=".0 C°"
android:textColor="#color/Text_Color_Light"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/textView8"
app:layout_constraintStart_toEndOf="#+id/textView8"
app:layout_constraintTop_toTopOf="#+id/textView8"
app:layout_constraintVertical_bias="0.625" />
<TextView
android:id="#+id/textView7"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_marginStart="4dp"
android:text=".0 C°"
android:textColor="#color/Text_Color_Light"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/textView5"
app:layout_constraintStart_toEndOf="#+id/textView5"
app:layout_constraintTop_toTopOf="#+id/textView5"
app:layout_constraintVertical_bias="0.79" />
<TextView
android:id="#+id/textView8"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="00"
android:textColor="#color/Text_Color_Light"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageButton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.937" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:text="#string/ROOMtext"
android:textColor="#color/Text_Color_Light"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:id="#+id/spinner"
android:layout_width="45dp"
android:layout_height="43dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="8dp"
android:background="#color/UI_ITEM_OVERLAP_LIGHT"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/imageButton"
android:layout_width="40dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_keyboard_arrow_up_black_24dp" />
<ImageButton
android:id="#+id/imageButton3"
android:layout_width="40dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageButton"
app:srcCompat="#drawable/ic_keyboard_arrow_down_black_24dp" />
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="00"
android:textColor="#color/Text_Color_Light"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.652" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
MainActivity.kt :
package com.corrupted.radheat.TEMPER
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.design.widget.BottomNavigationView
import android.support.v4.app.Fragment
import android.widget.*
class MainActivity : AppCompatActivity() {
private val fragmentManager = supportFragmentManager
private val fragmentTransaction = fragmentManager.beginTransaction()
private val editfragment = EditFragment()
private val infofragment = InfoFragment()
private val parametersfragment = ParamsFragment()
private fun showFragment(fragment: Fragment) {
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit()
}
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.action_edit -> {
showFragment(editfragment)
return#OnNavigationItemSelectedListener true
}
R.id.action_info-> {
showFragment(infofragment)
return#OnNavigationItemSelectedListener true
}
R.id.action_Settings-> {
showFragment(parametersfragment)
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fragmentTransaction.add(R.id.fragment_container, infofragment)
fragmentTransaction.commit()
setContentView(R.layout.activity_main)
val navigation = findViewById<BottomNavigationView>(R.id.activity_main_bottom_navigation)
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
// Create a GLSurfaceView instance and set it
// as the ContentView for this Activity.
}
}
Pic of it working : https://imgur.com/gallery/mLb4G5b
Thanks