Kotlin / anko

Pleasant Android application development
Apache License 2.0
15.89k stars 1.29k forks source link

Anko Layout on CoordinatorLayout has a weird AppBarLayout.ScrollingViewBehavior #514

Closed muhrifqii closed 6 years ago

muhrifqii commented 6 years ago

I search the anko layout sample for coordinatorlayout looks like they are perfectly works. But when I tried to implemented it, it has a strange behavior. I used anko version 0.10.2

class MainActivityUI(
    val adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>) : AnkoComponent<MainActivity> {
  override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) {
    coordinatorLayout {
      fitsSystemWindows = true
      themedAppBarLayout(R.style.AppTheme_AppBarOverlay) {
        toolbar {
          id = Ids.toolbar
          setTitleTextColor(WHITE)
          popupTheme = R.style.AppTheme_PopupOverlay
          lparams(width = matchParent)
        }
      }.lparams(width = matchParent) {
//        behavior = AppBarLayout.ScrollingViewBehavior()
      }
      recyclerView {
        id = Ids.mainList
        layoutManager = LinearLayoutManager(ctx)
        adapter = this@MainActivityUI.adapter
      }.lparams(width = matchParent, height = matchParent) {
        behavior = AppBarLayout.ScrollingViewBehavior()
      }
      floatingActionButton {
        id = Ids.faButton
        imageResource = R.drawable.ic_add_circle_white
      }.lparams {
        gravity = Gravity.RIGHT or Gravity.BOTTOM
        margin = dip(16)
      }
    }
  }
}

With this code, the whole view (including toolbar) have the scrolling behavior. If I un-comment that appbar's lparam behavior, the toolbar position fixed and not scrolled, but the recyclerview height is overlapping at the bottom side. Is there something wrong with this or I do a silly mistake? Thanks

4u7 commented 6 years ago

I'm not sure what are you trying to achieve, but i think you need to set scrollFlags for toolbar. Something like scrollFlags = SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS

muhrifqii commented 6 years ago

I tried to make a trivial layout like the one when creating a new basic activity (from the android studio menu). A layout that has 1 toolbar, 1 fab, and 1 content (in my case a recyclerview) inside a coordinatorlayout. Actually a very basic layout without a collapsing toolbar

4u7 commented 6 years ago

Some examples of CoordinatorLayout with Anko: #1 #2 #3

muhrifqii commented 6 years ago

@4u7 Thank you. So in anko I have to define the scrollFlag on my toolbar whereas on xml layout I don't have to add scrollFlag to the toolbar to create a normal toolbar (non-collapsing)?

Both of these producing the same layout. The different is on the scrollfag defined on my anko to stop toolbar for scrolling up

<android.support.design.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:layout_width="match_parent"
    android:layout_height="match_parent""
    >
  <android.support.design.widget.AppBarLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      >
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        />
  </android.support.design.widget.AppBarLayout>
  <android.support.design.widget.FloatingActionButton
      android:id="@+id/addFAB"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom|right"
      android:layout_margin="16dp"
      android:src="@drawable/ic_add_circle_white"
      />

  <android.support.v7.widget.RecyclerView
      android:id="@+id/list"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:layout_behavior="@string/appbar_scrolling_view_behavior"
      />

</android.support.design.widget.CoordinatorLayout>
class MainActivityUI(
    val adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>) : AnkoComponent<MainActivity> {

  private lateinit var toolbar: Toolbar

  override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) {
    coordinatorLayout {
      fitsSystemWindows = true
      themedAppBarLayout(R.style.AppTheme_AppBarOverlay) {
        toolbar {
          id = Ids.toolbar
          setTitleTextColor(WHITE)
          popupTheme = R.style.AppTheme_PopupOverlay
        }.lparams(width = matchParent){
          scrollFlags = SCROLL_FLAG_ENTER_ALWAYS
        }
      }.lparams(width = matchParent) {
        //        behavior = AppBarLayout.ScrollingViewBehavior()
      }
      frameLayout {
        recyclerView {
          id = Ids.mainList
          layoutManager = LinearLayoutManager(ctx)
          adapter = this@MainActivityUI.adapter
          lparams(matchParent, matchParent)
        }
      }.lparams(width = matchParent, height = matchParent) {
        behavior = AppBarLayout.ScrollingViewBehavior()
      }
      floatingActionButton {
        id = Ids.faButton
        imageResource = R.drawable.ic_add_circle_white
      }.lparams {
        gravity = Gravity.RIGHT or Gravity.BOTTOM
        margin = dip(16)
      }
    }
  }
}
4u7 commented 6 years ago

There are some inconsistencies in xml and programmatically created layouts. In this case when AppBarLayout.LayoutParams is created from xml scrollFlags is initialised with 0. When you create it programmatically it is initialised with SCROLL_FLAG_SCROLL. It's a bug in design library.

muhrifqii commented 6 years ago

Thank you, I didn't even know there's such an inconsistency on creating layout in xml & programatically. It is clearer now