How to show recyclerview in fragment after click on search field? - android-studio

How to make my recicle view visible on search field click in fragment and how to set search in this View?
Logcat shows, that "No adapter attached; skipping layout"
Code of home_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="8dp">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="330dp"
android:layout_height="30dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="62dp"
android:layout_height="match_parent"
android:src="#drawable/ic_baseline_search_24" />
<EditText
android:id="#+id/searchField"
android:layout_width="270dp"
android:layout_height="60dp"
android:ems="10"
android:hint="Поиск"
android:inputType="textPersonName"
tools:ignore="SpeakableTextPresentCheck" />
<ListView
android:id="#+id/listSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="#layout/list_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
Code of HomeFragment
package com.example.booksh
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.booksh.databinding.FragmentHomeBinding
class HomeFragment: Fragment(R.layout.fragment_home) {
private lateinit var binding: FragmentHomeBinding
private lateinit var newRecyclerView: RecyclerView
private lateinit var newArrayList: ArrayList<Books>
lateinit var imageId: Array<Int>
lateinit var heading: Array<String>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding = FragmentHomeBinding.inflate(layoutInflater)
super.onViewCreated(binding.root, savedInstanceState)
// Поисковой список
imageId = arrayOf(
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e,
R.drawable.f,
R.drawable.h,
R.drawable.i,
R.drawable.j
)
heading = arrayOf(
"Война и мир",
"Капитанская дочка",
"Раковый корпус",
"Мастер и маргарита",
"Муму",
"О дивный новый мир",
"Скотный двор",
"Портрет Дориана Грея",
"Отель с привидениями"
)
//Переменные для выпадающего списка на главной странице - поиск книг
newRecyclerView = binding.recyclerView
newRecyclerView.layoutManager = LinearLayoutManager(this.context)
newRecyclerView.setHasFixedSize(true)
newArrayList = arrayListOf()
getUserData()
}
//Заносим в список данные о книгах
private fun getUserData() {
for (i in imageId.indices){
val book = Books(imageId[i], heading[i])
newArrayList.add(book)
}
newRecyclerView.adapter = MyAdapter(newArrayList)
}
}
Code of adapter
package com.example.booksh
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 MyAdapter(private var booksList: ArrayList<Books>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item,
parent, false)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = booksList[position]
holder.titleImage.setImageResource(currentItem.titleImage)
holder.tvHeading.text = currentItem.heading
}
override fun getItemCount(): Int {
return booksList.size
}
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val titleImage : ShapeableImageView = itemView.findViewById(R.id.list_item_icon)
val tvHeading: TextView = itemView.findViewById(R.id.list_item_text)
}
}
I made a ricycle view for main activity without visibility change, but it was shown in every fragment of my app. Then I copied all code connected with recyclerView to fragment home (xml, kt), but it became invisible whether I click on the search field or not.

Related

Android studio crashing after setOnClickListener

