2

I have a RecyclerView with an Adapter which holds two different kinds of views. The first view has a slightly bigger width and height than the following views.

When starting the activity which contains the RecyclerView, I want to scroll to a certain position in the Adapter. I do this by calling scrollToPositionWithOffset(position, offset) on the LinearLayoutManager which is connected to the RecyclerView.

The following code roughly describes the setup (nothing unusual). The activity which contains the RecyclerView calls Timeline.scrollTo(position). Please bear with me for posting Scala code.

Activity which holds the RecyclerView

class Activity extends [...] {

    lazy val timeline = findView( TR.layout_screen_transaction_timeline )

    override def onCreate( state: Option[Bundle] ) = {
        super.onCreate( state )

        setContentView( R.layout.screen_transaction_timeline )

        [...]

        timeline.setAdapter( adapter )

        if ( state.isEmpty ) {
            focus.foreach { position ⇒
                new Handler().post { () ⇒
                    timeline.scrollTo( position )
                }
            }
        }
    }

RecyclerView with LinearLayoutManager

class Timeline( attributes: AttributeSet = null, style: Int = 0 )( implicit context: Context )
    extends RecyclerView( context, attributes, style ) {
    [...]

    setHasFixedSize( true )
    setLayoutManager( layoutManager )

    def scrollTo( position: Int ) = {
        layoutManager.scrollToPositionWithOffset( position, 0 )
    }

    object layoutManager extends LinearLayoutManager( context, VERTICAL, false )
}

Adapter

object adapter extends Adapter[Holder] {
    override def getItemCount = tour.shipments.length + 1

    override def onBindViewHolder( holder: Holder, position: Int ) = holder.view match {
        case collection: widget.transaction.timeline.Header ⇒
            collection.set( tour.collection, tour, tour.state == Tour.State.New )
        case waypoint: widget.transaction.timeline.Waypoint ⇒
            waypoint.set( position, tour.shipments( position - 1 ), focus.contains( position ) )
    }

    override def onCreateViewHolder( parent: ViewGroup, kind: Int ) = Holder {
        val view = kind match {
            case 0 ⇒ new widget.transaction.timeline.Header()
            case 1 ⇒ new widget.transaction.timeline.Waypoint()
        }

        view.setLayoutParams( new RecyclerView.LayoutParams( MATCH_PARENT, WRAP_CONTENT ) )
        view
    }

    override def getItemViewType( position: Int ) = position match {
        case 0 ⇒ 0
        case _ ⇒ 1
    }
}

Everything works fine except when I want to scroll to the last position. In that case the LinearLayoutManager sometimes scrolls to the position correctly and sometimes in a way which is slightly off.

Update: I just found out that removing the ActionBar in the activity which holds the RecyclerView resolves this issue. However I need an ActionBar...

enter image description here

tymm
  • 543
  • 1
  • 6
  • 18
  • 1
    Have you tried using [scrollToPosition](http://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#scrollToPosition(int)) on the recyclerview rather than directly calling the linearlayout implementation? – cziemba Dec 02 '15 at 19:07
  • 1
    Yes, I did. Did not work. – tymm Dec 02 '15 at 19:09

0 Answers0