E/RecyclerView: No adapter attached; skipping layout in kotlin - kotlin

** I want to know what mistake i did so occure its error please tell meWhat solution of this error can anyone tell me how to fix this problem :E/RecyclerView: No adapter attached; skipping layout,i couldn't solve yet please tell me how i fix this error...........................................................................................................................................**
search.xml
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/app_bar_layout_search"
android:visibility="gone">
</androidx.recyclerview.widget.RecyclerView>
search.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view=inflater.inflate(R.layout.fragment_search, container, false)
recyclerView=view.findViewById(R.id.recycler_view_search)
recyclerView?.setHasFixedSize(true)
recyclerView?.layoutManager=LinearLayoutManager(context)
mUser=ArrayList()
userAdapter=context?.let{ UserAdapter(it,mUser as
ArrayList<User>,true) }
recyclerView?.adapter=userAdapter
view.search_edit_text.addTextChangedListener(object: TextWatcher{
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
TODO("Not yet implemented")
}

Try adding "RecyclerView.VERTICAL, false" to your LinearLayoutManager initialization as follow
LinearLayoutManager(context, RecyclerView.VERTICAL, false)
also make sure your adapter is initialized properly (try adding a Log after your useAdapter initialization)

<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_hashtags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="horizontal"
tools:listitem="#layout/item_trending"/
Check the context which you are using. If its null the adapter might not get attached and the above error might occur
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" This line can help you get rid of the above error.

Related

Need MotionLayout Reference using DataBinding Tree

I'm trying to get the reference to my MotionLayout inside a Fragment inside my RecyclerView so that I can attach my addTransitionListener. I've got the listener prepared, but I don't know the valid path to this object.
I've seen many great examples that reference motionLayout vars, but I can't seem to get a valid one using DataBinding methods.
My RecyclerView is inside my Fragment as:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/shipper_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:background="#color/mainList"
tools:listitem="#layout/row_shipper_line"
/>
My MotionLayout is inside my "row_shipper_line" as:
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/line_container"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#color/mainList"
app:layoutDescription="#xml/row_shipper_line_container_scene"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
My binding var is set as:
binding = DataBindingUtil.inflate(
inflater,
R.layout.create_shipper_fragment,
container,
false
)
I've got this code entered and it compiles, but the events aren't called:
rec = LayoutInflater.from(context).inflate(R.layout.shipper_list, null)
ml = rec.findViewById(R.id.line_container)
var transitionListener = object : MotionLayout.TransitionListener {
override fun onTransitionStarted(p0: MotionLayout?, startId: Int, endId: Int) {
Log.d("MyApp", "Transition onTransitionStarted.")
}
override fun onTransitionChange(
p0: MotionLayout?,
startId: Int,
endId: Int,
progress: Float
) {
Log.d("MyApp", "Transition onTransitionChange.")
}
override fun onTransitionCompleted(p0: MotionLayout?, currentId: Int) {
Log.d("MyApp", "Transition onTransitionCompleted.")
}
override fun onTransitionTrigger(
p0: MotionLayout?,
triggerId: Int,
positive: Boolean,
progress: Float
) {
Log.d("MyApp", "Transition onTransitionTrigger.")
}
}
ml.setTransitionListener(transitionListener)
My line swipes LEFT perfectly. I just need to listen for onTransitionComplete.
My binding tree looks like this:
Fragment containing my RecyclerView -> Row Layout containing the MotionLayout tag.
What I'm trying to do is something like this:
binding.shipper_list.line_container
Thank you in advance!

Kotlin, embed root_preferences in existing fragment

Kotlin, I want to embed root_preferences.xml in a fragment with existing content. I navigate using <navigation..> I want to embed the preferences like this:
// ... existing items
<include
android:id="#+id/summaryPrefs"
layout="#layout/fragment_container_settings"
/>
// ... more items here
What I did
Create new Settings Fragment. This does NOT create a layout file, but an XML file at res/xml/root_preferences.xml, make no changes to code.
Create a 'container fragment' new Fragment (Blank) name it, ContainerSettingsFragment. it creates the layout file fragment_container_settings.
Delete code in class ContainerSettingsFragment and replace with this:
// Make a container fragment that holds the preference xml.
class ContainerSettingsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_container_settings, container, false)
requireActivity().supportFragmentManager
.beginTransaction()
.replace(
R.id.settings, // this is the id in fragment_container_settings <FrameLayout>
SettingsFragment() // SR: ?? This loads the XML into this fragment
)
.commit()
// Inflate the layout for this fragment
return view
}
}
Replaced code in fragment_container_settings with this:
FrameLayout
android:id="#+id/settings"
android:layout_width="250dp"
android:layout_height="300dp"
Expected result: FrameLayout #+id/settings displays the contents of root_preferences
Actual: Size is 250dp x250dp but none of the items are displayed
Was easy, if using nav_graph, don't mix with .supportFragmentManager
I removed all the code in the container settings fragment.
): View? {
return inflater.inflate(R.layout.fragment_container_settings, container, false)
}
Completed layout in fragment_container_settings.xml
<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:id="#+id/settingsSummary"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.settingssummary.ContainerSettingsFragment">
</androidx.constraintlayout.widget.ConstraintLayout>
Used include to add to fragment_settings_summary

Unresolved reference in findViewById when using Glide in Fragment in Kotlin

