先看一下效果

ViewPager无限循环实现画廊式banner_第1张图片

两边显示上一个和下一个item部分布局,可以自动滚动

实现:

布局

主要属性:android:clipChildren="false" //允许子布局超出父布局显示

xml代码:

<?xml version="1.0" encoding="utf-8"?>        

Adapter

没什么特别的只要 getCount()返回一个很大的值如:return Integer.MAX_VALUE;

适配器代码:

package com.guzhc.module_demo;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.view.ViewParent;import android.widget.ImageView;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.viewpager.widget.PagerAdapter;import com.bumptech.glide.Glide;import java.util.ArrayList;import java.util.List;/** * @author : GuZhC * @date :  2019/6/1 9:46 * @description : 顶部banner viewPager 适配器 */public class ShortViewoViewPagerAdapter extends PagerAdapter {    private final Context context;    private final List mData;    private PagerClick pagerClick;    public ShortViewoViewPagerAdapter(List mData, Context context) {        this.mData = mData;        this.context = context;    }    @Override    public int getCount() {        return Integer.MAX_VALUE;    }    @Override    public void destroyItem(ViewGroup container, int position,                            Object object) {        //Warning:不要在这里调用removeView    }    @Override    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {        return view == object;    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        position %= mData.size();        final String data = mData.get(position);        View view =  View.inflate(container.getContext(),R.layout.demo_item_short_video_viewpager, null);        ImageView img = view.findViewById(R.id.demo_img_short_video_item);        TextView tvContent = view.findViewById(R.id.demo_tv_short_video_item);        tvContent.setText(data);        Glide.with(context)                .load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559367407524&di=2a7d6a1a12707287e908d61922a637c2&imgtype=0&src=http%3A%2F%2Fpic72.nipic.com%2Ffile%2F20150715%2F9448607_192612583000_2.jpg")                .into(img);        //对ViewPager页号求模取出View列表中要显示的项        if (position < 0) {            position = mData.size() + position;        }        //如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。        ViewParent vp = view.getParent();        if (vp != null) {            ViewGroup parent = (ViewGroup) vp;            parent.removeView(view);        }        container.addView(view);              return view;    }  }

调用

注意:两边的item滑动没有效果吗,需要将容器的触摸事件反馈给ViewPager

    //设置banner        shortViewoViewPagerAdapter = new ShortViewoViewPagerAdapter(mData, getContext());        View bannerView = LayoutInflater.from(getContext()).inflate(R.layout.demo_layout_short_video_banner, null);        viewPagerBanner = bannerView.findViewById(R.id.demo_vp_short_video_top);        LinearLayout mViewPagerContainer = bannerView.findViewById(R.id.demo_ll_short_video_vp_root);        viewPagerBanner.setAdapter(shortViewoViewPagerAdapter);        viewPagerBanner.addOnPageChangeListener(this);        //将容器的触摸事件反馈给ViewPager        mViewPagerContainer.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                return viewPagerBanner.dispatchTouchEvent(event);            }        });

 

无限循环:方式很多,这里用的Handler实现

设置viewPager.addOnPageChangeListener(this)实现接口重写方法:实现滑动时候暂停自动滑动,停止的时候开启

重写方法代码:

@Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        handler.sendMessage(Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED, position, 0));    }    @Override    public void onPageSelected(int position) {    }    @Override    public void onPageScrollStateChanged(int state) {        switch (state) {            //滑动中            case ViewPager.SCROLL_STATE_DRAGGING:                handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);                break;            //未滑动            case ViewPager.SCROLL_STATE_IDLE:                handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);                break;            default:                break;        }    }

Handler代码:

public class ImageHandler extends Handler {    /**     * 请求更新显示的View。     */    protected static final int MSG_UPDATE_IMAGE  = 1;    /**     * 请求暂停轮播。     */    protected static final int MSG_KEEP_SILENT   = 2;    /**     * 请求恢复轮播。     */    protected static final int MSG_BREAK_SILENT  = 3;    /**     * 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。     * 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,     * 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。     */    protected static final int MSG_PAGE_CHANGED  = 4;    //轮播间隔时间    protected static final long MSG_DELAY = 5000;    //使用弱引用避免Handler泄露.    private WeakReference weakReference;    private int currentItem = 0;    protected ImageHandler(WeakReference wk){        weakReference = wk;    }    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        ShortVedioFragmet shortVedioFragmet = weakReference.get();        if (shortVedioFragmet==null){            //Activity已经回收,无需再处理UI了            return ;        }        //检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。        if (shortVedioFragmet.handler.hasMessages(MSG_UPDATE_IMAGE)){            shortVedioFragmet.handler.removeMessages(MSG_UPDATE_IMAGE);        }        switch (msg.what) {            case MSG_UPDATE_IMAGE:                currentItem++;                shortVedioFragmet.viewPagerBanner.setCurrentItem(currentItem);                //准备下次播放                shortVedioFragmet.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);                break;            case MSG_KEEP_SILENT:                //只要不发送消息就暂停了                break;            case MSG_BREAK_SILENT:                shortVedioFragmet.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);                break;            case MSG_PAGE_CHANGED:                //记录当前的页号,避免播放的时候页面显示不正确。                currentItem = msg.arg1;                break;            default:                break;        }    }}

如果是viewpager嵌套Fragment的界面中使用可以通过setUserVisibleHint(boolean isVisibleToUser)方法这样开启和暂停:

setUserVisibleHint()方法会在fragment显示和隐藏的时候被调用

@Override    public void setUserVisibleHint(boolean isVisibleToUser) {        super.setUserVisibleHint(isVisibleToUser);        if(isVisibleToUser) {            //相当于OnResume(),可以做相关逻辑            //开始轮播效果            handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);        }else {            //相当于OnPause()            //暂停轮播效果            handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);        }    }

在Activity使用 可以在onResum() 和onPause()开启可暂停。

至此完成。

更多相关文章

  1. 安卓霓虹灯效果
  2. 后台动态添加布局文件、控件与动态设置属性2
  3. Android TextView 中文本横向滚动效果实现
  4. androidUI布局仿猫扑界面
  5. Android UI开发第八篇――ViewFlipper 左右滑动效果
  6. [Tools]Android Studio代码提示功能--Ctrl+Alt+Space(空格键)
  7. Android Layout 布局 && Android自带样式(theme)&& CheckBox样例 &
  8. 使用Android常用控件与布局实现美观的登录页面

随机推荐

  1. Android train——基本组件LinearLayout
  2. android AIDL简单步骤
  3. android的listview 嵌套在 ViewPage 多次
  4. android开机自启动apk的方法
  5. Android应用程序打包时,出现错误:Android(
  6. mac下面更新Android SDK(解决无法下载)
  7. android studio对于错误拼写/不识别的英
  8. Android HelloWorld出现error generating
  9. textview设置字体以及引入新字体
  10. 操作android中的通讯录