黑马程序员技术交流社区

标题: 【济南中心】Android课程同步笔记智慧北京:Day03(下) [打印本页]

作者: 小鲁哥哥    时间: 2017-5-14 19:56
标题: 【济南中心】Android课程同步笔记智慧北京:Day03(下)
本帖最后由 小鲁哥哥 于 2017-5-14 20:14 编辑

【济南中心】Android课程同步笔记智慧北京:Day03(下)

轮播图滑动点的切换

第一步: 初始化小圆点的容器布局
在【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类中定义开始播放轮播图
[Java] 纯文本查看 复制代码
//开始切换
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坐标一致时,实现点击事件









作者: Windycom    时间: 2017-5-18 10:05
请问有智慧北京的学习视频和资料吗、?求分享

作者: Hosing    时间: 2017-7-12 06:52
亲爱的小鲁哥哥,求代码,谢谢啦!
作者: baby14    时间: 2018-11-27 07:59
多谢分享




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2