I have a TabLayout with two fragments which both of them shows a RecyclerView (one movies and the other tv shows). The TabLayout works perfectly but the problem comes when I click on the image of a film. The click in a movie should make a transaction to the movie details fragment. But when this happens the ListFragment with the TabLayout appears under the new one so the two of them are displayed.
My ActivityMain code where I call the transaction and where I set the Page Adapter:
override fun onMovieClicked(iDMovie: Int) {
val movieDetails = MovieDetailsFragment.newInstance(iDMovie)
supportFragmentManager.
beginTransaction().
replace(R.id.main_container, movieDetails).
addToBackStack(null).
commit()
}
private fun setStatePageAdapter() {
val fragmentAdapter = MyPagerAdapter(supportFragmentManager)
viewPager.adapter = fragmentAdapter
tabLayout.setupWithViewPager(viewPager)
}
My PageAdapterClass:
class MyPagerAdapter(fm: FragmentManager): FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
return when (position) {
0 -> {
ListFilmFragment()
}
else -> {
return TVShowsFragmentList()
}
}
}
override fun getCount(): Int {
return 2
}
override fun getPageTitle(position: Int): CharSequence {
return when (position) {
0 -> "PelĂculas"
else -> {
return "Series"
}
}
}
}
And the Layouts:
Activity Main:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_container"
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="match_parent">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?actionBarSize"
app:tabGravity="fill"
app:tabIndicatorHeight="4dp"
app:tabBackground="#color/black"
app:tabMode="fixed"
app:tabTextColor="#color/white"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_height="match_parent"
android:layout_width="match_parent">
</android.support.v4.view.ViewPager>
Observation: With FrameLayout instead of Coordinator didn't work either.
The result I get is the following:
The FragmentDetails overlaps the filmListFragment and the two of them are displayed at the same time. But only the details fragments has to be displayed.
You can solve your problem in 2 ways
first:
You can hide your ViewPager and TabLayout befor inflating Your fragments.
so change your MovieClicked method like below
override fun onMovieClicked(iDMovie: Int) {
viewPager.visibiliy=View.Gone;
tabLayout.visibility=View.Gone
val movieDetails = MovieDetailsFragment.newInstance(iDMovie)
supportFragmentManager.
beginTransaction().
replace(R.id.main_container, movieDetails).
addToBackStack(null).
commit()
}
Seconde:
You can change your fragments XML Root elements
1-set a background for each of you fragments android:background="yourColor" to hide
behind layout .
2-set OnClick attribute to true to make app receive your current layout
onClickListeners not behind layout with android:onClick=true
Your Xml must be like below
<android.support.design.widget.CoordinatorLayout
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="match_parent"
android:onClick="true"
android:background="#ffffff"<!--White Color for example-->
>
</android.support.design.widget.CoordinatorLayout>
If you have several fragment layout that has your problem
You can set an style and change your fragment style to your style
So declare an style in style.xml
<style name="fragmentsRootElementStyle">
<item name="android:onClick">true</item>
<item name="android:background">#ffffff</item>
</style>
and set style for fragment layouts root as below
<android.support.design.widget.CoordinatorLayout
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="match_parent"
style="#style/fragmentsRootElementsStyle"
>
</android.support.design.widget.CoordinatorLayout>
Related
when I switch between the fragment I created, the home fragment is not deleted, it writes on the others.
please i have an issue. I am using bottom navigation and nav controller. once I switch fragments, the home fragment keeps showing under the rest
`
class FeedActivity : AppCompatActivity() {
private lateinit var bottomNavigationView: BottomNavigationView
//loadFragment(HomeFragment())
bottomNavigationView = findViewById(R.id.bottom_navigation) as BottomNavigationView
bottomNavigationView.setOnItemSelectedListener {
when (it.itemId) {
R.id.nav_home -> {
loadFragment(HomeFragment())
true
}
R.id.nav_search -> {
loadFragment(SearchFragment())
true
}
R.id.nav_add -> {
loadFragment(AddFragment())
true
}
R.id.nav_notifications -> {
loadFragment(NotificationsFragment())
true
}
R.id.nav_profile -> {
loadFragment(ProfileFragment())
true
}
else -> throw IllegalStateException("Someone forgot to add enough fragment cases to 'when' clause!")
}
}
}
private fun loadFragment(fragment: Fragment){
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.cercevekapsayici,fragment)
transaction.commit()
}`
`<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=".view.FeedActivity">
<FrameLayout
android:id="#+id/cercevekapsayici"
android:layout_above="#id/bottom_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
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:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/bottom_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:itemIconTint="#color/cardview_dark_background"
app:labelVisibilityMode="unlabeled"
app:menu="#menu/bottom_navigation" />
</com.google.android.material.appbar.AppBarLayout>
[[enter image description here](https://i.stack.imgur.com/3D2Z8.png)](https://i.stack.imgur.com/llwZ5.png)`
I want the recyclerview to disappear when I switch to other fragments.
You can make your FramLayout height match parent :
<FrameLayout
android:id="#+id/cercevekapsayici"
android:layout_above="#id/bottom_appbar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Your loadFragment function replaces whatever Fragment is attached to R.id.cercevekapsayici, which is a FrameLayout that contains your fragments. But your RecyclerView is part of your main layout, so it will always be there whatever you attach to R.id.cercevekapsayici.
If you want it to be replaced, put it in a Fragment and add it to that FrameLayout - then it'll be removed when you switch to a different fragment.
Maybe you need to give background to the other fragments
I have an activity and a few fragments in it, and I have an action bar that I need to be visible all the time except for the case when I open MyTestFragment, so when I open this fragment I need my action bar to be hidden.
As my Activity is AppCompatActivity, I tried to call this method (from Activity) in order to hide an actionBar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
supportActionBar?.hide()
...
and it works, however, I need to make this call from fragment, so I do it like this
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as AppCompatActivity).supportActionBar!!.hide()
}
and the result is
The action bar became kind of invisible instead of gone (you see this gray pass right under the clock)
What am I missing here?
UPD
I would like to add explanation to the problem, in order to illustrate this I did such code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
Thread {
Thread.sleep(8000)
mainExecutor.execute {
supportActionBar?.show() <---- 2
}
}.start()
Thread {
Thread.sleep(12000)
mainExecutor.execute {
supportActionBar?.hide() <---- 3
}
}.start()
supportActionBar?.hide() <---- 1
...
What is happening here is - the method marked 1 is invoking first and the actionbar hides as expected. The next method #2 invokes show() for the action bar and the action bar appears as expected, however, when it comes to method #3 and tries to hide the actionbar again the bug is here. Instead of hiding the actionbar it kind of makes it invisible and you can see a grey line (like on the screenshot).
So, looks like it is possible to hide the actionbar only immediately in OnCreate() method if you try to do it after you will see a grey line instead of the actionbar.
UPD
My MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/awl_application_drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/main_activity_layout_bg_color"
tools:openDrawer="end">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<application.widget.toolbar.BondToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/errorViewContainer"
android:layout_below="#id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<FrameLayout
android:id="#+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/toolbar_layout"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
style="#style/AppTabLayout"
android:layout_width="match_parent"
android:layout_height="#dimen/bottom_nav_tab_height"
android:background="#color/deprecated_palette_FF000000"
android:elevation="6dp"
android:fillViewport="true"
android:padding="0dp"
app:tabPaddingBottom="0dp"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp"
app:tabPaddingTop="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:tabMinWidth="#dimen/bottom_nav_tab_min_width" />
<CustomView
android:layout_width="match_parent"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="#id/tab_layout"
app:layout_constraintTop_toTopOf="parent"
app:theme="#style/ThemeOverlay.AppCompat.Light" />
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
android:id="#+id/navigation_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_marginTop="?android:attr/actionBarSize" />
</androidx.drawerlayout.widget.DrawerLayout>
When navigating to TestFragment, do supportActionBar?.hide() from Activity.
Do supportActionBar?.show() from Activity when navigating to the Fragment where the ActionBar should be visible.
I've done something like this in a project but on an Activity but you can do the similar thing on Fragments also
Here I've created a method called "setupToolbar" which I call from onCreate right after setContentView(R.layout.___)
private fun setupToolbar() {
toolbar.title = ""
setSupportActionBar(toolbar)
toolbar.navigationIcon = ContextCompat.getDrawable(this, R.drawable.arrow_back_white_24)
toolbar.setNavigationOnClickListener {
finish()
}
supportActionBar?.hide()
}
Then I added a gesture listener and observing SingleTap
private var gestureListener: GestureDetector.SimpleOnGestureListener =
object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent?): Boolean {
if (toolbar.visibility == View.VISIBLE) {
supportActionBar?.hide()
return true
} else {
supportActionBar?.show()
}
return false
}
}
There might be two options here.
Defining topbar in each fragment layout and don't include in specific fragment where not required, rather than including in activity.
OR
Define some NO ACTION BAR styles in style.xml, then set/unset it in java/kotlin code, when navigating to/from some fragment.
In styles.xml :
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
In kotlin/java code from activity:
Call setTheme method with above defined style and then call recreate()
i am trying to add viewpager and tablayout along with bottom navigation. First time fragment loads fine then i click the item the fragment is not loading properly
here is my main activity code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<include layout="#layout/toolbar"
android:id="#+id/layout_toolbar"/>
<FrameLayout
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/bottom_nav_menu"
android:background="#drawable/bg_bottom_bar"
/>
</LinearLayout>
Kotlin Code
bottomNav.setOnNavigationItemSelectedListener {
var selectedFragment: Fragment? = null
when (it.itemId) {
R.id.homeFragment -> {
replaceFragment(fragment = HomeFragment())
return#setOnNavigationItemSelectedListener true
}
R.id.fixtures -> {
replaceFragment(fragment = AllMatchsFragment())
return#setOnNavigationItemSelectedListener true
}
}
false
}
private fun replaceFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction().replace(R.id.fragmentContainer, fragment).commit()
}
Here is fragment code where i want to load viewpager and tablayout:
homePagerAdapter = HomeViewpagerAdapter(activity!!.supportFragmentManager)
homePagerAdapter!!.populateFragment(AllMatchsFragment())
homePagerAdapter!!.populateFragment(LiveMatchesFragment())
view.homeViewPager.adapter=homePagerAdapter
view.tabLayout.setupWithViewPager(view.homeViewPager)
return view
Fragment XML
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="172dp"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabTextColor="#color/colorPrimary"
app:tabSelectedTextColor="#color/colorAccent"
>
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/homeViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/tabLayout"/>
ViewPagerAdapter
val tabNameList= listOf("All","Live")
val fragmentList = mutableListOf<Fragment>()
override fun getItem(position: Int): Fragment {
return fragmentList[position]
}
override fun getCount(): Int {
return 2
}
override fun getPageTitle(position: Int): CharSequence? {
return tabNameList[position]
}
fun populateFragment(fragment: Fragment){
fragmentList.add(fragment)
}
When I perform second click on the second viewpager got stuck and fragment disappear when I close and reopen the app it works fine and after second click again remain the same.
Try to use childFragmentManager instead of supportFragmentManager
homePagerAdapter = HomeViewpagerAdapter(activity!!.supportFragmentManager)
I am trying to create an App like Instagram as part of a project and I want to keep the bottom part of the app fixed with the different Image Buttons that takes you to different parts of the App like home, messages and other functionalities.
I am currently making my app in a Relative Layout and will be switching to Constraint Layout after I get my App properly developed
I want the bottom part of the App with the Image Buttons fixed when a user clicks one of those buttons and is taken to some other type of layout xml file
Looks like you are talking about Bottom navigation bars :
Bottom navigation bars display three to five destinations at the bottom of a screen. Each destination is represented by an icon and an optional text label. When a bottom navigation icon is tapped, the user is taken to the top-level navigation destination associated with that icon.
With the Bottom navigation bars, you can switch fragments and have the navigation bar visible and fixed all over your app.
You can find a lot of information about how to create this, you can check this toturial, this video and many more.
You can use Bottom Navigation View or even a TabLayout anchored at the bottom of an activity.
You need an Activity that will host Fragments. These fragments will be displayed in turn as you interact with the Activity's hosting view.
I have created an Android Project to demonstrate. Sorry, you didn't specify language so i wrote it in Kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupViewPager(pager)
}
//the ViewPager will be responsible for navigating through your fragments even when you need to slide through them
private fun setupViewPager(viewPager: ViewPager){
val adapter = ViewPagerAdapter(supportFragmentManager)
setTabs(adapter)
// viewPager.offscreenPageLimit = 3
viewPager.adapter = adapter
initTabLayout()
}
//assign icons to the TabLayout
#SuppressLint("NewApi")
fun setTabIcons(){
tabLayout.getTabAt(0)!!.setIcon(ContextCompat.getDrawable(applicationContext,R.mipmap.ic_launcher))
tabLayout.getTabAt(1)!!.setIcon(ContextCompat.getDrawable(applicationContext,R.mipmap.ic_launcher))
tabLayout.getTabAt(2)!!.setIcon(ContextCompat.getDrawable(applicationContext,R.mipmap.ic_launcher))
}
#SuppressLint("NewApi")
fun initTabLayout(){
tabLayout!!.setupWithViewPager(pager)
setTabIcons()
}
//assign Fragments associated with a specific Tab Item
private fun setTabs(adapter:ViewPagerAdapter){
adapter.addFragment(FragmentOne(), "")
adapter.addFragment(FragmentTwo(), "")
adapter.addFragment(FragmentThree(), "")
}
}
class ViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager){
private val mFragmentList = ArrayList<Fragment>()
private val mFragmentTitleList = ArrayList<String>()
override fun getItem(position: Int): Fragment {
return mFragmentList[position]
}
override fun getCount(): Int {
return mFragmentList.size
}
fun addFragment(fragment: Fragment, title: String){
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
override fun getPageTitle(position:Int): CharSequence{
return mFragmentTitleList.get(position)
}
}
Your single fragment will look something like:
class FragmentOne : Fragment() {
lateinit var rootView:View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
rootView = inflater.inflate(R.layout.fragment_view,container,false)
rootView.findViewById<TextView>(R.id.textView).setText("Fragment One")
return rootView
}
}
Your view will look something like this (in this case it is named fragment_view.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/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
app:tabMode="fixed"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#FFF"
android:elevation="6dp"
android:layout_gravity="bottom"
app:tabGravity="center"
app:tabRippleColor="#color/colorAccent"
app:tabPaddingStart="35dp"
app:tabPaddingEnd="35dp"
app:tabBackground="#android:color/transparent"
app:tabTextColor="#color/colorPrimaryDark"
app:tabSelectedTextColor="#color/colorPrimaryDark"
app:tabIndicatorColor="#android:color/transparent"
android:minHeight="?attr/actionBarSize"
/>
I've got a CoordinatorLayout which contains a CollapsingToolbarLayout and a RecyclerView. Everything looks the way it's supposed to, except that when I try to scroll to the last item programmatically, it doesn't go all the way to the bottom. Instead, it does this:
I don't think this is a clipping problem, since the bottom item is fully there if I scroll down:
Here's the main layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="16dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="#+id/toolbar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:contentInsetStart="72dp"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="#dimen/recyclerview_bottom_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
And here's the code that goes with the screencaps above:
class TestActivity : AppCompatActivity() {
private val itemNames = listOf("top item", "next item", "yada", "yada yada", "yada yada yada", "second last item", "last item")
private val selectedPosition = itemNames.size - 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.recyclerview_with_collapsing_toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setTitle(R.string.some_title)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.setHasFixedSize(true)
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = MyAdapter()
// try to scroll to the initial selected position
recyclerView.scrollToPosition(selectedPosition)
// layoutManager.scrollToPosition(selectedPosition)
// layoutManager.scrollToPositionWithOffset(selectedPosition, resources.getDimensionPixelOffset(R.dimen.item_height))
// recyclerView.post {
// recyclerView.smoothScrollToPosition(selectedPosition)
// }
}
inner class MyAdapter: RecyclerView.Adapter<MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, itemType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return itemNames.size
}
override fun onBindViewHolder(vh: MyViewHolder, position: Int) {
vh.words.text = itemNames[position]
if (selectedPosition == position) {
vh.parent.setBackgroundColor(Color.MAGENTA)
} else {
vh.parent.setBackgroundColor(Color.BLACK)
}
}
}
inner class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val parent = itemView
val words: TextView = itemView.findViewById(R.id.some_text)
}
}
Additional notes:
If I get rid of the CollapsingToolbarLayout then it does show the entire last item.
I've left some of my other attempts in the code above (commented out). None of them worked.
This example just involves a short static list and always scrolls to the same item, but the code I'm actually working on is a bit more complicated.
The designer really wants everything to look exactly as designed, and I'm not free to change the visual design.
How can I scroll to the last item in a RecyclerView that's inside a layout with a collapsing toolbar?
The problem is that getNestedScrollingParentForType(type) in NestedScrollingChildHelper#dispatchNestedScroll returns null for the non-touch scroll, so scrolling is not dispatched when it is done programmatically.
So we need to enable that before scrolling programmatically:
if (!recyclerView.hasNestedScrollingParent(ViewCompat.TYPE_NON_TOUCH)) {
recyclerView.startNestedScroll(View.SCROLL_AXIS_VERTICAL,ViewCompat.TYPE_NON_TOUCH);
}
// now smooth scroll your recycler view programmatically here.
A fix for this problem would be to collapse the toolbar before scrolling to the given position. This can be done by adding app_bar_layout.setExpanded(false) before scrollToPosition.