ConstraintLayout2.0一篇写不完之Carousel

点击上方蓝字关注我,知识会给你力量

本文译自 https://github.com/androidx/constraintlayout/wiki/Carousel

Carousel是一个Motion Helper,它可以轻松构建自定义的Carousel视图,显示用户可以浏览的元素列表。与实现此类视图的其他解决方案相比,Carousel可以利用MotionLayout迅速为轮播创建复杂的动画效果。

Carousel支持带有开始和结束的列表以及循环环绕列表。

概念:轮播如何MotionLayout工作

假设我们要构建一个简单的水平轮播视图,并放大一个居中视图:

我们的基本布局包含几个视图,代表了我们的轮播项目:

通过MotionLayout创建具有三个状态的ConstraintSet(请确保为它们提供ID):

  • previous

  • start

  • next

如果start状态与该基本布局相对应,则previous的状态则应该表示为轮播项目向右移动一个。

例如,假设我们有5个视图:处于开始状态的A,B,C,D,E。

start时,B,C,D可见,而A和E在屏幕外。我们要设置previous的状态,以使A,B,C,D的位置现在位于B,C,D,E所在的位置,并且视图从左向右移动。

在next状态中,需要相反的情况发生,与B,C,D,E移动到其中A,B,C,D分别为和的观点从从右向左移动。

至关重要的是,start状态必须恰好位于原始视图的起始状态。这种无限轮播的错觉的方式,实际上是将实际视图移回它们的位置,然后使用新的匹配内容将其重新初始化。下图显示了这种机制(请注意“ item#”值):

转场Transitions

在ConstraintSet中定义的这三个状态,在start和next,以及start和previous之间创建两个Transitions:向前和向后。让我们添加一个OnSwipe,以通过手势触发Transitions,例如:

    <Transition
        motion:constraintSetStart="@id/start"
        motion:constraintSetEnd="@+id/next"
        motion:duration="1000"
        android:id="@+id/forward">
        <OnSwipe
            motion:dragDirection="dragLeft"
            motion:touchAnchorSide="left" />
    </Transition>

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/previous"
        android:id="@+id/backward">
        <OnSwipe
            motion:dragDirection="dragRight"
            motion:touchAnchorSide="right" />
    </Transition>

添加轮播

一旦创建了这个基本的Motion Scene,我们只需要在布局中添加一个Carousel Help并引用这些视图即可(以实现上一个/下一个动画的顺序)。

Carousel Helper还需要设置几个属性:

  • app:carousel_firstView:表示轮播的第一个元素的视图,在我们的示例中为C,即首先展示默认居中的视图

  • app:carousel_previousState:ConstraintSet中previous状态的ID

  • app:carousel_nextState:ConstraintSet中next状态的ID

  • app:carousel_backwardTransition:Transition在start->previous之间应用的ID

  • app:carousel_forwardTransition:Transition在start->next之间应用的ID

例如,您的布局XML文件中将包含以下内容:

    <androidx.constraintlayout.motion.widget.MotionLayout ... >

        <ImageView  android:id="@+id/imageView0" .. />
        <ImageView  android:id="@+id/imageView1" .. />
        <ImageView  android:id="@+id/imageView2" .. />
        <ImageView  android:id="@+id/imageView3" .. />
        <ImageView  android:id="@+id/imageView4" .. />

        <androidx.constraintlayout.helper.widget.Carousel
            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" />

    </androidx.constraintlayout.motion.widget.MotionLayout>

最后,我们还需要在代码中设置一个Carousel适配器:

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
            }
        })

Additional

根据轮播中当前选中的项目,你可能需要隐藏表示之前或之后的项目的视图,以便正确考虑轮播的开始和结束。Carousel Helper将自动为您处理此问题,默认情况下会将这些视图标记为 View.INVISIBLE在那种情况下(这样,整体布局不会改变)。

可以使用另一种模式,其中Carousel Helper将这些视图标记为View.GONE。可以使用以下属性设置此模式:

app:carousel_emptyViewsBehavior="gone"

向大家推荐下我的网站 https://xuyisheng.top/  点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

往期推荐

本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

< END >

作者:徐宜生

更文不易,点个“三连”支持一下????

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这里给您提供一个简单的carousel示例,使用HTMLCSS和JavaScript实现: HTML代码: ``` <div class="carousel-container"> <div class="carousel-slide"> <img src="https://via.placeholder.com/500x250?text=Slide%201" alt="Slide 1"> <img src="https://via.placeholder.com/500x250?text=Slide%202" alt="Slide 2"> <img src="https://via.placeholder.com/500x250?text=Slide%203" alt="Slide 3"> </div> <button class="carousel-prev">❮</button> <button class="carousel-next">❯</button> </div> ``` CSS代码: ``` .carousel-container { position: relative; width: 500px; height: 250px; margin: 0 auto; overflow: hidden; } .carousel-slide { display: flex; width: 100%; height: 100%; } .carousel-slide img { width: 100%; height: 100%; object-fit: cover; } .carousel-prev, .carousel-next { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; background-color: rgba(0, 0, 0, 0.5); color: #fff; border: none; outline: none; cursor: pointer; } .carousel-prev { left: 0; } .carousel-next { right: 0; } ``` JavaScript代码: ``` const carouselSlide = document.querySelector(".carousel-slide"); const carouselImages = document.querySelectorAll(".carousel-slide img"); // Buttons const prevBtn = document.querySelector(".carousel-prev"); const nextBtn = document.querySelector(".carousel-next"); // Counter let counter = 1; const size = carouselImages[0].clientWidth; carouselSlide.style.transform = "translateX(" + (-size * counter) + "px)"; // Button listeners nextBtn.addEventListener("click", () => { if (counter >= carouselImages.length - 1) return; carouselSlide.style.transition = "transform 0.4s ease-in-out"; counter++; carouselSlide.style.transform = "translateX(" + (-size * counter) + "px)"; }); prevBtn.addEventListener("click", () => { if (counter <= 0) return; carouselSlide.style.transition = "transform 0.4s ease-in-out"; counter--; carouselSlide.style.transform = "translateX(" + (-size * counter) + "px)"; }); // Transition listener carouselSlide.addEventListener("transitionend", () => { if (carouselImages[counter].alt === "lastClone") { carouselSlide.style.transition = "none"; counter = carouselImages.length - 2; carouselSlide.style.transform = "translateX(" + (-size * counter) + "px)"; } if (carouselImages[counter].alt === "firstClone") { carouselSlide.style.transition = "none"; counter = carouselImages.length - counter; carouselSlide.style.transform = "translateX(" + (-size * counter) + "px)"; } }); ``` 这个示例实现了一个基本的carousel功能,包括图片轮播和左右箭头按钮。您可以根据自己的需求进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值