ViewPager,ViewPager2 无限轮播功能。自定义 Indicator,支持一屏三页,支持仿魅族 banner 效果。极其简单的使用方式

banner

项目地址:zguop/banner 

简介: 🔥🔥ViewPager,ViewPager2 无限轮播功能。自定义 Indicator,支持一屏三页,支持仿魅族 banner 效果。极其简单的使用方式

更多:作者   提 Bug   

标签:

全新升级,基于ViewPager2实现无限轮播功能。可以自定义 indicator,需自定义实现 Indicator 接口,内置了的 IndicatorView,支持五种动画切换。支持传入 RecyclerView.Adapter 即可实现无限轮播,支持任何 ReyclerView.Apdater 框架,集成使用请参考 Demo。

  • 支持自动轮播
  • 支持一屏三页
  • 支持自定义 Indicator
  • 支持自定义 view
  • 支持垂直滚动
  • 支持任意 RecyclerView.adapter
  • 目前就 4 个类,良好的代码封装,更多请参考代码实现。

ViewPager2 是 androidx 中的 还在使用 support 请使用 ViewPager 版本(持续维护...)banner 请点击

效果图

点击下载 banner.apk 体验


基本使用的功能,请下载 apk 体验更流畅
描述普通样式两边缩放
一屏三页
IndicatorViewIndicatorStyle
INDICATOR_CIRCLEINDICATOR_CIRCLE_RECT
INDICATOR_BEZIERINDICATOR_DASH
INDICATOR_BIG_CIRCLE

注意:0.0.5 版本开始,IndicatorView 更新

  • INDICATOR_DASH:不再提供默认的长度,默认是没有长度的,一定要设置 setIndicatorSelectedRatio 属性,将圆点进行拉伸为矩形。

  • INDICATOR_BIG_CIRCLE:不再提供默认的 Max 圆,默认是一样大的,所以看起来没有效果,一定要设置 indicatorSelectedRadius 属性,控制选中的大小。

效果图12
收集更多的效果
Indicator 查看 simple 代码

...

版本更新内容点击查看

使用步骤

Step 1.依赖 banner

Gradle

    repositories {
        mavenCentral()
    }

dependencies{
    //已迁移至 mavenCentral
    implementation 'io.github.zguop:pager2Banner:1.0.5'
}

或者引用本地 lib

compile project(':pager2banner')

Step 2.xml

     <com.to.aboomy.pager2banner.Banner
        android:id="@+id/banner"
        android:layout_width="match_parent"
        android:layout_height="150dp"/>

Step 3.自定义 RecyclerView.Adapter

//自定义 adapter
public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> 

//或者使用其他三方框架,都是支持的,如:BRVAH
public class ImageAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
    public ImageAdapter() {
        super(R.layout.item_image);
    }
    @Override
    protected void convert(@NonNull BaseViewHolder helper, String item) {
        Glide.with(mContext)
                .load(item)
                .into((ImageView) helper.getView(R.id.img));
    }
}

Step 4.在页面中使用 Banner


 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        banner = findViewById(R.id.banner);

        //使用内置 Indicator
        IndicatorView indicator = new IndicatorView(this)
              .setIndicatorColor(Color.DKGRAY)
              .setIndicatorSelectorColor(Color.WHITE);

        //创建 adapter
          ImageAdapter adapter = new ImageAdapter();

          //传入 RecyclerView.Adapter 即可实现无限轮播
         banner.setIndicator(indicator)
              .setAdapter(adapter);
    }

简单设置一屏三页效果


//设置左右页面露出来的宽度及 item 与 item 之间的宽度
.setPageMargin(UIUtil.dip2px(this, 20), UIUtil.dip2px(this, 10))
//内置 ScaleInTransformer,设置切换缩放动画
.setPageTransformer(true, new ScaleInTransformer())

支持访魅族样式

//单独设置 OverlapSliderTransformer,项目里有,可以拷贝到项目中使用 kotlin 实现的-。-
 .addPageTransformer(new OverlapSliderTransformer(banner.getViewPager2().getOrientation(), 0.25f, 0, 1,0))

关于 ViewPager 切换动画

pager2banner 只内置了 ScaleInTransformer ,这个比较常用。 demo 里集成了以下两个 ViewPager 切换动画,请运行 Sample 查看动画效果,需要哪个拷贝到项目中用好了。

ViewPagerTransforms

MagicViewPager

介绍一下 IndicatorView

内置的 indicator 很强大,可以做到很多效果了,很灵活,可以运行 demo 尝试改变一下参数:

    .setIndicatorRatio(1f) //ratio,默认值是 1 ,也就是说默认是圆点,根据这个值,值越大,拉伸越长,就成了矩形,小于 1,就变扁了呗
    .setIndicatorRadius(2f) // radius 点的大小
    .setIndicatorSelectedRatio(3) 
    .setIndicatorSelectedRadius(2f)
    .setIndicatorStyle(IndicatorView.IndicatorStyle.INDICATOR_BIG_CIRCLE)

如何自定义 Indicator

/**
 * 可以实现该接口,自定义 Indicator 可参考内置的{@link IndicatorView}
 */
public interface Indicator {

    /**
     * 当数据初始化完成时调用
     *
     * @param pagerCount pager 数量
     */
    void initIndicatorCount(int pagerCount);

    /**
     * 返回一个 View,添加到 banner 中
     */
    View getView();

    /**
     * banner 是一个 RelativeLayout,设置 banner 在 RelativeLayout 中的位置,可以是任何地方
     */
    RelativeLayout.LayoutParams getParams();

    void onPageScrolled(int position, float positionOffset, @Px int positionOffsetPixels);

    void onPageSelected(int position);

    void onPageScrollStateChanged(int state);
}

