第一步: 初始化小圆点的容器布局
在【NewsCenterContentTabPager】文件初始化小圆点布局容器
第二步:创建小圆点,并添加到容器中
在【NewsCenterContentTabPager】文件中定义创建小圆点的方法
第三步:监听ViewPager滑动监听,动态改变滑动点的背景资源
在【NewsCenterContentTabPager】文件中给轮播图添加滑动监听,当轮播图被选中时,处理滑动点的背景资源给轮播图添加滑动监听
[Java] 纯文本查看 复制代码
//加载图片,并绑定到Viewpager上
private void initSwitchImageView() {
imageViews = new ArrayList<>();
int size = newsCenterTabBean.data.topnews.size();
for (int i = -1; i < size+1; i++) {
NewsCenterTabBean.TopNewsBean topNewsBean = null;
if(i == -1){//
//添加最后的一张图片
topNewsBean = newsCenterTabBean.data.topnews.get(size-1);
}else if(i == size){
//添加第一张图片
topNewsBean = newsCenterTabBean.data.topnews.get(0);
}else{
topNewsBean = newsCenterTabBean.data.topnews.get(i);
}
ImageView iv = new ImageView(context);
Picasso.with(context).load(topNewsBean.topimage).into(iv);
imageViews.add(iv);
}
//创建轮播图适配器
SwitchImageVPAdapter adapter = new SwitchImageVPAdapter(imageViews, newsCenterTabBean.data.topnews);
//绑定ViewPager
vpSwitchImage.setAdapter(adapter);
//设置轮播图的文字显示
tvTitle.setText(newsCenterTabBean.data.topnews.get(0).title);
//给轮播图设置滑动监听
vpSwitchImage.addOnPageChangeListener(this);
}
当轮播图被选中时,处理滑动点的背景资源
轮播图的自动切换和停止第一步:创建Handler首先在我们的NewsCenterContentTabPager页面创建Handler对象:
注意:有个boolean hasSwitch变量:改变来判断当前界面中轮播图是否已经开始轮播了。
如果以及开始轮播,就不需要重新延迟发送消失。反之,开始播放。
第二步:开始播放轮播图在NewsCenterContentTabPager类中定义开始播放轮播图
public void startSwitch(){
//注意:如果轮播图未切换轮播,开始发送消失进行,否则反之
if(!hasSwitch){
//往Handler里面的消息队列里面发送一个延时的消息
mHandler.postDelayed(new SwitchTask(),3000);
}
}
第三步:停止播放在【NewsCenterContentTabPager】文件中定义停止切换的逻辑
注意:这里的hasSwitch变量,不要忘记赋值为false。重新开始播放。
第四步:切换处理
在【NewsCenterContentTabPager】文件定义切换任务,并处理切换的任务
第五步:声明开始播放的切入点开始播放的切入点有两种情况:
第一种情况:新闻中心界面中,第一个子tab界面被选中时,开始播放
第二种情况:新闻中心界面中,每个子tab界面切换时,被选中时,开始播放
第一种情况代码实现:
在【NewsCenterFragment】文件中 initViewPager方法中进行处理
[Java] 纯文本查看 复制代码
private void initViewPager() {
//保存ViewPager显示每个条目的集合
views = new ArrayList<>();
//获取每个item的数据
for(NewsCenterBean.NewsCenterNewsTabBean tabBean:newsCenterBean.data.get(0).children){
NewsCenterContentTabPager tabPager = new NewsCenterContentTabPager(getContext());
views.add(tabPager);
}
//创建适配器
NewsCenterTabVPAdapter adapter = new NewsCenterTabVPAdapter(views,newsCenterBean.data.get(0).children);
//设置适配器
vpNewsCenterContent.setAdapter(adapter);
//让TabPagerIndicator和ViewPager进行联合
tabPageIndicator.setViewPager(vpNewsCenterContent);
//让新闻中心第一个子tab的轮播图开始切换
views.get(0).startSwitch();
//给ViewPager设置页面切换监听
//注意:ViewPager和TabPagerIndicator配合使用,监听只能设置给TabPagerIndicator
tabPageIndicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//当前的开始切换,其他的tab停止切换
for (int i = 0; i < views.size(); i++) {
NewsCenterContentTabPager tabPager = views.get(i);
if(position == i){
//选中页
tabPager.startSwitch();
}else{
//未选中页
tabPager.stopSwitch();
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
第二种情况代码实现:
给TabPagerIndicator设置滑动监听,并重写onPagerSelected方法,进行监听切换。
监听内容:
如果当前页面被选中,开始播放
如果未选中页,停止播放
在【NewsCenterFragment】文件中 initViewPager方法中进行处理
[Java] 纯文本查看 复制代码
private void initViewPager() {
//保存ViewPager显示每个条目的集合
views = new ArrayList<>();
//获取每个item的数据
for(NewsCenterBean.NewsCenterNewsTabBean tabBean:newsCenterBean.data.get(0).children){
NewsCenterContentTabPager tabPager = new NewsCenterContentTabPager(getContext());
views.add(tabPager);
}
//创建适配器
NewsCenterTabVPAdapter adapter = new NewsCenterTabVPAdapter(views,newsCenterBean.data.get(0).children);
//设置适配器
vpNewsCenterContent.setAdapter(adapter);
//让TabPagerIndicator和ViewPager进行联合
tabPageIndicator.setViewPager(vpNewsCenterContent);
//让新闻中心第一个子tab的轮播图开始切换
views.get(0).startSwitch();
//给ViewPager设置页面切换监听
//注意:ViewPager和TabPagerIndicator配合使用,监听只能设置给TabPagerIndicator
tabPageIndicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//当前的开始切换,其他的tab停止切换
for (int i = 0; i < views.size(); i++) {
NewsCenterContentTabPager tabPager = views.get(i);
if(position == i){
//选中页
tabPager.startSwitch();
}else{
//未选中页
tabPager.stopSwitch();
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
手指按下停止轮播图的切换
第一步:自定义Viewpager
[Java] 纯文本查看 复制代码
public class SwitchImageViewViewPager extends ViewPager {
private static final String TAG = "SwitchImageViewViewPager";
//控制轮播图开始和停止的对象
private NewsCenterContentTabPager tabPager;
//在哪里调用? 在加载数据成功之后,就可以把该对象设置过来
public void setTabPager(NewsCenterContentTabPager tabPager) {
this.tabPager = tabPager;
}
public SwitchImageViewViewPager(Context context) {
super(context);
}
public SwitchImageViewViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
MyLogger.i(TAG,"按下");
//停止轮播图的切换
tabPager.stopSwitch();
break;
case MotionEvent.ACTION_MOVE:
MyLogger.i(TAG,"移动");
tabPager.stopSwitch();
break;
case MotionEvent.ACTION_UP:
MyLogger.i(TAG,"弹起");
//开始切换
tabPager.startSwitch();
break;
}
return super.dispatchTouchEvent(ev);
}
}
第二步:替换ViewPager
第三步:在Viewpager中控制轮播图开始和停止要想在Viewpager中控制轮播图的播放和停止,需要在Viewpager中有NewsCenterContentTabPager对象 的引用,因为在NewsCenterContentTabPager中定义了轮播图的停止和播放轮播图的功能。因此需要传递NewsCenterContentTabPager对象给ViewPager来控制轮播图开始和停止
在【NewsCenterContentTabPager】文件中的processData方法中进行处理
[Java] 纯文本查看 复制代码
//把json字符串转换成对应的数据模型
public void processData(String json) {
Gson gson = new Gson();
newsCenterTabBean = gson.fromJson(json, NewsCenterTabBean.class);
//把数据绑定给对应的控件
bindDataToView();
//把当前的NewsCenterContentTabPager对象传递给SwitchImageViewViewPager
vpSwitchImage.setTabPager(this);
}
轮播图的无限循环-在图片的前后多添加一张图片
通过视图分析:
实现无限循环,此时需要给轮播图的前后各加一个图片,根据当前轮播图的索引,加载对应的图片。
如果当前索引为-1,加载最后一张图片
如何当前索引为图片集合size时,加载第一张图片
实现步骤第一步:添加前后各一个图片
下面简单修改一下NewsCenterContentTabpager界面的initSwitchImageView方法。
第二步:处理加载图片的逻辑
如果当前索引为-1,加载最后一张图片
如何当前索引为图片集合size时,加载第一张图片
轮播图无限循环-数据下标的修正实现步骤第一步:轮播图默认加载第一张图片
在实现无限循环的基础上,ViewPager默认加载的是,轮播图下标为0的图片,而下标为0时,加载的的图片集合中下标为1的图片。也就是最后一张图片,因此,这里我们可以通过ViewPager的setCurrentItem方法指定加载的图片
注意:
让轮播图正确加载显示第一张图片时:当我们部署到程序到手机端,切换过程中,出现了异常:
图片代码如下:
出现的原因:索引越界的异常,是因为,当轮播图从最后一张图片切换到下一张图片时,根据轮播图当前选中的position,从图片集合数据中获取图片时,索引越界了。
从图示来分析:
因此,我们要根据轮播图的下标,来计算出图片集合数据对应下标。
如何修正下标值呢?
可以在轮播图切换时,定义一个修改下标的值pageIndex,默认为0,
并获取图片集合的大小size
根据当前轮播图选中的下标,来计算加载数据的下标
如果轮播图选中下标position= 0,修正之后的下标值为:pageIndex = size - 1
如果轮播图选中的下标position = size+1,修正之后的下标值为:pageIndex = 0;
其他情况,修正下标为:pageIndex = position -1;
第二步:修正数据下标
第一步:修正数据下标
注意:下标的修正,是在轮播图Viewpager的切换监听的onPageSelected()方法处理的
注意:根据修正的下标,替换轮播图文字显示的下标和轮播图滑动点的背景下标把之前的position 替换为pageIndex。该处理逻辑也是在轮播图Viewpager的切换监听的onPageSelected()方法处理的
轮播图无限循环-向右不打开侧滑菜单
当我们切换轮播图时,如何不要侧滑菜单拦截我的滑动事件呢?
我们可以在自定义的ViewPager中,监听滑动事件,如果是左右滑动,请求侧滑菜单不要拦截滑动事件。
实现思路通过分析:
可以在Viewpager中实现dispatchTouchEvent方法
处理按下事件,记录按下的x,y坐标值
处理移动事件:
记录移动时的xy坐标
计算移动之后的xy坐标 = 移动的xy坐标 – 按下xy坐标
处理水平方向滑动并且是向右滑动时,请求外层空间不要拦截
实现步骤第一步:请求父控件不要拦截
自定义ViewPager【SwitchImageViewViewPager】,并实现dispatchTouchEvent方法,在该方法中处理按下和移动事件:
处理按下事件,记录按下的x,y坐标值
处理移动事件:
记录移动时的xy坐标
计算移动之后的xy坐标 = 移动的xy坐标 – 按下xy坐标
处理水平方向滑动并且是向右滑动时,请求外层空间不要拦截
轮播图的点击事件实现思路可以监听轮播图的抬起事件,来处理点击事件。
处理逻辑:
在自定义的Viewpager中实现dispatchTouchEvent方法
处理按下事件,记录按下的x,y坐标值
处理抬起事件:记录抬起的xy坐标
如果按下的xy坐标和抬起的xy坐标一致时,实现点击事件
实现步骤:在自定义的Viewpager中【SwitchImageViewViewPager】实现dispatchTouchEvent方法
处理按下事件,记录按下的x,y坐标值
处理抬起事件:记录抬起的xy坐标
如果按下的xy坐标和抬起的xy坐标一致时,实现点击事件