Fragment displaying a grey field - kotlin

I am still a bit new to fragments in android studio but I was wondering if this is usually how fragments are displayed as on the phone. It appear as a grey background above my activity, as shown in this image: https://gyazo.com/9d5569718c5092debfeaab1c631b0046
This is my MainAppActivity code:
class MainAppActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainAppBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainAppBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarMainApp.toolbar)
binding.appBarMainApp.fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_content_main_app)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main_app, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_main_app)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
Any buttons or similar seems to also be affected by it.
Is this normal or is it some sort of bug?
My content_main_app, this is my home set 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/app_bar_main_app">
<fragment
android:id="#+id/nav_host_fragment_content_main_app"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment 1:
class HomeFragment : Fragment() {
private lateinit var binding: FragmentHomeBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
return binding.root
}
}
XML layout fragment 1:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<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"
tools:context=".HomeFragment"
android:background="#android:color/transparent"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Fragment 2:
class HobbiesFragment : Fragment() {
private var _binding: FragmentHobbiesBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val hobbiesViewModel =
ViewModelProvider(this).get(GalleryViewModel::class.java)
_binding = FragmentHobbiesBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.mainTitle
hobbiesViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
XML layout fragment 2:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/beige1"
tools:context=".ui.Hobbies.HobbiesFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/mainTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HOBBIES"
android:textColor="#color/blueMix"
android:textSize="38sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.043" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.097"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mainTitle"
app:layout_constraintVertical_bias="0.064" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Fragment 3:
class GalleryFragment : Fragment() {
private var _binding: FragmentGalleryBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val galleryViewModel =
ViewModelProvider(this).get(GalleryViewModel::class.java)
_binding = FragmentGalleryBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textGallery
galleryViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
XML layout fragment 3:
<?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.gallery.GalleryFragment">
<TextView
android:id="#+id/text_gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

After a few hours of messing around in android studio I finally found out what was giving me a grey background, covering the main fragment. I had to go into my main activity ( mainAppActivity in my case ) and delete the material divider (as seen in the image). It solved the problem for me.

Related

how to use findNavController properly in fragment? android studio(kotlin)

when i tried that code in main activity it worked perfectly without any errors. But when i moved code from main activity to mine fragment kt file got some errors. Any solutions?
Here is my kt files:
class MainFragment : Fragment(R.layout.fragment_main) {
private lateinit var bottomNavigationView: BottomNavigationView
private lateinit var navController: NavController
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bottomNavigationView = view.findViewById(R.id.bottomNavView)
navController = findNavController(R.id.nav_host_fragment)
}
}
<?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"
tools:context=".fragments.MainFragment">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottomNavView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>

After second click on Fragment, recycler view disappears

When I Click on Home navigation fragment(there is recyclerview) recycler view disappears with error message: E/RecyclerView: No adapter attached; skipping layout
when the app launchs it appears but when i move to another fragment and return again to home fragment, recycler view just disappears. even If I dont move on another fragment and click on home fragment, it still disappears.
What could be the problem and what can I do to fix it?
My codes:
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
android:paddingBottom="65dp"
app:reverseLayout="false" />
</LinearLayout>
Posts.kt
data class Posts(
var id: Int,
var imageUrl: String,
var title: String,)
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var recyclerViewPersonAdapter: RecyclerViewPersonAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView = findViewById<BottomNavigationView>(R.id.bottomNavMenu)
val controller = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.homeFragment,
R.id.addFragment,
R.id.userFragment
)
)
setupActionBarWithNavController(controller, appBarConfiguration)
navView.setupWithNavController(controller)
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = RecyclerViewPersonAdapter(getData())
}
private fun getData() : List<Posts>{
val list = ArrayList<Posts>()
list.add(
Posts(
1,
"https://www.myanbiz-consulting.com/wp-content/uploads/2019/04/4214892-news-images.jpg",
"Best news in the world\nfor you"
)
)
list.add(
Posts(
2,
"https://www.myanbiz-consulting.com/wp-content/uploads/2019/04/4214892-news-images.jpg",
"very very gooood\nnews for you"
)
)
list.add(
Posts(
3,
"https://www.myanbiz-consulting.com/wp-content/uploads/2019/04/4214892-news-images.jpg",
"very very gooood\nnews for you"
)
)
list.add(
Posts(
4,
"https://www.myanbiz-consulting.com/wp-content/uploads/2019/04/4214892-news-images.jpg",
"very very gooood\nnews for you"
)
)
return list
}
}
RecyclerViewPersonAdapter.kt
class RecyclerViewPersonAdapter(private val list: List<Posts>) : RecyclerView.Adapter<RecyclerViewPersonAdapter.PersonViewHolder>() {
class PersonViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val imageView: ImageView
val textView: TextView
init {
imageView = itemView.findViewById(R.id.imageView)
textView = itemView.findViewById(R.id.textView)
}
fun setData(posts: Posts){
Glide.with(itemView.context)
.load(posts.imageUrl)
.into(imageView)
textView.text = posts.title
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PersonViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.news_post, parent, false)
return PersonViewHolder(itemView)
}
override fun onBindViewHolder(holder: PersonViewHolder, position: Int) {
val posts = list[position]
holder.setData(posts)
}
override fun getItemCount(): Int {
return list.size
}
}
news_post.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="400dp"
android:layout_height="100dp"
android:background="#color/teal_200"
android:layout_marginTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/img" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="22dp"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="8sp"
android:text="Best news in the world\nfor you"
android:textColor="#color/black"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_gravity="center"
android:src="#drawable/ic_baseline_thumb_up_alt_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:lineSpacingExtra="7sp"
android:text="2,687"
android:textColor="#333333"
android:textSize="13sp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="22dp"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_gravity="center"
android:src="#drawable/ic_baseline_remove_red_eye_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:lineSpacingExtra="7sp"
android:text="32,577"
android:textColor="#333333"
android:textSize="13sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Your RecyclerView is in fragment_home.xml.
But you declare it in MainActivity.
Just do that in your HomeFragment instead of MainActivity.
class HomeFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
recyclerView = view.findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.adapter = RecyclerViewPersonAdapter(getData())
...