//举个栗子
public class IndicatorView extends View implements Indicator{

        @Override
        public void initIndicatorCount(int pagerCount) {
            this.pagerCount = pagerCount;
            setVisibility(pagerCount > 1 ? VISIBLE : GONE);
            requestLayout();
        }

        @Override
        public View getView() {
            return this;
        }
         /**
          * 控制 Indicator 在 Banner 中的位置,开发者自行实现
          */
        @Override
        public RelativeLayout.LayoutParams getParams() {
            if (params == null) {
                params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                params.addRule(RelativeLayout.CENTER_HORIZONTAL);
                params.bottomMargin = dip2px(10);
            }
            return params;
        }
        /**
          * banner 切换时同步回调的三个方法
          */
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            selectedPage = position;
            offset = positionOffset;
            invalidate();
        }

        @Override
        public void onPageSelected(int position) {
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }
}
方法名描述
addPageTransformer(ViewPager2.PageTransformer transformer)设置 viewpager2 的自定义动画,支持多个添加
setOuterPageChangeListener(ViewPager2.OnPageChangeCallback listener)设置 viewpager2 的滑动监听
setAutoTurningTime(long autoTurningTime)设置自动轮播时长
setAutoPlay(boolean autoPlay)设置是否自动轮播,大于 1 页可以轮播
setIndicator(Indicator indicator)设置 indicator
setIndicator(Indicator indicator, boolean attachToRoot)设置 indicator
setAdapter(@Nullable RecyclerView.Adapter adapter)加载数据,此方法时开始轮播的方法,请再最后调用
setAdapter(@Nullable RecyclerView.Adapter adapter, int startPosition)重载方法,设置轮播的起始位置
isAutoPlay()是否无限轮播
getCurrentPager()获取 viewPager2 当前位置
startTurning()开始轮播
stopTurning()停止轮播
setPageMargin(int multiWidth, int pageMargin)设置一屏多页
setPageMargin(int leftWidth, int rightWidth, int pageMargin)设置一屏多页,方法重载
setOffscreenPageLimit(int limit)同 viewPager2 用法
setOrientation(@ViewPager2.Orientation int orientation)设置 viewpager2 滑动方向
ViewPager2 getViewPager2()获取 viewpager2
RecyclerView.Adapter getAdapter()获取 apdater
setPagerScrollDuration(long pagerScrollDuration)设置 viewpager2 的切换时长

内置 IndicatorView 使用方法介绍,没有提供任何自定义属性

方法名描述
setIndicatorRadius(float indicatorRadius)设置圆点半径
setIndicatorSpacing(float indicatorSpacing)设置圆点间距
setIndicatorStyle(@IndicatorStyle int indicatorStyle)设置圆点切换动画,内置五种切换动画,请参考 Sample
setIndicatorColor(@ColorInt int indicatorColor)设置默认的圆点颜色
setIndicatorSelectorColor(@ColorInt int indicatorSelectorColor)设置选中的圆点颜色
setParams(RelativeLayout.LayoutParams params)设置 IndicatorView 在 banner 中的位置,默认底部居中,距离底部 10dp,请参考 Sample
setIndicatorRatio(float indicatorRatio)设置 indicator 比例,拉伸圆为矩形,设置越大,拉伸越长,默认 1.0
setIndicatorSelectedRadius(float indicatorSelectedRadius)设置选中的圆角,默认和 indicatorRadius 值一致,可单独设置选中的点大小
setIndicatorSelectedRatio(float indicatorSelectedRatio)设置选中圆比例,拉伸圆为矩形,控制该比例,默认比例和 indicatorRatio 一致,默认值 1.0

总结

- xiexie ni de guāng gù ! 喜欢的朋友轻轻右上角赏个 star,您的鼓励会给我持续更新的动力。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现这个功能,可以通过在 ViewPager2 的 Adapter 中重写 `onViewAttachedToWindow()` 方法来控制页面的滑动。具体步骤如下: 1. 在 Adapter 中定义一个变量 `fixedPosition`,表示固定位置的页面的索引。 2. 在 `onViewAttachedToWindow()` 方法中,判断当前绑定的页面是否是固定位置的页面,如果是,则将其禁止滑动;否则,保持正常的滑动行为。 示例代码如下: ```java public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private List<Fragment> fragments; private int fixedPosition; public MyAdapter(List<Fragment> fragments, int fixedPosition) { this.fragments = fragments; this.fixedPosition = fixedPosition; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_page, parent, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.bind(fragments.get(position)); } @Override public int getItemCount() { return fragments.size(); } @Override public void onViewAttachedToWindow(@NonNull MyViewHolder holder) { super.onViewAttachedToWindow(holder); int position = holder.getAdapterPosition(); if (position == fixedPosition) { holder.itemView.setTranslationX(0); holder.itemView.setClickable(false); } else { holder.itemView.setTranslationX(-holder.itemView.getWidth() / 3f); holder.itemView.setClickable(true); } } static class MyViewHolder extends RecyclerView.ViewHolder { private TextView textView; public MyViewHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.text); } public void bind(Fragment fragment) { textView.setText(fragment.toString()); } } } ``` 在这个示例中,我们假设 `fixedPosition` 为 0,表示第一个页面是固定位置的页面。在 `onViewAttachedToWindow()` 方法中,如果当前绑定的页面是第一个页面,则将其禁止滑动,否则将其向左平移 1/3 的宽度,并启用点击事件。 注意:这种方式只是实现了页面不滑动的效果,但是用户仍然可以通过点击页面来切换页面。如果需要完全禁止用户切换页面,可以在禁止页面滑动的同时,禁用 ViewPager2 的滑动事件。 希望这个回答能够帮到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值