I am new to Kotlin. I have an "unresolved reference:findViewByid" when I am using Fragment. I try to add "view?.findViewByid", but the app crashed and val imgUniverse returns "null". Is there a way to solve it?. Thanks.
I am trying to implement swipe pictures on different xml on multiple screens using PageViewer2.
KC
class Page1Fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val imgUniverse = findViewById<ImageView>(R.id.image_universe) // Unresolved reference in findViewById
val imgFooter = findViewById<ImageView>(R.id.image_footer) // Unresolved reference in findViewById
Log.d("testing2: " , imgUniverse.toString())
Glide.with(this)
.load(R.drawable.universe3)
.fitCenter()
.centerCrop()
.into(imgUniverse!!)
Glide.with(this)
.load(R.drawable.footer)
.fitCenter()
.centerCrop()
.into(imgFooter!!)
return inflater.inflate(R.layout.fragment_page1, container, false)
}
}
You are searching for views before you are inflating (creating) them. The view is created in the last line with by inflating it using inflater.inflate(). Before that, none of the views even exists and therefore cannot be found and used.
Move all the code (except for the last line) into onViewCreated() and it will work.

OnClickListener for multiple buttons does not work

I searched here fo a solution and on google but it doesn't work for me and I can't understand why.
I did everything like in this solution: Multiple OnClickListener in Kotlin
XML Code:
<?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=".MainActivity">
<Button
android:id="#+id/btnP1"
android:layout_width="60dp"
android:layout_height="54dp"
android:layout_marginTop="200dp"
android:fontFamily="sans-serif-medium"
android:shape="rectangle"
android:text="1"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold"
app:backgroundTint="#98BFD1"
app:layout_constraintEnd_toStartOf="#+id/btnP2"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtDart1"
tools:text="1" />
<Button
android:id="#+id/btnP2"
android:layout_width="60dp"
android:layout_height="54dp"
android:layout_marginTop="334dp"
android:shape="rectangle"
android:text="2"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold"
app:backgroundTint="#98BFD1"
app:layout_constraintEnd_toStartOf="#+id/btnP3"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/btnP1"
app:layout_constraintTop_toTopOf="parent"
tools:text="2" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt:
package com.example.test
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity(), View.OnClickListener {
private var toast: Toast? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnP1.setOnClickListener(this)
btnP2.setOnClickListener(this)
}
override fun onClick(view: View?)
{
when ( view!!.id)
{
TODO()
}
}
private fun myToast(string: String)
{
toast = Toast.makeText(this,string,Toast.LENGTH_SHORT)
toast?.show()
}
}
Problem: btnP1.setOnClickListener(this) and btnP2.setOnClickListener(this)
-> btnP1 and btnP2 are always red -> "unresolved reference"
Why does it work for everyone but not in my case?
Thank you!
At Build.gardle(app)
ADD
plugins {
id 'kotlin-android-extensions'
}
or
apply plugin: 'kotlin-android-extensions'
depends on your version. and then sync
After that you would be able to use your button or whatever without using findViewById
if you still don't find it.
make sure to import this at your KotlinFile
***normally it will import auto after you type the id name like in your case btnP1 ***
import kotlinx.android.synthetic.main.YOUR_XML_FILE_NAME.* (Don't forget *)
example
import kotlinx.android.synthetic.main.activity_main.*
more info https://antonioleiva.com/kotlin-android-extensions/
What you have declared in the XML is not automatically available in your code.
You have not defined or declared the btnP1 and btnP2 in your Kotlin code, and therefore compiler does not know what to refer to, hence the error
Use findViewById to obtain a reference to your buttons
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val btnP1 = findViewById<Button>(R.id.btnP1)
val btnP2 = findViewById<Button>(R.id.btnP2)
btnP1.setOnClickListener(this)
btnP2.setOnClickListener(this)
}
You can read more about this method here

Viewmodel SavedStateHandle data lost after process death

I am trying to use savedStateHandle in my ViewModel and test it. My simple case is that I'm just storing an Int value in the SavedStateHandle and trying to get it again after the process death. But its not working at all. I am using the following dependency
implementation 'androidx.activity:activity-ktx:1.2.0-alpha08'
implementation "androidx.fragment:fragment-ktx:1.3.0-alpha08"
Below is my Fragment which is having one button and one TextView. When I click the button, number 5 is stored in the savedStateHandle of the ViewModel and then the same was observed via the getLiveData method of the savedStateHandle and the number is displayed in the TextView. So, after process death, it should correctly restore the value of 5 and display it in the text view. Following is my fragment code
class FirstFragment : Fragment() {
private val viewModel by lazy{
ViewModelProvider(this).get(FirstFragmentVM::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
button_first.setOnClickListener {
viewModel.rememberNumber(5)
}
observeViewModel()
}
private fun observeViewModel(){
viewModel.rememberedNumber.observe(viewLifecycleOwner){
textview_first.text = it.toString()
}
}
}
and the following is my ViewModel code
#ExperimentalCoroutinesApi
#FlowPreview
class FirstFragmentVM(savedStateHandle: SavedStateHandle) : ViewModel() {
companion object{
private const val KEY_NUMBER_TO_REMEMBER="number:to:remember"
}
private val savedState=savedStateHandle
val rememberedNumber=savedState.getLiveData<Int>(KEY_NUMBER_TO_REMEMBER)
fun rememberNumber(number:Int){
savedState.set(KEY_NUMBER_TO_REMEMBER,number)
}
}
When run this app and click the button, the number 5 is stored in the savedStateHandle and its displaying "5" correcly in the text view. But when I put the app in the background and kill the process using adb and then restart the process from the recent screen, the entire app is restarted and its not showing the remembered number in the textView. Instead, its showing "Hello" which I set in the layout xml. I am killing the process as follows
adb shell
am kill <package name>
Anyone kindly help me why its not at all working for me? What am I doing wrong here?
Finally, I found the reason. The app restarts if we kill the app process after launching it directly from the IDE. Instead, If I close the app by swiping it from recents, launch it from the app drawer and then killing it via adb works and restores the state of the app perfectly.