Why is my FloatingActionButton doesn't work on Fragment in Kotlin?

I have created a FloatingActionButton to switch the view between gridView and listView of the recyclerView in an fragment. I just wanted to make sure that the FloatingActionButton works correctly and So I just added a `toast. However, the toast doesn't show up when I hit the button.
fragment_dashboard.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"
android:background="#color/colorOffWhite"
tools:context=".ui.fragments.DashboardFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_dashboard_items"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fb_dashboard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginBottom="60dp"
android:backgroundTint="#color/colorAccent"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_grid_list_view"
app:layout_anchorGravity="bottom|right|end"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="#+id/tv_no_dashboard_items_found"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="#string/no_dashboard_item_found"
android:textAlignment="center"
android:textSize="#dimen/no_data_found_textSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
DashboardFragment.kt
class DashboardFragment : BaseFragment() {
private var binding: FragmentDashboardBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding?.fbDashboard?.setOnClickListener { view ->
Toast.makeText(requireContext(), "You clicked FA Button", Toast.LENGTH_LONG).show()
}
val root = inflater.inflate(R.layout.fragment_dashboard, container, false)
return root
}
}
I get the following error when I use the code in the first answer.
You should assign the binding variable using the DatabindingUtil inflate
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_dashboard, container, false
)
binding?.fbDashboard?.setOnClickListener { view ->
Toast.makeText(requireContext(), "You clicked FA Button", Toast.LENGTH_LONG).show()
}
return binding.root
}
Also, wrap the layout file fragment_dashboard in a layout tag.
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
</layout>
This is what I used and resolved the issue.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentDashboardBinding.inflate(inflater, container, false)
binding.fbDashboard.setOnClickListener {
Toast.makeText(requireContext(), "You clicked FA Button", Toast.LENGTH_LONG).show()
}
return binding.root
}

How to find a view for Snackbar in fragment's onCreateView method if I use view binding and navigation component?

I'm trying to show a snack bar in fragment's onCreateView method but I don't know what view to passing inside the snack bar.
I'm very confused because I first time use the Navigation component and view binding and maybe is there a problem.
I tried binding.root but I got this exception:
java.lang.IllegalArgumentException: No suitable parent found from the
given view. Please provide a valid view.
After that I tried requireView().rootView as parameter but I also got this exception:
java.lang.IllegalStateException: Fragment XFragment{7a091b5}
(cefa1aef-59c3-4602-bcf1-b36f7d538cf9) id=0x7f0800f7} did not return a
View from onCreateView() or this was called before onCreateView()
MY CODE IN XFragment:
package com.sdsd.sds
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.Navigation
import com.google.android.material.snackbar.Snackbar
import com.sdsd.sds.databinding.FragmentXBinding
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
class XFragment : Fragment() {
private var _binding: FragmenXBinding? = null
private val binding get() = _binding!!
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentXBinding.inflate(inflater, container, false)
binding.tvFgRegistration.setOnClickListener {
Navigation.findNavController(binding.root)
.navigate(R.id.action_f1_to_f2)
}
val snackbar: Snackbar = Snackbar.make(binding.root, "Succesful", Snackbar.LENGTH_LONG)
snackbar.show()
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
#JvmStatic
fun newInstance(param1: String, param2: String) =
XFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
XML LAYOUT 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"
android:background="#drawable/ic"
tools:context=".XFragment">
<EditText
android:id="#+id/etE"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:background="#color/translucent"
android:drawableStart="#drawable/ic_vector"
android:drawablePadding="5dp"
android:ems="10"
android:hint="#string/e_mail"
android:inputType="text"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView" />
<EditText
android:id="#+id/etP"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:background="#color/translucent"
android:drawableStart="#drawable/ic_vector"
android:drawablePadding="5dp"
android:ems="10"
android:hint="#string/password"
android:inputType="textPassword"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/etE" />
<TextView
android:id="#+id/tvFgRegistration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="180dp"
android:layout_marginEnd="76dp"
android:layout_marginBottom="100dp"
android:text="#string/new_u"
android:textColor="#color/white"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I only want to show a snack bar with a message when XFragment creates.
Can anyone tell me how to solve this and explain me in a few words why?
I found few ways to show a snack bar from a fragment
One of the solution is to use requireView().
Snackbar.make(
requireView(),
"Hello from Snackbar",
Snackbar.LENGTH_SHORT
).show()
This solution will work when you are inside any onClickListner{} you can simply pass it as a view and it will do the job.
binding.button.setOnClickListener {
Snackbar.make(
it,
"Hello from Snackbar",
Snackbar.LENGTH_SHORT
).show()
}
I found a simple solution and seems a Snackbar works excellent only with CoordinatorLayout as root layout so I set CoordinatorLayout as my root layout in the XML file.
In the Snackbar I just put binding.coordinatorlayout where coordinatorlayout is just an id of CoordinatorLayout in the XML file.
Code solution for a fragment is here:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentXBinding.inflate(inflater, container, false)
binding.tvFgRegistration.setOnClickListener {
Navigation.findNavController(binding.root)
.navigate(R.id.action_f1_to_f2)
}
val snackbar: Snackbar = Snackbar.make(binding.coordinatorlayout, "Succesful", Snackbar.LENGTH_LONG)
snackbar.show()
return binding.root
}
XML layout file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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/coordinatorlayout" //ID OF COORDINATOR LAYOUT
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/ic"
tools:context=".XFragment" >
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/ic_backg">
<EditText
android:id="#+id/etE"
android:layout_width="0dp"
.
.
.
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I faced the same issue while using navigation architecture.
What worked for me was
if(isAdded){
Snackbar.make(requireActivity.window.decorView.rootView,"message").show()
}

recyclerview showing empty white screen

I am new kotlin and recently started working with retrofit and I have followed this tutorial http://velmm.com/kotlin-retrofit-android-example-with-recyclerview/
but when I run code it is showing empty white screen below
empty screenshot
below my MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var recyclerView: RecyclerView
lateinit var recyclerAdapter: RecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerview)
recyclerAdapter = RecyclerAdapter(this)
recyclerview.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = recyclerAdapter
val apiInterface = ApiInterface.create().getMovies()
//apiInterface.enqueue( Callback<List<Movie>>())
apiInterface.enqueue( object : Callback<List<Movie>> {
override fun onResponse(call: Call<List<Movie>>?, response: Response<List<Movie>>?) {
if(response?.body() != null)
recyclerAdapter.setMovieListItems(response.body()!!)
}
override fun onFailure(call: Call<List<Movie>>?, t: Throwable?) {
}
})
}
}
below Adapter class
class RecyclerAdapter(val context: Context) : RecyclerView.Adapter() {
var movieList : List<Movie> = listOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_adapter,parent,false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return movieList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.tvMovieName.text = movieList.get(position).title
Glide.with(context).load(movieList.get(position).image)
.apply(RequestOptions().centerCrop())
.into(holder.image)
}
fun setMovieListItems(movieList: List<Movie>){
this.movieList = movieList;
notifyDataSetChanged()
}
class MyViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!) {
val tvMovieName: TextView = itemView!!.findViewById(R.id.title)
val image: ImageView = itemView!!.findViewById(R.id.image)
}
}
below ApiInterface.kt
interface ApiInterface {
#GET("volley_array.json")
fun getMovies() : Call<List<Movie>>
companion object {
var BASE_URL = "http://35.200.174.74/apis/"
fun create() : ApiInterface {
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
return retrofit.create(ApiInterface::class.java)
}
}
}
below Movie.kt
data class Movie(var title: String, var image: String)
below recyclerview_adapter.xml
<?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"
android:layout_width="match_parent"
android:layout_height="150dp">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textStyle="bold"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
below activity_main.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
There is an issue at the recyclerview_adapter.xml file. You should not use match_parent inside constraint layout but 0dp, and when doing it you must take into account you need to constraint start and end if you want full width, or top and bottom if you want to do it vertically. Here how the file should look like:
<?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"
android:layout_width="match_parent"
android:layout_height="150dp">
<ImageView
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="#+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textStyle="bold"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
And the activity should look like this:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>