I want to create an app to download a song from an URL.
I made a Alertbox with EditText for the URL. This seems to work fine, but as soon as I want to assign the functions to the buttons inside the Alertbox, the app crashes as soon as I click on the Button to open the alertbox and I get a Nullpointer error.
See my cod below:
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/url"
android:hint="Enter URL"
android:inputType="textPersonName"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/downloadbtn"
android:text="Download"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/pastebtn"
android:text="Paste"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/cancelbtn"
android:text="Cancel"/>
</LinearLayout>
Kotlin:
package com.example.mymusicapp
import android.annotation.SuppressLint
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.CancellationSignal
import android.view.LayoutInflater
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
//import the button didnt fix it: import com.example.mymusicapp.R.id.downloadbtn
class MainActivity : AppCompatActivity() {
#SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val songbtn = findViewById<Button>(R.id.btnsong)
val downloadbtn = findViewById<Button>(R.id.downloadbtn)
val pastebtn = findViewById<Button>(R.id.pastebtn)
val cancelbtn = findViewById<Button>(R.id.cancelbtn)
songbtn.setOnClickListener{
val mDialogView = LayoutInflater.from (this). inflate(R.layout.url_dialog, null)
val mBuilder = AlertDialog.Builder(this)
.setView(mDialogView)
.setTitle("Download MP3")
val mAlertDialog = mBuilder.show()
/* as soon as I use this code, the app crashes after clicking the "btnsong":
downloadbtn.setOnClickListener {
mAlertDialog.dismiss()
}
}
}
}
You cannot access a button inside a dialog directly using findviewbyid.
val btn=mAlertDialog.findViewById<Button>(R.id.downloadbtn)
or
val builder = AlertDialog.Builder(this)
val view = layoutInflater.inflate(R.layout.custom_dialog, null)
builder.setView(view)
val dialog = builder.create()
dialog.show()
val button = dialog.findViewById<Button>(R.id.my_button)
button.setOnClickListener {
Log.d("TAG", "Clicked")
dialog.dismiss()
}

How can I pass the checked radio button value into text View in kotlin android studio?

I made a dialogue box and I put radio group in it and I add three radio button 1)male 2)female 3)others if user select male so the selected radio button male should be shown in text View
Here, I would like to share you here a simple app with both the activity and layout code. I hope this will help you.
First the layout
<?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="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="100dp"
tools:context=".TestActivity">
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:text="What is your gender?"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/txtViewGender"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:text="-- Selected Gender --"
android:textSize="16sp" />
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Select" />
</LinearLayout>
Second the Main Activity code
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class GenderActivity: AppCompatActivity() {
private lateinit var selectedGender: String
private var selectedGenderIndex: Int = 0
private val gender = arrayOf("Male", "Female", "Others")
private lateinit var txtViewGender: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test4)
txtViewGender = findViewById<TextView>(R.id.txtViewGender)
var androidButton: Button = findViewById<Button>(R.id.button)
androidButton.setOnClickListener {
showRadioDialog()
}
}
private fun showRadioDialog() {
selectedGender = gender[selectedGenderIndex]
MaterialAlertDialogBuilder(this)
.setTitle("Select your gender")
.setSingleChoiceItems(gender, selectedGenderIndex) { dialog, which ->
selectedGenderIndex = which
selectedGender = gender[which]
}
.setPositiveButton("Ok") { dialog, which ->
Toast.makeText(this, "Selected --> $selectedGender ", Toast.LENGTH_SHORT)
.show()
txtViewGender.text = selectedGender
}
.setNegativeButton("Cancel") { dialog, which ->
dialog.dismiss()
}
.show()
}
}
When you run the code, you will get the following two screens.
Screen 1
Screen 2

How to drag and drop ListView rows in Android Studio using Kotlin

I’m using Android Studio with Kotlin. I’d like to be able to drag and drop items in a ListView to reorder them. I also want to swipe left to delete. This was pretty straightforward in XCode/Swift for iOS, but I’m having trouble finding examples for Android/Kotlin. I’ve seen some fairly old discussions with Java and with RecyclerView, but it would be great to be able to do it in Kotlin with ListView. I should add that the ListView does everything I need so far – I realise there is much discussion about ListView vs RecyclerView.
I’m not asking for people to solve this for me, but it would be great if you could point me to anything that might get me going.
By way of background, here is my code. It is just a ListView with numbers ‘zero’ to ‘ten’ and the selected row highlighted. I should add that I wrote this code with the help of many discussions here and on YouTube, for which I’m very grateful.
I also have a ListView with sections that needs these options, but I’ve not put the code here for that (happy to do so if required).
activity_main.xml
<?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">
<ListView
android:id="#+id/list_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_margin="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
listview_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/rowText"
android:layout_width="match_parent"
android:layout_height="48dp"
android:textColor="#color/black"
android:paddingLeft="0dp"
android:paddingTop="8dp"
android:paddingRight="0dp"
android:paddingBottom="8dp"
android:autoSizeTextType="uniform"
android:autoSizeMaxTextSize="40sp"
android:autoSizeMinTextSize="8sp"
android:autoSizeStepGranularity="2sp"
android:lines="1" />
</LinearLayout>
listview_selected_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/selectedRowText"
android:layout_width="match_parent"
android:layout_height="48dp"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="#color/teal_200"
android:textColor="#color/black"
android:autoSizeTextType="uniform"
android:autoSizeMaxTextSize="40sp"
android:autoSizeMinTextSize="8sp"
android:autoSizeStepGranularity="2sp"
android:lines="1" />
</LinearLayout>
ListViewAdapter.kt
package com.ijmusic.listviewrearrange
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
val TYPE_LISTVIEW_ITEM = 0
val TYPE_LISTVIEW_SELECTED_ITEM = 1
class ListViewAdapter(private val context: Context): BaseAdapter() {
private val mData: ArrayList<String> = ArrayList()
private var mIndex: ArrayList<Int> = ArrayList()
private var mSelectedItem = -1
private lateinit var textView: TextView
fun addItem(item: String, index: Int) {
mData.add(item)
mIndex.add(index)
notifyDataSetChanged()
}
fun addSelectedItem(item: String, index: Int) {
mData.add(item)
mIndex.add(index)
mSelectedItem = mData.size - 1
notifyDataSetChanged()
}
fun highlightSelection(int: Int) {
mSelectedItem = int
notifyDataSetChanged()
}
override fun getItemViewType(position: Int): Int {
return if (position == mSelectedItem) TYPE_LISTVIEW_SELECTED_ITEM
else TYPE_LISTVIEW_ITEM
}
override fun getCount(): Int {
return mData.size
}
override fun getItem(position: Int): Any {
return mData[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, view: View?, parent: ViewGroup?): View? {
var view = view
var type = getItemViewType(position)
if (position == mSelectedItem) type = TYPE_LISTVIEW_SELECTED_ITEM
when (type) {
TYPE_LISTVIEW_ITEM -> {
view = LayoutInflater.from(context).inflate(R.layout.listview_row, parent, false)
textView = view.findViewById(R.id.rowText)
}
TYPE_LISTVIEW_SELECTED_ITEM -> {
view = LayoutInflater.from(context).inflate(R.layout.listview_selected_row, parent, false)
textView = view.findViewById(R.id.selectedRowText)
}
}
textView.text = mData[position]
return view
}
}
MainActivity.kt
package com.ijmusic.listviewrearrange
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import com.ijmusic.listviewrearrange.databinding.ActivityMainBinding
val list = listOf("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var mAdapter: ListViewAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
mAdapter = ListViewAdapter(this)
setListView()
binding.listView.onItemClickListener = object: AdapterView.OnItemClickListener {
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
binding.listView.setSelection(position)
mAdapter.highlightSelection(position)
}
}
}
fun setListView() {
for ( i in 0 until list.count() ) {
if ( i == 0 )
mAdapter.addSelectedItem(list[i], i)
else
mAdapter!!.addItem(list[i], i)
}
binding.listView.adapter = mAdapter
}
}
You can look into a concept called gestures in android Kotlin. It will help.

W/RecyclerView: No adapter attached; skipping layout

I have made a basic shopping list app that utilises a recyclerview to display the list items. I am trying to add a settings screen using navigation with fragments. I am running into the issue where my recyclerview & data display when I open the app, however when I go to the settings menu then back to the main screen there's no recyclerview. Logcat shows the error "W/RecyclerView: No adapter attached; skipping layout"
MainActivity.kt
package com.example.shoppinglist
import android.app.Dialog
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.FloatingActionButton
class MainActivity : AppCompatActivity(), RVAdapter.ListItemClickInterface {
lateinit var itemsRV: RecyclerView
lateinit var addFAB: FloatingActionButton
lateinit var list: List<ListItems>
lateinit var RVAdapter: RVAdapter
lateinit var viewModel: ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupActionBarWithNavController(findNavController(R.id.fragment_main))
itemsRV = findViewById(R.id.recyclerView)
addFAB = findViewById(R.id.idFABAdd)
list = ArrayList<ListItems>()
RVAdapter = RVAdapter(list, this)
itemsRV.layoutManager = LinearLayoutManager(this)
itemsRV.adapter = RVAdapter
val repository = Repository(Database(this))
val factory = ViewModelFactory(repository)
viewModel = ViewModelProvider(this, factory).get(ViewModel::class.java)
viewModel.getAllListItems().observe(this, Observer {
RVAdapter.list = it
RVAdapter.notifyDataSetChanged()
})
addFAB.setOnClickListener {
openDialog()
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragment_main)
return navController.navigateUp() || super.onSupportNavigateUp()
}
fun openDialog() {
val dialog = Dialog(this)
dialog.setContentView(R.layout.add_dialog)
val cancelButton = dialog.findViewById<Button>(R.id.idBtnCancel)
val addButton = dialog.findViewById<Button>(R.id.idBtnAdd)
val itemEdt = dialog.findViewById<EditText>(R.id.idEditItemName)
val itemQuantityEdt = dialog.findViewById<EditText>(R.id.idEditItemQuantity)
cancelButton.setOnClickListener {
dialog.dismiss()
}
addButton.setOnClickListener {
val itemName: String = itemEdt.text.toString()
val itemQuantity: String = itemQuantityEdt.text.toString()
if (itemName.isNotBlank() && itemQuantity.isNotBlank()) {
val items = ListItems(itemName, itemQuantity)
viewModel.insert(items)
Toast.makeText(applicationContext, "Item Added", Toast.LENGTH_SHORT).show()
RVAdapter.notifyDataSetChanged()
dialog.dismiss()
} else {
Toast.makeText(applicationContext, "Enter All Info To Add Item",
Toast.LENGTH_SHORT)
.show()
}
}
dialog.show()
}
override fun onItemClick(listItems: ListItems) {
viewModel.delete(listItems)
RVAdapter.notifyDataSetChanged()
Toast.makeText(applicationContext, "Item Deleted", Toast.LENGTH_SHORT).show()
}
}
HomeFragment.kt
package com.example.shoppinglist
import android.os.Build
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
import kotlinx.android.synthetic.main.fragment_home.*
class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
#RequiresApi(Build.VERSION_CODES.N)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
idFABSettings.setOnClickListener {
findNavController().navigate(R.id.action_homeFragment_to_settingsFragment)
}
loadSettings()
}
#RequiresApi(Build.VERSION_CODES.N)
private fun loadSettings(){
val sp = PreferenceManager.getDefaultSharedPreferences(context)
val theme = sp.getBoolean("theme_switch",false)
}
}
SettingsFragment.kt
package com.example.shoppinglist
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="#+id/fragment_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/navigation"
/>
</RelativeLayout>
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?attr/colorPrimary"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="#layout/list_rv_item"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/idFABAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:backgroundTint="?attr/colorSecondary"
android:contentDescription="Add Item Button"
android:src="#drawable/ic_add"
android:tint="#android:color/white" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/idFABSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:backgroundTint="?attr/colorSecondary"
android:contentDescription="Add Item Button"
android:src="#drawable/ic_settings"
android:tint="#android:color/white" />
</RelativeLayout>
navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/navigation"
app:startDestination="#id/homeFragment">
<fragment
android:id="#+id/settingsFragment"
android:name="com.example.shoppinglist.SettingsFragment"
android:label="Settings" >
<action
android:id="#+id/action_settingsFragment_to_homeFragment"
app:destination="#id/homeFragment" />
</fragment>
<fragment
android:id="#+id/homeFragment"
android:name="com.example.shoppinglist.HomeFragment"
android:label="Shopping List"
tools:layout="#layout/fragment_home" >
<action
android:id="#+id/action_homeFragment_to_settingsFragment"
app:destination="#id/settingsFragment" />
</fragment>
</navigation>
Not sure if any more info is required. Apologies in advance - I am new to android studio & kotlin.
You are trying to work with views that are specific to HomeFragment's layout through the MainActivity. This will not work correctly. The first time you start the activity, in onCreate you use findViewById to find the view with ID recyclerView, and it successfully finds it because at that time the view is part of the HomeFragment, which is in the layout.
However, when you change fragments, the original fragment view is detached and removed. When you return to the first fragment, Android creates a new instance of your HomeFragment and its layout. The MainActivity is still referencing the original RecyclerView from the first instance of the HomeFragment, so it will update that view that is no longer on screen and it won't touch the new view. You have actually created a memory leak where the MainActivity is preventing that first fragment's view from being destroyed.
Another issue that you haven't discovered yet possibly is that if you rotate the screen while the SettingsFragment is open, you'll crash with a NullPointerException. This is because a screen rotation will cause a new Activity to be created, so onCreate() will be called again, and when it tries to find recyclerView when the HomeFragment is not in the layout, it will fail.
It doesn't make sense to work with a Fragment's specific views from the hosting Activity. The Activity should not have to know any details about what is in a Fragment and what to do with the contents of that fragment. All your code that has to do with the RecyclerView should be in HomeFragment.

No adapter attached; skipping layout error in logcat windowin android studio

i have been facing this issue from 3-4 days and i still can't resolve this error. i have also gone through this a solution of the same problem
but i didn't understand enough. i got that, that this error occurs when we didn't attach our adapter but i have attached.
below i have attached my fragment file, adapter file and RecyclerView file-
this is a code where i declared my adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.chumonsuru.R
import com.example.chumonsuru.model.Resturant
import com.squareup.picasso.Picasso
class DashboardRecyclerAdapter(val context : Context , val resturantInfoList : ArrayList<Resturant>) : RecyclerView.Adapter<DashboardRecyclerAdapter.DashboardViewHolder>(){
class DashboardViewHolder(view:View): RecyclerView.ViewHolder(view){
val txtResturantid : TextView = view.findViewById(R.id.txtResturantid)
val txtResturantName : TextView = view.findViewById(R.id.txtResturantName)
val txtPerPrice : TextView = view.findViewById(R.id.txtPerPrice)
val txtResturantRating : TextView = view.findViewById(R.id.txtResturantRating)
val imgResturantImage : ImageView = view.findViewById(R.id.imgResturantImage)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DashboardViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.recycler_dashboard_row_one , parent , false)
return DashboardViewHolder(view)
}
override fun getItemCount(): Int {
return resturantInfoList.count()
}
override fun onBindViewHolder(holder: DashboardViewHolder, position: Int) {
val resturant = resturantInfoList[position]
holder.txtResturantid.text = resturant.id
holder.txtResturantName.text = resturant.name
holder.txtPerPrice.text = resturant.cost_for_one
holder.txtResturantRating.text = resturant.rating
Picasso.get().load(resturant.image_url).into(holder.imgResturantImage)
}
}
and here is my dashboard fragment file-
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import com.example.chumonsuru.R
import com.example.chumonsuru.adapter.DashboardRecyclerAdapter
import com.example.chumonsuru.model.Resturant
import kotlin.collections.HashMap
class DashFrag : Fragment() {
lateinit var recyclerView: RecyclerView
lateinit var linearLayoutManager: LinearLayoutManager
lateinit var recyclerAdapter: DashboardRecyclerAdapter
val resturantInfoList = arrayListOf<Resturant>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.dash_frag, container, false)
linearLayoutManager = LinearLayoutManager(activity)
recyclerView = view.findViewById(R.id.recyclerView)
val queue = Volley.newRequestQueue(activity as Context)
val url = "http://13.235.250.119/v1/book/fetch_books/"
val jsonObjectRequest = object : JsonObjectRequest(Request.Method.GET, url, null, Response.Listener {
val success = it.getBoolean("success")
if (success != null) {
val data = it.getJSONArray("data")
for (i in 0 until data.length()) {
val resturantJsonObject = data.getJSONObject(i)
val resturantObject = Resturant(
resturantJsonObject.getString("id"),
resturantJsonObject.getString("name"),
resturantJsonObject.getString("rating"),
resturantJsonObject.getString("cost_for_one"),
resturantJsonObject.getString("image_url")
)
resturantInfoList.add(resturantObject)
recyclerAdapter = DashboardRecyclerAdapter(activity as Context, resturantInfoList)
recyclerView.adapter = recyclerAdapter
recyclerView.layoutManager = linearLayoutManager
recyclerView.addItemDecoration(DividerItemDecoration(recyclerView.context,
(linearLayoutManager)
.orientation))
}
}
},
Response.ErrorListener {
/////ERROR/////
}) {
override fun getHeaders(): MutableMap<String, String> {
val headers = HashMap<String, String>()
headers["Content-type"] = "application/json"
headers["token"] = "xyz"
return headers
}
}
queue.add(jsonObjectRequest)
return view
}
}
and
my restaurant class-
data class Resturant(
val id: String,
val name: String,
val rating: String,
val cost_for_one : String,
val image_url: String
)
my dashboard fragment xml file-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.DashFrag">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/txtHelloFrag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/hello_blank_fragment"
android:textSize="50sp"
android:textColor="#color/colorAccent"
android:padding="20dp"
android:background="#drawable/gradient"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/txtHelloFrag"
android:layout_margin="10dp"
android:padding="5dp"
/>
</RelativeLayout>
and the layout of the row of the recycler view
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="140dp"
android:orientation="horizontal"
android:background="#ffffff"
android:weightSum="6">
<ImageView
android:layout_weight="1.5"
android:id="#+id/imgResturantImage"
android:layout_width="0dp"
android:layout_height="110dp"
android:src="#mipmap/ic_launcher1"
android:padding="5dp"/>
<RelativeLayout
android:layout_weight="3.3"
android:layout_width="0dp"
android:layout_height="match_parent">
<TextView
android:padding="8dp"
android:id="#+id/txtResturantid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="id"
android:layout_toLeftOf="#id/txtResturantName"
android:textSize = "18sp"
/>
<TextView
android:id="#+id/txtResturantName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Name of the Resturant"
android:paddingTop="8dp"
android:textSize="18sp"
android:textColor="#000000"/>
<TextView
android:id="#+id/txtBookAuthor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/txtResturantName"
android:text="Name of the Author"
android:padding="8dp"
android:textSize="15sp"/>
<TextView
android:id="#+id/txtPerPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Rs. 299"
android:paddingTop="8dp"
android:paddingLeft="8dp"
android:layout_below="#id/txtBookAuthor"
android:textSize="15sp"
android:textStyle="bold"
android:textColor="#357a38"/>
<TextView
android:id="#+id/txtPerPerson"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/person"
android:layout_toRightOf="#id/txtPerPrice"
android:textSize="15sp"
android:layout_below="#id/txtBookAuthor"
android:textColor="#357a38"
android:paddingTop="8dp"
android:textStyle="bold"/>
</RelativeLayout>
<TextView
android:id="#+id/txtResturantRating"
android:layout_weight="1.2"
android:layout_width="0dp"
android:padding="6dp"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/star_foreground"
android:textColor="#ffca28"
android:text="4.5"
android:textSize="15sp"
android:textStyle="bold">
</TextView>
</LinearLayout>
i think i have already attached the adapter to my recycler view. if i didn't please help me to do this.
Please help me to get rid of this problem
I think something that you need to check.
return view
Instead of this, you have to use
return view;
second,
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/txtHelloFrag"
android:layout_margin="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:padding="5dp"
/>
You try to put app:layoutManager into that.
or
val layoutManager = LinearLayoutManager(this)
recyclerView_main.setLayoutManager(layoutManager)
As above, LayoutManager is set in the setLayoutManager and it processes as code.
LinearLayoutManager manager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
this is related above, you have set the layout manager for RecyclerView
I hope that It will be work.

Resources