android:layout_with="",Carousel with MotionLayout

a8c518569fe4332dd27d29a3c17ec8b7.gif

Carousel is a motion helper object to easily build custom "carousel"

views – showing a list of elements that a user can skim through.

Compared to other solutions to implement such views, this helper lets you

quickly create complex motion and dimension changes for your carousel by taking

advantage of MotionLayout.

The Carousel widget supports lists with a start and end as well as circular

wrap-around lists.

Concept: How Carousel with MotionLayout works

Let's imagine that we want to build a simple horizontal carousel view, with

a centered view enlarged:

3419af876c064a34269514d3d2464b9c.png

Our basic layout contains several views, representing our carousel items:

05dc7e3420c77b9e3192b1ffbf46e429.png

Create a MotionLayout with three states (make sure to give them Ids):

previous

start

next

If the start state corresponds to that base layout, the previous state

should be done in such a way that the carousel items will be shifted by one.

For example let's imagine we have 5 views: A, B, C, D, E in the start state,

with B, C, D visible and A and E outside of the screen. We want to set up

the previous state such that the positions of A, B, C, D now are where B,

C, D, E were, with the views moving from left to right. In the

next state, the opposite needs to happen, with B, C, D, E moving to where

A, B, C, D were, and the views moving from right to left.

53c0c42f7892922d506019dda4984e91.png

What is critical is that the views end up exactly where the original views

started; the way the carousel give the illusion of an infinite collection of

elements is by moving the actual views back to where they were, but

reinitializing them with the new matching content. The following diagram

shows this mechanism (pay attention to the "item #" values):

073e7d075458b5c6b90256abc8d1f7fd.png

Transitions

With those three ConstraintSets defined in your motion scene file,

create two transitions – forward and backward – between the start

and next, and start and previous. Let's add an OnSwipe

handler to trigger the transitions via a gesture. For example:

motion:constraintSetStart="@id/start"

motion:constraintSetEnd="@+id/next"

motion:duration="1000"

android:id="@+id/forward">

motion:dragDirection="dragLeft"

motion:touchAnchorSide="left" />

motion:constraintSetStart="@+id/start"

motion:constraintSetEnd="@+id/previous"

android:id="@+id/backward">

motion:dragDirection="dragRight"

motion:touchAnchorSide="right" />

Adding the Carousel

Once this basic motion scene is created, we only need to add a Carousel

helper to the layout and references those views (in the same order we

implemented our previous/next animation).

The Carousel helper also need a couple of attributes to be set up:

app:carousel_firstView: the view that will represent the first element of

the carousel, in our example, C

app:carousel_previousState: the ConstraintSet id of the previous state

app:carousel_nextState: the ConstraintSet id of the next state

app:carousel_backwardTransition: the Transition

id applied between start -> previous

app:carousel_forwardTransition: the Transition id applied between

start -> next

For example, you'd have something like this in your layout XML file:

android:id="@+id/carousel"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

app:carousel_forwardTransition="@+id/forward"

app:carousel_backwardTransition="@+id/backward"

app:carousel_previousState="@+id/previous"

app:carousel_nextState="@+id/next"

app:carousel_infinite="true"

app:carousel_firstView="@+id/imageView2"

app:constraint_referenced_ids="imageView0,imageView1,imageView2,imageView3,imageView4" />

Finally, we also need to set up a Carousel adapter in code:

Kotlin

carousel.setAdapter(object : Carousel.Adapter {

override fun count(): Int {

// need to return the number of items we have in the carousel

}

override fun populate(view: View, index: Int) {

// need to implement this to populate the view at the given index

}

override fun onNewItem(index: Int) {

// called when an item is set

}

})Java

carousel.setAdapter(new Carousel.Adapter() {

@Override

public int count() {

// need to return the number of items we have in the carousel

}

@Override

public void populate(View view, int index) {

// need to implement this to populate the view at the given index

}

@Override

public void onNewItem(int index) {

// called when an item is set

}

});

Additional notes

Depending on the current item "selected" in the Carousel, the views

representing the items before or after may need to be hidden in order to

correctly account for the Carousel start and end. The Carousel helper

will handle this automatically for you, by default marking those views as

View.INVISIBLE in those situations (so the overall layout doesn't change).

An alternative mode is available in which the Carousel helper instead marks

those views as View.GONE. This mode can be set using the following property:

app:carousel_emptyViewsBehavior="gone"

Examples

For more examples using the Carousel helper, see the example projects

on GitHub.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值