Android开发实战《智慧北京》——3.完善视图

Android开发实战《智慧北京》——3.完善视图,第1张

概述文章目录1.给新闻菜单详情页ViewPager填充数据2.处理页签无法滑动的Bug3.使用ViewPagerIndicator4.修改ViewPagerIndicator样式5.跳转到下一个页签6.指示器请求所有父控件不拦截事件7.页签滑动时呼出侧边栏的Bug修复8.请求页签网格数据并解析9.页签加网络缓存10.BitmapUtils

文章目录1.给新闻菜单详情页ViewPager填充数据2.处理页签无法滑动的Bug3.使用ViewPagerIndicator4.修改ViewPagerIndicator样式5.跳转到下一个页签6.指示器请求所有父控件不拦截事件7.页签滑动时呼出侧边栏的Bug修复8.请求页签网格数据并解析9.页签加网络缓存10.BitmapUtils的使用11.头条新闻滑动事件处理12.头条新闻标题更新13.头条新闻小圆点14.ImageView的CenterCrop属性15.展示新闻列表16.给ListView添加头布局展示头条新闻18.自定义下拉刷新 & 隐藏头布局19.自定义圆环进度条

1.给新闻菜单详情页VIEwPager填充数据

在上一篇博客的末尾,我们完成了侧边栏的逻辑,现在需要将获得的数据传到VIEwPager中,即让内容显示出来,我们现在来完成这个逻辑。

新建paper_news_menu_detail.xml布局文件,作为VIEwPager的数据填充布局,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <androID.support.v4.vIEw.VIEwPager        androID:ID="@+ID/vp_news_menu_detail"        androID:layout_wIDth="match_parent"        androID:layout_height="match_parent"/></linearLayout>
修改NewsMenuDetailPaper,修改initVIEws()方法,使用刚刚创建好的布局文件,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    public NewsMenuDetailPaper(Activity activity) {        super(activity);    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }}
修改NewsMenuDetailPaper,添加initData()方法,为VIEwPager初始化数据,同时新建内部类NewsMenuDetailAdapter,用于创建适配器逻辑,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    public NewsMenuDetailPaper(Activity activity) {        super(activity);    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        super.initData();    }    class NewsMenuDetailAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return 0;        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            return super.instantiateItem(container, position);        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
在base/impl包下新建TabDetailPaper,继承BaseMenuDetailPaper,作为详情页的标签条,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.Widget.TextVIEw;import com.example.zhbj.base.BaseMenuDetailPaper;/** * 页签详情页,包含北京、中国、国际等页签 */public class TabDetailPaper extends BaseMenuDetailPaper {    public TabDetailPaper(Activity activity) {        super(activity);    }    @OverrIDe    public VIEw initVIEws() {        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");        return vIEw;    }}
修改NewsCenterPaper,修改processData()方法,在添加菜单详情页时额外添加一个参数,代码如下:
    /**     * 解析从服务器获取的JsON数据     */    private voID processData(String Json) {        Gson gson = new Gson();        // 通过Json和对象类,来生成一个对象        newsMenu = gson.fromJson(Json, NewsMenu.class);        // 找到侧边栏对象        MainActivity mainUI = (MainActivity) mActivity;        leftMenuFragment fragment = mainUI.getleftMenuFragment();        fragment.setMenuData(newsMenu.data);        // 网络请求成功之后,初始化四个菜单详情页        mPapers = new ArrayList<>();        mPapers.add(new NewsMenuDetailPaper(mActivity,newsMenu.data.get(0).children)); // 通过构造方法传递数据        mPapers.add(new topicmenuDetailPaper(mActivity));        mPapers.add(new PhotosMenuDetailPaper(mActivity));        mPapers.add(new InteractMenuDetailPaper(mActivity));        // 设置新闻菜单详情页为默认页面        setMenuDetailPager(0);    }
修改InteractMenuDetailPaper、NewsMenuDetailPaper、PhotosMenuDetailPaper、topicmenuDetailPaper,修改其构造方法,添加参数,这里只演示其中一个类的修改,其他同理,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import java.util.ArrayList;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    private ArrayList<NewsMenu.NewsTabData> children;    public NewsMenuDetailPaper(Activity activity, ArrayList<NewsMenu.NewsTabData> children) {        super(activity);        this.children = children;    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // 初始化12个页签对象,具体数量以服务器为准    }    class NewsMenuDetailAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return 0;        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            return super.instantiateItem(container, position);        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
修改NewsMenuDetailPaper,修改initData()方法,获取十二个页签对象,并且修改NewsMenuDetailAdapter内部类的方法,使其相匹配,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.base.impl.TabDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import java.util.ArrayList;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    private ArrayList<NewsMenu.NewsTabData> children;    private ArrayList<TabDetailPaper> mPaper;    public NewsMenuDetailPaper(Activity activity, ArrayList<NewsMenu.NewsTabData> children) {        super(activity);        this.children = children;    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // 初始化12个页签对象,具体数量以服务器为准        mPaper = new ArrayList<>();        for (int i = 0; i < children.size(); i++) {            TabDetailPaper paper = new TabDetailPaper(mActivity);            mPaper.add(paper);        }        mVIEwPager.setAdapter(new NewsMenuDetailAdapter());    }    class NewsMenuDetailAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return mPaper.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            TabDetailPaper paper = mPaper.get(position);            paper.initData(); // 初始化数据            container.addVIEw(paper.mRootVIEw);            return paper.mRootVIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
修改NewsMenuDetailPaper,修改initData()方法,将网络数据填充进去,代码如下:
    @OverrIDe    public voID initData() {        // 初始化12个页签对象,具体数量以服务器为准        mPaper = new ArrayList<>();        for (int i = 0; i < children.size(); i++) {            TabDetailPaper paper = new TabDetailPaper(mActivity,children.get(i));            mPaper.add(paper);        }        mVIEwPager.setAdapter(new NewsMenuDetailAdapter());    }

与此同时,修改TabDetailPaper,将构造方法修改成与其相对应,代码如下:

package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.Widget.TextVIEw;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;/** * 页签详情页,包含北京、中国、国际等页签 */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;    }    @OverrIDe    public VIEw initVIEws() {        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");        return vIEw;    }}
修改NewsMenuDetailPaper,修改initData()方法,设置其页面显示的内容,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.Widget.TextVIEw;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;/** * 页签详情页,包含北京、中国、国际等页签 */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */    private TextVIEw vIEw;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;    }    @OverrIDe    public VIEw initVIEws() {        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");        return vIEw;    }    @OverrIDe    public voID initData() {        vIEw.setText(newsTabData.Title); // 修改当前布局的数据    }}
2.处理页签无法滑动的BUG

现在数据设置好了,当前页面只有一个数据“北京”,由于界面是一个VIEwPager,按理说应该可以滑动,然而在滑动时出现了无法滑动的BUG(即滑动冲突),我们现在来处理一下。

修改NoScrollVIEwPaper,重写onIntercepttouchEvent()方法,让父类不要拦截子类的事件,代码如下:

    /**     * 事件中断,拦截     * @param ev     * @return     */    @OverrIDe    public boolean onIntercepttouchEvent(MotionEvent ev) {        // true:拦截,false:不拦截,传给子控件        return false; // 标签页的VIEwPager不拦截标签菜单详情页页签的VIEwPager    }
3.使用VIEwPagerIndicator

在编写新的逻辑代码前,再去梳理一下当前的UI框架图。

在这个基础上,现在要编写标题栏上的条签,这里我们使用第三方组件VIEwPagerIndicator来实现这个效果。引入这个第三方模块,然后开始编写我们接下来的逻辑。

修改paper_news_menu_detail.xml,添加相关组件,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <com.vIEwpagerindicator.TabPageIndicator        androID:ID="@ID/indicator"        androID:layout_wIDth="match_parent"        androID:layout_height="wrap_content"/>    <androID.support.v4.vIEw.VIEwPager        androID:ID="@+ID/vp_news_menu_detail"        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:layout_weight="1"/></linearLayout>
修改NewsMenuDetailPaper,注册TagPageIndicator控件,并且绑定,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.base.impl.TabDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.vIEwpagerindicator.TabPageIndicator;import java.util.ArrayList;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    @VIEwInject(R.ID.indicator)    private TabPageIndicator mIndicator;    private ArrayList<NewsMenu.NewsTabData> children;    private ArrayList<TabDetailPaper> mPaper;    public NewsMenuDetailPaper(Activity activity, ArrayList<NewsMenu.NewsTabData> children) {        super(activity);        this.children = children;    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // 初始化12个页签对象,具体数量以服务器为准        mPaper = new ArrayList<>();        for (int i = 0; i < children.size(); i++) {            TabDetailPaper paper = new TabDetailPaper(mActivity,children.get(i));            mPaper.add(paper);        }        mVIEwPager.setAdapter(new NewsMenuDetailAdapter());        mIndicator.setVIEwPager(mVIEwPager); // 将VIEwPager和VIEwPageIndicator绑定在一起,注意需要在setAdapter结束之后再调    }    class NewsMenuDetailAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return mPaper.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            TabDetailPaper paper = mPaper.get(position);            paper.initData(); // 初始化数据            container.addVIEw(paper.mRootVIEw);            return paper.mRootVIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
修改NewsMenuDetailPaper,重写getPageTitle()方法、添加返回标题的逻辑,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.annotation.Nullable;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.base.impl.TabDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.vIEwpagerindicator.TabPageIndicator;import java.util.ArrayList;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    /**     * indicator指示器     */    @VIEwInject(R.ID.indicator)    private TabPageIndicator mIndicator;    /**     * 存储标题     */    private ArrayList<NewsMenu.NewsTabData> children;    /**     * 存储详情页     */    private ArrayList<TabDetailPaper> mPaper;    public NewsMenuDetailPaper(Activity activity, ArrayList<NewsMenu.NewsTabData> children) {        super(activity);        this.children = children;    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // 初始化12个页签对象,具体数量以服务器为准        mPaper = new ArrayList<>();        for (int i = 0; i < children.size(); i++) {            TabDetailPaper paper = new TabDetailPaper(mActivity,children.get(i));            mPaper.add(paper);        }        mVIEwPager.setAdapter(new NewsMenuDetailAdapter());        mIndicator.setVIEwPager(mVIEwPager); // 将VIEwPager和VIEwPageIndicator绑定在一起,注意需要在setAdapter结束之后再调    }    class NewsMenuDetailAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return mPaper.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            TabDetailPaper paper = mPaper.get(position);            paper.initData(); // 初始化数据            container.addVIEw(paper.mRootVIEw);            return paper.mRootVIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }        /**         * 返回指示器Indicator的标题         * @param position         * @return         */        @Nullable        @OverrIDe        public CharSequence getPageTitle(int position) {            return children.get(position).Title;        }    }}
4.修改VIEwPagerIndicator样式

现在VIEwPagerIndicator创建好了,不过样式不太好看,那么这一节我们就来修改一下它的样式。

修改AndroIDManifest.xml,修改MainActivity的默认样式,代码如下:
<?xml version="1.0" enCoding="utf-8"?><manifest xmlns:androID="http://schemas.androID.com/apk/res/androID"    package="com.example.zhbj">    <uses-permission androID:name="androID.permission.INTERNET" />    <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE" />    <application        androID:allowBackup="true"        androID:icon="@drawable/icon_150"        androID:label="@string/app_name"        androID:roundIcon="@mipmap/ic_launcher_round"        androID:supportsRtl="true"        androID:theme="@style/Apptheme">        <uses-library androID:name="org.apache.http.legacy" androID:required="false" />        <activity            androID:name=".SplashActivity"            androID:theme="@androID:style/theme.Black.NoTitlebar.Fullscreen">            <intent-filter>                <action androID:name="androID.intent.action.MAIN" />                <category androID:name="androID.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity androID:name=".GuIDeActivity" />        <activity androID:name=".MainActivity"             androID:theme="@style/theme.PageIndicatorDefaults"/>    </application></manifest>
修改activity_main.xml,将背景颜色改为白色,以替换修改新样式后变成的黑色,(在java类中修改ContentFragment的布局也可以)代码如下:
<?xml version="1.0" enCoding="utf-8"?><FrameLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:ID="@+ID/fl_content"    androID:background="#fff"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"></FrameLayout>
为了优化显示效果,修改vpi__tab_indicator.xml文件(在指示器文件夹中),注意将需要用到的图片拷到VIEwPageIndicator的res/drawable中,不然无法引用,代码如下:
<?xml version="1.0" enCoding="utf-8"?><!-- copyright (C) 2008 The AndroID Open Source Project     licensed under the Apache license, Version 2.0 (the "license");     you may not use this file except in compliance with the license.     You may obtain a copy of the license at            http://www.apache.org/licenses/liCENSE-2.0       Unless required by applicable law or agreed to in writing, software     distributed under the license is distributed on an "AS IS" BASIS,     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implIEd.     See the license for the specific language governing permissions and     limitations under the license.--><selector xmlns:androID="http://schemas.androID.com/apk/res/androID">    <!-- Non focused states -->    <item androID:state_focused="false" androID:state_selected="false" androID:state_pressed="false" androID:drawable="@androID:color/transparent" />    <item androID:state_focused="false" androID:state_selected="true"  androID:state_pressed="false" androID:drawable="@drawable/news_tab_item_bg_select" />    <!-- Focused states -->    <item androID:state_focused="true" androID:state_selected="false" androID:state_pressed="false" androID:drawable="@androID:color/transparent" />    <item androID:state_focused="true" androID:state_selected="true"  androID:state_pressed="false" androID:drawable="@drawable/news_tab_item_bg_select" />    <!-- pressed -->    <!--    Non focused states -->    <item androID:state_focused="false" androID:state_selected="false" androID:state_pressed="true" androID:drawable="@androID:color/transparent" />    <item androID:state_focused="false" androID:state_selected="true"  androID:state_pressed="true" androID:drawable="@drawable/news_tab_item_bg_select" />    <!--    Focused states -->    <item androID:state_focused="true" androID:state_selected="false" androID:state_pressed="true" androID:drawable="@androID:color/transparent" />    <item androID:state_focused="true" androID:state_selected="true"  androID:state_pressed="true" androID:drawable="@drawable/news_tab_item_bg_select" /></selector>
为了优化文字效果,修改vpi__dark_theme文件(在指示器文件夹中),代码如下:
<?xml version="1.0" enCoding="utf-8"?><!-- copyright (C) 2010 The AndroID Open Source Project     licensed under the Apache license, Version 2.0 (the "license");     you may not use this file except in compliance with the license.     You may obtain a copy of the license at            http://www.apache.org/licenses/liCENSE-2.0       Unless required by applicable law or agreed to in writing, software     distributed under the license is distributed on an "AS IS" BASIS,     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implIEd.     See the license for the specific language governing permissions and     limitations under the license.--><selector xmlns:androID="http://schemas.androID.com/apk/res/androID">    <item androID:state_enabled="false" androID:color="#000"/>    <item androID:state_window_focused="false" androID:color="#000"/>    <item androID:state_pressed="true" androID:color="#000"/>    <item androID:state_selected="true" androID:color="#f00"/>    <!--item androID:state_activated="true" androID:color="@color/vpi__bright_foreground_holo_dark"/-->    <item androID:color="#000"/> <!-- not selected --></selector>
5.跳转到下一个页签

之前我们实现了页签条的配置,现在需要在页签条的末尾加上一个箭头,点击后会跳转到下一个页面,现在开始实现这个逻辑。

修改paper_news_menu_detail.xml,增加箭头图标,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <linearLayout        androID:layout_wIDth="match_parent"        androID:layout_height="wrap_content"        androID:orIEntation="horizontal">        <com.vIEwpagerindicator.TabPageIndicator            androID:ID="@+ID/indicator"            androID:layout_wIDth="0dp"            androID:layout_height="wrap_content"            androID:layout_weight="1"/>        <Imagebutton            androID:ID="@+ID/btn_next"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:background="@null"            androID:layout_gravity="center_vertical"            androID:padding="5dp"            androID:src="@drawable/news_cate_arr"/>    </linearLayout>    <androID.support.v4.vIEw.VIEwPager        androID:ID="@+ID/vp_news_menu_detail"        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:layout_weight="1"/></linearLayout>
修改NewsMenuDetailPaper,为刚刚添加的按钮注册点击事件,由于使用的是Xutils,所以新建一个nextPage()方法来完成这个逻辑,代码如下:
    /**     * 通过Xutils来添加按钮的点击事件     * 注意:在xml中,配置组件的onClick属性只适用于Activity     * @param vIEw     */    @OnClick(R.ID.btn_next)    public voID nextPage(VIEw vIEw){        // 跳转到下一个页面        int currentPos = mVIEwPager.getCurrentItem();        //mIndicator.setCurrentItem(++currentPos); 会导致显示BUG        mVIEwPager.setCurrentItem(++currentPos);    }
6.指示器请求所有父控件不拦截事件

在向右滑动标签条时,可能会将侧边栏也滑动出来,这就需要让指示器请求所有父控件而不拦截事件,现在开始实现。

​ 修改vIEwpagerIndicator中的TabPageIndicator,重写dispatchtouchEvent()方法,代码如下:

    /**     * 事件处理:dispatchtouchEvent(事件分发) -> onIntercepttouchEvent -> ontouchEvent     * @param ev     * @return     */    @OverrIDe    public boolean dispatchtouchEvent(MotionEvent ev) {        // 请求父控件和祖宗控件不要拦截事件        getParent().requestdisallowIntercepttouchEvent(true);        return super.dispatchtouchEvent(ev);    }
7.页签滑动时呼出侧边栏的BUG修复

在第六节中我们让指示器请求所有父控件不拦截事件,现在来修复一个BUG:页签滑动到第二个页签时,左滑会呼出侧边栏。现在开始实现这个逻辑。

修改NewsMenuDetailPaper,修改initData()方法,并且实现OnPagechangelistener接口,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.annotation.Nullable;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.base.impl.TabDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.lIDroID.xutils.vIEw.annotation.event.OnClick;import com.vIEwpagerindicator.TabPageIndicator;import java.util.ArrayList;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper implements VIEwPager.OnPagechangelistener {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    /**     * indicator指示器     */    @VIEwInject(R.ID.indicator)    private TabPageIndicator mIndicator;    /**     * 存储标题     */    private ArrayList<NewsMenu.NewsTabData> children;    /**     * 存储详情页     */    private ArrayList<TabDetailPaper> mPaper;    public NewsMenuDetailPaper(Activity activity, ArrayList<NewsMenu.NewsTabData> children) {        super(activity);        this.children = children;    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // 初始化12个页签对象,具体数量以服务器为准        mPaper = new ArrayList<>();        for (int i = 0; i < children.size(); i++) {            TabDetailPaper paper = new TabDetailPaper(mActivity,children.get(i));            mPaper.add(paper);        }        mVIEwPager.setAdapter(new NewsMenuDetailAdapter());        mIndicator.setVIEwPager(mVIEwPager); // 将VIEwPager和VIEwPageIndicator绑定在一起,注意需要在setAdapter结束之后再调        // 设置页面的触摸监听        // mVIEwPager.setonPagechangelistener(this);        mIndicator.setonPagechangelistener(this); // 当VIEwPager和Indicator绑定时,事件需要设置给mIndicator    }    /**     * 通过Xutils来添加按钮的点击事件     * 注意:在xml中,配置组件的onClick属性只适用于Activity     * @param vIEw     */    @OnClick(R.ID.btn_next)    public voID nextPage(VIEw vIEw){        // 跳转到下一个页面        int currentPos = mVIEwPager.getCurrentItem();        //mIndicator.setCurrentItem(++currentPos); 会导致显示BUG        mVIEwPager.setCurrentItem(++currentPos);    }    @OverrIDe    public voID onPageScrolled(int i, float v, int i1) {    }    @OverrIDe    public voID onPageSelected(int i) {    }    @OverrIDe    public voID onPageScrollStateChanged(int i) {    }    class NewsMenuDetailAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return mPaper.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            TabDetailPaper paper = mPaper.get(position);            paper.initData(); // 初始化数据            container.addVIEw(paper.mRootVIEw);            return paper.mRootVIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }        /**         * 返回指示器Indicator的标题         * @param position         * @return         */        @Nullable        @OverrIDe        public CharSequence getPageTitle(int position) {            return children.get(position).Title;        }    }}
修改NewsMenuDetailPaper,实现onPageSelected()方法,用于控制侧边栏的开启和关闭,代码如下:
package com.example.zhbj.base.impl.menudetail;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.annotation.Nullable;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.MainActivity;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.base.impl.TabDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.jeremyfeinstein.slIDingmenu.lib.SlIDingMenu;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.lIDroID.xutils.vIEw.annotation.event.OnClick;import com.vIEwpagerindicator.TabPageIndicator;import java.util.ArrayList;/** * 菜单详情页 - 新闻 */public class NewsMenuDetailPaper extends BaseMenuDetailPaper implements VIEwPager.OnPagechangelistener {    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_news_menu_detail)    private VIEwPager mVIEwPager;    /**     * indicator指示器     */    @VIEwInject(R.ID.indicator)    private TabPageIndicator mIndicator;    /**     * 存储标题     */    private ArrayList<NewsMenu.NewsTabData> children;    /**     * 存储详情页     */    private ArrayList<TabDetailPaper> mPaper;    public NewsMenuDetailPaper(Activity activity, ArrayList<NewsMenu.NewsTabData> children) {        super(activity);        this.children = children;    }    @OverrIDe    public VIEw initVIEws() {        // 给空的帧布局动态添加布局对象        /*        TextVIEw vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("菜单详情页-新闻");        */        VIEw vIEw = VIEw.inflate(mActivity, R.layout.paper_news_menu_detail, null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // 初始化12个页签对象,具体数量以服务器为准        mPaper = new ArrayList<>();        for (int i = 0; i < children.size(); i++) {            TabDetailPaper paper = new TabDetailPaper(mActivity,children.get(i));            mPaper.add(paper);        }        mVIEwPager.setAdapter(new NewsMenuDetailAdapter());        mIndicator.setVIEwPager(mVIEwPager); // 将VIEwPager和VIEwPageIndicator绑定在一起,注意需要在setAdapter结束之后再调        // 设置页面的触摸监听        // mVIEwPager.setonPagechangelistener(this);        mIndicator.setonPagechangelistener(this); // 当VIEwPager和Indicator绑定时,事件需要设置给mIndicator    }    /**     * 通过Xutils来添加按钮的点击事件     * 注意:在xml中,配置组件的onClick属性只适用于Activity     * @param vIEw     */    @OnClick(R.ID.btn_next)    public voID nextPage(VIEw vIEw){        // 跳转到下一个页面        int currentPos = mVIEwPager.getCurrentItem();        //mIndicator.setCurrentItem(++currentPos); 会导致显示BUG        mVIEwPager.setCurrentItem(++currentPos);    }    @OverrIDe    public voID onPageScrolled(int i, float v, int i1) {    }    @OverrIDe    public voID onPageSelected(int i) {        if (i == 0){            // 打开侧边栏            setSlIDingMenuEnable(true);        }else {            // 禁用侧边栏            setSlIDingMenuEnable(false);        }    }    @OverrIDe    public voID onPageScrollStateChanged(int i) {    }    /**     * 开启/禁用侧边栏     */    private voID setSlIDingMenuEnable(boolean enable){        // 获取MainActivity对象        MainActivity mainUI = (MainActivity) mActivity;        // 获取SlIDingMenu对象        SlIDingMenu slIDingMenu = mainUI.getSlIDingMenu();        if (enable){            slIDingMenu.settouchModeAbove(SlIDingMenu.touchMODE_FulLSCREEN);        }else {            slIDingMenu.settouchModeAbove(SlIDingMenu.touchMODE_NONE);        }    }    class NewsMenuDetailAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return mPaper.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            TabDetailPaper paper = mPaper.get(position);            paper.initData(); // 初始化数据            container.addVIEw(paper.mRootVIEw);            return paper.mRootVIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }        /**         * 返回指示器Indicator的标题         * @param position         * @return         */        @Nullable        @OverrIDe        public CharSequence getPageTitle(int position) {            return children.get(position).Title;        }    }}
8.请求页签网格数据并解析

现在处理好了页签的逻辑,接下来我们需要给主页面请求页签网格数据并解析。

在完成逻辑之前,让我们先看看现在UI图的结构:

新建一个布局文件paper_tab_detail.xml,作为图片的展示布局,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <androID.support.v4.vIEw.VIEwPager        androID:ID="@+ID/vp_tab_detail"        androID:layout_wIDth="match_parent"        androID:layout_height="180dp"        /></linearLayout>
修改TabDetailPaper,注释掉之前的视图,换上新的视图,并且编写topNewsAdapter,作为这个Pager的数据适配器,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private VIEwPager mVIEwPaper;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据    }    class topNewsAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return 0;        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            return super.instantiateItem(container, position);        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
在domain包下新建NewsTab类,作为显示图片的实体类,代码如下:
package com.example.zhbj.domain;import java.util.ArrayList;/** * 页签网络数据 */public class NewsTab {    public NewsTabData data;    public class NewsTabData{        public String more;        public ArrayList<topNews> topnews;        public ArrayList<News> news;    }    public class topNews{        public String ID;        public String pubdate;        public String Title;        public String topimage;        public String url;    }    public class News{        public String ID;        public String pubdate;        public String Title;        public String listimage;        public String url;    }}
修改TabDetailPaper,新增getDataFromServer()方法,用于从服务器上获取数据。再新增processData()方法,用于解析Json数据,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.Google.gson.Gson;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private VIEwPager mVIEwPaper;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, GlobalConstans.SERVER_URL + newsTabData.url, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);    }    class topNewsAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return 0;        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            return super.instantiateItem(container, position);        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
9.页签加网络缓存

现在我们获取到了服务器上的数据,就像之前一样,现在需要获得数据后加入到缓存中,现在开始编写这个逻辑。

修改TabDetailPaper,修改initData()方法,用于将网上的数据缓存到本地。再修改RequestCallBack内部类中的onSuccess()方法,用于读取本地缓存,代码如下:

package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.Google.gson.Gson;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private VIEwPager mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        gson.fromJson(result, NewsTab.class);    }    class topNewsAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return 0;        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            return super.instantiateItem(container, position);        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
10.BitmapUtils的使用

现在我们取到了数据,接下来要做的就是将数据中的url链接解析出来,然后显示到主页上,开始编写这个逻辑。

修改TabDetailPaper,解析获得的数据,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.Google.gson.Gson;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import java.util.ArrayList;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private VIEwPager mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    /**     * 保存头条新闻图片的集合     */    private ArrayList<NewsTab.topNews> mtopNewsList;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);        // 初始化头条新闻数据        mtopNewsList = newsTab.data.topnews;        if (mtopNewsList != null){            mVIEwPaper.setAdapter(new topNewsAdapter());        }    }    class topNewsAdapter extends PagerAdapter{        @OverrIDe        public int getCount() {            return mtopNewsList.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            ImageVIEw vIEw = new ImageVIEw(mActivity);            NewsTab.topNews topNews = mtopNewsList.get(position);            String topimage = topNews.topimage; // 图片的下载链接            container.addVIEw(vIEw);            return vIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
修改TabDetailPaper,由于将图片解析过来的工程量过大,这里直接使用xUtils中的BitmapUtils,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.Google.gson.Gson;import com.lIDroID.xutils.BitmapUtils;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import java.util.ArrayList;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private VIEwPager mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    /**     * 保存头条新闻图片的集合     */    private ArrayList<NewsTab.topNews> mtopNewsList;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);        // 初始化头条新闻数据        mtopNewsList = newsTab.data.topnews;        if (mtopNewsList != null){            mVIEwPaper.setAdapter(new topNewsAdapter());        }    }    class topNewsAdapter extends PagerAdapter{        /**         * xUtils中的BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public topNewsAdapter() {           mBitmapUtils = new BitmapUtils(mActivity);           // 设置加载中的默认图片           mBitmapUtils.configDefaultLoadingImage(R.drawable.pic_item_List_default);        }        @OverrIDe        public int getCount() {            return mtopNewsList.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            ImageVIEw vIEw = new ImageVIEw(mActivity);            NewsTab.topNews topNews = mtopNewsList.get(position);            String topimage = topNews.topimage; // 图片的下载链接            vIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY); // 设置缩放模式:宽高匹配窗体            /**             * 1,根据url下载图片             * 2.将图片设置给ImageVIEw             * 3.将图片作成缓存             * 4.避免内存溢出             * 由于工程量巨大,这里使用xUtils中的BitmapUtils里的API来完成这四个逻辑             */            mBitmapUtils.display(vIEw,topimage);            container.addVIEw(vIEw);            return vIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
11.头条新闻滑动事件处理

之前我们完成了图片的解析和加载,现在需要处理头条新闻图片的滑动事件,现在开始完成这个逻辑。

在vIEw包下新建topNewsVIEwPaper,表示头条新闻的标题栏,代码如下:
package com.example.zhbj.vIEw;import androID.content.Context;import androID.support.annotation.NonNull;import androID.support.annotation.Nullable;import androID.support.v4.vIEw.VIEwPager;import androID.util.AttributeSet;import androID.vIEw.MotionEvent;/** * 头条新闻的VIEwPager */public class topNewsVIEwPaper extends VIEwPager {    public topNewsVIEwPaper(@NonNull Context context) {        super(context);    }    public topNewsVIEwPaper(@NonNull Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    @OverrIDe    public boolean dispatchtouchEvent(MotionEvent ev) {        // 请求父控件不要拦截        getParent().requestdisallowIntercepttouchEvent(true);        return super.dispatchtouchEvent(ev);    }}
修改paper_tab_detail.xml,用刚才编写的vIEwpaper替换掉原来的组件,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <com.example.zhbj.vIEw.topNewsVIEwPaper        androID:ID="@+ID/vp_tab_detail"        androID:layout_wIDth="match_parent"        androID:layout_height="180dp"        /></linearLayout>
修改TabDetailPaper,修改mVIEwPaper的类型,需要与刚才的类型同步,代码如下:
    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private topNewsVIEwPaper mVIEwPaper;
修改topNewsVIEwPaper,优化滑动事件的处理,代码如下:
package com.example.zhbj.vIEw;import androID.content.Context;import androID.support.annotation.NonNull;import androID.support.annotation.Nullable;import androID.support.v4.vIEw.VIEwPager;import androID.util.AttributeSet;import androID.vIEw.MotionEvent;/** * 头条新闻的VIEwPager */public class topNewsVIEwPaper extends VIEwPager {    /**     * 起始的X坐标     */    private int startX;    /**     * 起始的Y坐标     */    private int startY;    /**     * 终点的X坐标     */    private int endX;    /**     * 终点的Y坐标     */    private int endY;    /**     * X坐标的偏移量     */    private int dX;    /**     * Y坐标的便宜量     */    private int dY;    public topNewsVIEwPaper(@NonNull Context context) {        super(context);    }    public topNewsVIEwPaper(@NonNull Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    /**     * 需要分情况来判断是否需要拦截事件     * 1.上下滑动,需要拦截     * 2.左滑时,最后一个页面需要拦截     * 3.右滑时,第一个页面需要拦截     * @param ev     * @return     */    @OverrIDe    public boolean dispatchtouchEvent(MotionEvent ev) {        // 请求父控件不拦截事件        getParent().requestdisallowIntercepttouchEvent(true);        switch (ev.getAction()){            case MotionEvent.ACTION_DOWN:                // 按下                startX = (int) ev.getX();                startY = (int) ev.getY();                break;            case MotionEvent.ACTION_MOVE:                // 移动                endX = (int) ev.getX();                endY = (int) ev.getY();                dX = endX - startX;                dY = endY - startY;                if (Math.abs(dX) > Math.abs(dY)){                    // 左右滑动                    int currentPos = getCurrentItem();                    if (dX > 0){                        // 右滑动                        if (currentPos == 0){                            getParent().requestdisallowIntercepttouchEvent(false);                        }                    }else {                        // 左滑动                        int count = getAdapter().getCount(); // 当前vIEwpager中的item总数                        if (currentPos == count - 1){                            getParent().requestdisallowIntercepttouchEvent(false);                        }                    }                }else {                    // 上下滑动                    getParent().requestdisallowIntercepttouchEvent(false);                }                break;            default:break;        }        return super.dispatchtouchEvent(ev);    }}
12.头条新闻标题更新

现在解决了头条新闻的滑动问题,接下来就是给每条新闻增加标题栏,现在开始实现逻辑。

修改paper_tab_detail.xml,添加标题,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <FrameLayout        androID:layout_wIDth="match_parent"        androID:layout_height="180dp">        <com.example.zhbj.vIEw.topNewsVIEwPaper            androID:ID="@+ID/vp_tab_detail"            androID:layout_wIDth="match_parent"            androID:layout_height="180dp"/>        <relativeLayout            androID:layout_wIDth="match_parent"            androID:layout_height="wrap_content"            androID:layout_gravity="bottom"            androID:padding="5dp"            androID:background="#9000">            <TextVIEw                androID:ID="@+ID/tv_Title2"                androID:layout_wIDth="wrap_content"                androID:layout_height="wrap_content"                androID:textcolor="#fff"                androID:textSize="16sp"/>        </relativeLayout>    </FrameLayout></linearLayout>
修改TabDetailPaper,获取刚刚创建的控件,并且修改processData()方法,用于绑定数据,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.example.zhbj.vIEw.topNewsVIEwPaper;import com.Google.gson.Gson;import com.lIDroID.xutils.BitmapUtils;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import java.util.ArrayList;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private topNewsVIEwPaper mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    /**     * 保存头条新闻图片的集合     */    private ArrayList<NewsTab.topNews> mtopNewsList;    /**     * TextVIEw控件实例     */    @VIEwInject(R.ID.tv_Title2)    private TextVIEw tvTitle;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);        // 初始化头条新闻数据        mtopNewsList = newsTab.data.topnews;        if (mtopNewsList != null){            mVIEwPaper.setAdapter(new topNewsAdapter());            mVIEwPaper.setonPagechangelistener(new VIEwPager.OnPagechangelistener() {                @OverrIDe                public voID onPageScrolled(int i, float v, int i1) {                }                @OverrIDe                public voID onPageSelected(int i) {                    // 更新头条新闻的标题                    tvTitle.setText(mtopNewsList.get(i).Title);                }                @OverrIDe                public voID onPageScrollStateChanged(int i) {                }            });            // 初始化首页标题            tvTitle.setText(mtopNewsList.get(0).Title);        }    }    class topNewsAdapter extends PagerAdapter{        /**         * xUtils中的BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public topNewsAdapter() {           mBitmapUtils = new BitmapUtils(mActivity);           // 设置加载中的默认图片           mBitmapUtils.configDefaultLoadingImage(R.drawable.pic_item_List_default);        }        @OverrIDe        public int getCount() {            return mtopNewsList.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            ImageVIEw vIEw = new ImageVIEw(mActivity);            NewsTab.topNews topNews = mtopNewsList.get(position);            String topimage = topNews.topimage; // 图片的下载链接            vIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY); // 设置缩放模式:宽高匹配窗体            /**             * 1,根据url下载图片             * 2.将图片设置给ImageVIEw             * 3.将图片作成缓存             * 4.避免内存溢出             * 由于工程量巨大,这里使用xUtils中的BitmapUtils里的API来完成这四个逻辑             */            mBitmapUtils.display(vIEw,topimage);            container.addVIEw(vIEw);            return vIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
13.头条新闻小圆点

标题已经弄好了,我们现在需要弄好一个显示图片的小圆点的功能,现在开始实现逻辑(这里借鉴一下VIEwpageIndicator的实现)。

修改paper_tab_detail.xml,添加圆点指示器组件,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    xmlns:app="http://schemas.androID.com/apk/res-auto"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <FrameLayout        androID:layout_wIDth="match_parent"        androID:layout_height="180dp">        <com.example.zhbj.vIEw.topNewsVIEwPaper            androID:ID="@+ID/vp_tab_detail"            androID:layout_wIDth="match_parent"            androID:layout_height="180dp"/>        <relativeLayout            androID:layout_wIDth="match_parent"            androID:layout_height="wrap_content"            androID:layout_gravity="bottom"            androID:padding="5dp"            androID:background="#9000">            <TextVIEw                androID:ID="@+ID/tv_Title2"                androID:layout_wIDth="wrap_content"                androID:layout_height="wrap_content"                androID:textcolor="#fff"                androID:textSize="16sp"/>            <com.vIEwpagerindicator.CirclePageIndicator                androID:ID="@+ID/indicator2"                androID:layout_height="wrap_content"                androID:layout_wIDth="wrap_content"                androID:layout_alignParentRight="true"                androID:layout_centerVertical="true"                androID:paddingleft="5dp"                androID:paddingRight="5dp"                app:radius="3dp"                app:fillcolor="#f00"                app:pagecolor="#cccccc"                app:strokeWIDth="0dp" />        </relativeLayout>    </FrameLayout></linearLayout>
修改TabDetailPaper,获取刚刚创建的组件实例,然后再绑定事件,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.example.zhbj.vIEw.topNewsVIEwPaper;import com.Google.gson.Gson;import com.lIDroID.xutils.BitmapUtils;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.vIEwpagerindicator.CirclePageIndicator;import java.util.ArrayList;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private topNewsVIEwPaper mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    /**     * 保存头条新闻图片的集合     */    private ArrayList<NewsTab.topNews> mtopNewsList;    /**     * TextVIEw控件实例     */    @VIEwInject(R.ID.tv_Title2)    private TextVIEw tvTitle;    @VIEwInject(R.ID.indicator2)    private CirclePageIndicator mIndicator;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);        // 初始化头条新闻数据        mtopNewsList = newsTab.data.topnews;        if (mtopNewsList != null){            mVIEwPaper.setAdapter(new topNewsAdapter());            mIndicator.setVIEwPager(mVIEwPaper); // 将圆形指示器和vIEwpager绑定            mIndicator.setSnap(true); // 快照展示方式            mIndicator.onPageSelected(0); // 将圆点位置归零,保证圆点和页面同步            mIndicator.setonPagechangelistener(new VIEwPager.OnPagechangelistener() {                @OverrIDe                public voID onPageScrolled(int i, float v, int i1) {                }                @OverrIDe                public voID onPageSelected(int i) {                    // 更新头条新闻的标题                    tvTitle.setText(mtopNewsList.get(i).Title);                }                @OverrIDe                public voID onPageScrollStateChanged(int i) {                }            });            // 初始化首页标题            tvTitle.setText(mtopNewsList.get(0).Title);        }    }    class topNewsAdapter extends PagerAdapter{        /**         * xUtils中的BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public topNewsAdapter() {           mBitmapUtils = new BitmapUtils(mActivity);           // 设置加载中的默认图片           mBitmapUtils.configDefaultLoadingImage(R.drawable.pic_item_List_default);        }        @OverrIDe        public int getCount() {            return mtopNewsList.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            ImageVIEw vIEw = new ImageVIEw(mActivity);            NewsTab.topNews topNews = mtopNewsList.get(position);            String topimage = topNews.topimage; // 图片的下载链接            vIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY); // 设置缩放模式:宽高匹配窗体            /**             * 1,根据url下载图片             * 2.将图片设置给ImageVIEw             * 3.将图片作成缓存             * 4.避免内存溢出             * 由于工程量巨大,这里使用xUtils中的BitmapUtils里的API来完成这四个逻辑             */            mBitmapUtils.display(vIEw,topimage);            container.addVIEw(vIEw);            return vIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }}
14.ImageVIEw的CenterCrop属性

上面我们完成了图片的显示,这次需要实现新闻列表的编写。

修改paper_tab_detail.xml,添加一个ListVIEw组件,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    xmlns:app="http://schemas.androID.com/apk/res-auto"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <FrameLayout        androID:layout_wIDth="match_parent"        androID:layout_height="180dp">        <com.example.zhbj.vIEw.topNewsVIEwPaper            androID:ID="@+ID/vp_tab_detail"            androID:layout_wIDth="match_parent"            androID:layout_height="180dp"/>        <relativeLayout            androID:layout_wIDth="match_parent"            androID:layout_height="wrap_content"            androID:layout_gravity="bottom"            androID:padding="5dp"            androID:background="#9000">            <TextVIEw                androID:ID="@+ID/tv_Title2"                androID:layout_wIDth="wrap_content"                androID:layout_height="wrap_content"                androID:textcolor="#fff"                androID:textSize="16sp"/>            <com.vIEwpagerindicator.CirclePageIndicator                androID:ID="@+ID/indicator2"                androID:layout_height="wrap_content"                androID:layout_wIDth="wrap_content"                androID:layout_alignParentRight="true"                androID:layout_centerVertical="true"                androID:paddingleft="5dp"                androID:paddingRight="5dp"                app:radius="3dp"                app:fillcolor="#f00"                app:pagecolor="#cccccc"                app:strokeWIDth="0dp" />        </relativeLayout>    </FrameLayout>        <!--   有时候滑动ListVIEw整个背景变为黑色,可以加属性cachecolorHint修改缓冲区的颜色 -->    <ListVIEw        androID:ID="@+ID/lv_List"        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:cachecolorHint="@androID:color/transparent"        androID:layout_weight="1"/></linearLayout>
修改TabDetailPaper,获取刚刚创建的ListVIEw实例,并且写一个适配器内部类NewsAdapter绑定数据,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.BaseAdapter;import androID.Widget.ImageVIEw;import androID.Widget.ListVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.example.zhbj.vIEw.topNewsVIEwPaper;import com.Google.gson.Gson;import com.lIDroID.xutils.BitmapUtils;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.vIEwpagerindicator.CirclePageIndicator;import java.util.ArrayList;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private topNewsVIEwPaper mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    /**     * 保存头条新闻图片的集合     */    private ArrayList<NewsTab.topNews> mtopNewsList;    /**     * TextVIEw控件实例     */    @VIEwInject(R.ID.tv_Title2)    private TextVIEw tvTitle;    /**     * Indicator控件实例     */    @VIEwInject(R.ID.indicator2)    private CirclePageIndicator mIndicator;    /**     * ListVIEw控件实例     */    @VIEwInject(R.ID.lv_List)    private ListVIEw lvList;    /**     * 存储新闻列表的集合     */    private ArrayList<NewsTab.News> mNewsList;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);        // 初始化头条新闻数据        mtopNewsList = newsTab.data.topnews;        if (mtopNewsList != null){            mVIEwPaper.setAdapter(new topNewsAdapter());            mIndicator.setVIEwPager(mVIEwPaper); // 将圆形指示器和vIEwpager绑定            mIndicator.setSnap(true); // 快照展示方式            mIndicator.onPageSelected(0); // 将圆点位置归零,保证圆点和页面同步            mIndicator.setonPagechangelistener(new VIEwPager.OnPagechangelistener() {                @OverrIDe                public voID onPageScrolled(int i, float v, int i1) {                }                @OverrIDe                public voID onPageSelected(int i) {                    // 更新头条新闻的标题                    tvTitle.setText(mtopNewsList.get(i).Title);                }                @OverrIDe                public voID onPageScrollStateChanged(int i) {                }            });            // 初始化首页标题            tvTitle.setText(mtopNewsList.get(0).Title);        }        /**         * 初始化新闻列表数据         */        mNewsList = newsTab.data.news;        if (mNewsList != null){            lvList.setAdapter(new NewsAdapter());        }    }    class topNewsAdapter extends PagerAdapter{        /**         * xUtils中的BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public topNewsAdapter() {           mBitmapUtils = new BitmapUtils(mActivity);           // 设置加载中的默认图片           mBitmapUtils.configDefaultLoadingImage(R.drawable.pic_item_List_default);        }        @OverrIDe        public int getCount() {            return mtopNewsList.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            ImageVIEw vIEw = new ImageVIEw(mActivity);            NewsTab.topNews topNews = mtopNewsList.get(position);            String topimage = topNews.topimage; // 图片的下载链接            vIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY); // 设置缩放模式:宽高匹配窗体            /**             * 1,根据url下载图片             * 2.将图片设置给ImageVIEw             * 3.将图片作成缓存             * 4.避免内存溢出             * 由于工程量巨大,这里使用xUtils中的BitmapUtils里的API来完成这四个逻辑             */            mBitmapUtils.display(vIEw,topimage);            container.addVIEw(vIEw);            return vIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }    /**     * 新闻列表适配器     */    class NewsAdapter extends BaseAdapter{        @OverrIDe        public int getCount() {            return mNewsList.size();        }        @OverrIDe        public NewsTab.News getItem(int position) {            return mNewsList.get(position);        }        @OverrIDe        public long getItemID(int position) {            return position;        }        @OverrIDe        public VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) {                        return null;        }    }}
新建新闻列表中每条新闻的布局List_item_news.xml,代码如下:
<?xml version="1.0" enCoding="utf-8"?><relativeLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:padding="5dp">    <ImageVIEw        androID:ID="@+ID/iv_icon"        androID:layout_wIDth="100dp"        androID:layout_height="60dp"        androID:scaleType="fitXY"        androID:background="#a000"        androID:padding="1dp"        androID:layout_marginRight="5dp"        androID:src="@drawable/news_pic_default"/>    <TextVIEw        androID:ID="@+ID/tv_Title3"        androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        androID:layout_alignParenttop="true"        androID:layout_toRightOf="@+ID/iv_icon"        androID:textcolor="#000"        androID:textSize="16sp"        androID:maxlines="2"        androID:text="标题"/>    <TextVIEw        androID:ID="@+ID/tv_time"        androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        androID:layout_alignBottom="@+ID/iv_icon"        androID:layout_alignleft="@+ID/tv_Title3"        androID:textcolor="#a000"        androID:text="时间"/></relativeLayout>
15.展示新闻列表

通过上一节我们完成了新闻列表的大致布局,这一节我们来实现新闻列表的展示

修改TabDetailPaper,添加VIEwHolder,用于加载ListVIEw中的数据,代码如下:

package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.BaseAdapter;import androID.Widget.ImageVIEw;import androID.Widget.ListVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.example.zhbj.vIEw.topNewsVIEwPaper;import com.Google.gson.Gson;import com.lIDroID.xutils.BitmapUtils;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.vIEwpagerindicator.CirclePageIndicator;import java.util.ArrayList;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private topNewsVIEwPaper mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    /**     * 保存头条新闻图片的集合     */    private ArrayList<NewsTab.topNews> mtopNewsList;    /**     * TextVIEw控件实例     */    @VIEwInject(R.ID.tv_Title2)    private TextVIEw tvTitle;    /**     * Indicator控件实例     */    @VIEwInject(R.ID.indicator2)    private CirclePageIndicator mIndicator;    /**     * ListVIEw控件实例     */    @VIEwInject(R.ID.lv_List)    private ListVIEw lvList;    /**     * 存储新闻列表的集合     */    private ArrayList<NewsTab.News> mNewsList;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        VIEwUtils.inject(this,vIEw);        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);        // 初始化头条新闻数据        mtopNewsList = newsTab.data.topnews;        if (mtopNewsList != null){            mVIEwPaper.setAdapter(new topNewsAdapter());            mIndicator.setVIEwPager(mVIEwPaper); // 将圆形指示器和vIEwpager绑定            mIndicator.setSnap(true); // 快照展示方式            mIndicator.onPageSelected(0); // 将圆点位置归零,保证圆点和页面同步            mIndicator.setonPagechangelistener(new VIEwPager.OnPagechangelistener() {                @OverrIDe                public voID onPageScrolled(int i, float v, int i1) {                }                @OverrIDe                public voID onPageSelected(int i) {                    // 更新头条新闻的标题                    tvTitle.setText(mtopNewsList.get(i).Title);                }                @OverrIDe                public voID onPageScrollStateChanged(int i) {                }            });            // 初始化首页标题            tvTitle.setText(mtopNewsList.get(0).Title);        }        /**         * 初始化新闻列表数据         */        mNewsList = newsTab.data.news;        if (mNewsList != null){            lvList.setAdapter(new NewsAdapter());        }    }    class topNewsAdapter extends PagerAdapter{        /**         * xUtils中的BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public topNewsAdapter() {           mBitmapUtils = new BitmapUtils(mActivity);           // 设置加载中的默认图片           mBitmapUtils.configDefaultLoadingImage(R.drawable.pic_item_List_default);        }        @OverrIDe        public int getCount() {            return mtopNewsList.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            ImageVIEw vIEw = new ImageVIEw(mActivity);            NewsTab.topNews topNews = mtopNewsList.get(position);            String topimage = topNews.topimage; // 图片的下载链接            vIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY); // 设置缩放模式:宽高匹配窗体            /**             * 1,根据url下载图片             * 2.将图片设置给ImageVIEw             * 3.将图片作成缓存             * 4.避免内存溢出             * 由于工程量巨大,这里使用xUtils中的BitmapUtils里的API来完成这四个逻辑             */            mBitmapUtils.display(vIEw,topimage);            container.addVIEw(vIEw);            return vIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }    /**     * 新闻列表适配器     */    class NewsAdapter extends BaseAdapter{        /**         * BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public NewsAdapter() {            mBitmapUtils = new BitmapUtils(mActivity);            mBitmapUtils.configDefaultLoadingImage(R.drawable.news_pic_default);        }        @OverrIDe        public int getCount() {            return mNewsList.size();        }        @OverrIDe        public NewsTab.News getItem(int position) {            return mNewsList.get(position);        }        @OverrIDe        public long getItemID(int position) {            return position;        }        @OverrIDe        public VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) {            VIEwHolder holder;            if (convertVIEw == null){                convertVIEw = VIEw.inflate(mActivity,R.layout.List_item_news,null);                holder = new VIEwHolder();                holder.ivIcon = (ImageVIEw) convertVIEw.findVIEwByID(R.ID.iv_icon);                holder.tvTitle = (TextVIEw) convertVIEw.findVIEwByID(R.ID.tv_Title3);                holder.tvTime = (TextVIEw) convertVIEw.findVIEwByID(R.ID.tv_time);                convertVIEw.setTag(holder);            }else {                holder = (VIEwHolder) convertVIEw.getTag();            }            NewsTab.News info = getItem(position);            holder.tvTitle.setText(info.Title);            holder.tvTime.setText(info.pubdate);            mBitmapUtils.display(holder.ivIcon,info.listimage);            return convertVIEw;        }    }    static class VIEwHolder{        public ImageVIEw ivIcon;        public TextVIEw tvTitle;        public TextVIEw tvTime;    }}
16.给ListVIEw添加头布局展示头条新闻

在上一节中我们添加了一个ListVIEw,但是在实际使用时,我们发现ListVIEw只能控制下部滑动,没有整体滑动,这里使用ListVIEw.addheadVIEw(VIEw vIEw)这个API来实现一下,这里我们来调整一下

新建一个布局文件List_item_header.xml,将paper_tab_detail.xml中的图片轮播那块抽离出来,代码如下:
<?xml version="1.0" enCoding="utf-8"?><FrameLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    xmlns:app="http://schemas.androID.com/apk/res-auto"    androID:layout_wIDth="match_parent"    androID:layout_height="180dp">    <com.example.zhbj.vIEw.topNewsVIEwPaper        androID:ID="@+ID/vp_tab_detail"        androID:layout_wIDth="match_parent"        androID:layout_height="180dp"/>    <relativeLayout        androID:layout_wIDth="match_parent"        androID:layout_height="wrap_content"        androID:layout_gravity="bottom"        androID:padding="5dp"        androID:background="#9000">        <TextVIEw            androID:ID="@+ID/tv_Title2"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:textcolor="#fff"            androID:textSize="16sp"/>        <com.vIEwpagerindicator.CirclePageIndicator            androID:ID="@+ID/indicator2"            androID:layout_height="wrap_content"            androID:layout_wIDth="wrap_content"            androID:layout_alignParentRight="true"            androID:layout_centerVertical="true"            androID:paddingleft="5dp"            androID:paddingRight="5dp"            app:radius="3dp"            app:fillcolor="#f00"            app:pagecolor="#cccccc"            app:strokeWIDth="0dp" />    </relativeLayout></FrameLayout>
修改paper_tab_detail,删除之前写的图片轮播部分,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <!--   有时候滑动ListVIEw整个背景变为黑色,可以加属性cachecolorHint修改缓冲区的颜色 -->    <ListVIEw        androID:ID="@+ID/lv_List"        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:cachecolorHint="@androID:color/transparent"        androID:layout_weight="1"/></linearLayout>
修改TabDetailPaper,修改initVIEws()方法,加载头布局,代码如下:
package com.example.zhbj.base.impl;import androID.app.Activity;import androID.graphics.color;import androID.support.annotation.NonNull;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.text.TextUtils;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.BaseAdapter;import androID.Widget.ImageVIEw;import androID.Widget.ListVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.zhbj.R;import com.example.zhbj.base.BaseMenuDetailPaper;import com.example.zhbj.domain.NewsMenu;import com.example.zhbj.domain.NewsTab;import com.example.zhbj.global.GlobalConstans;import com.example.zhbj.util.CacheUtil;import com.example.zhbj.vIEw.topNewsVIEwPaper;import com.Google.gson.Gson;import com.lIDroID.xutils.BitmapUtils;import com.lIDroID.xutils.httpUtils;import com.lIDroID.xutils.VIEwUtils;import com.lIDroID.xutils.exception.httpException;import com.lIDroID.xutils.http.ResponseInfo;import com.lIDroID.xutils.http.callback.RequestCallBack;import com.lIDroID.xutils.http.clIEnt.httpRequest;import com.lIDroID.xutils.vIEw.annotation.VIEwInject;import com.vIEwpagerindicator.CirclePageIndicator;import java.util.ArrayList;/** * 页签详情页,包含北京、中国、国际等页签 * VIEwPagerIndicator * 1.引入VIEwPagerIndicator库 * 2.解决v4冲突,用大的版本覆盖小的版本 * 3.仿照sample中的程序进行拷贝SampleTabsDefault */public class TabDetailPaper extends BaseMenuDetailPaper {    /**     * 当前页签数据     */    private NewsMenu.NewsTabData newsTabData;    /**     * 文本框对象     */     // private TextVIEw vIEw;    /**     * VIEwPager对象     */    @VIEwInject(R.ID.vp_tab_detail)    private topNewsVIEwPaper mVIEwPaper;    /**     * 请求的URL地址     */    private String mUrl;    /**     * 保存头条新闻图片的集合     */    private ArrayList<NewsTab.topNews> mtopNewsList;    /**     * TextVIEw控件实例     */    @VIEwInject(R.ID.tv_Title2)    private TextVIEw tvTitle;    /**     * Indicator控件实例     */    @VIEwInject(R.ID.indicator2)    private CirclePageIndicator mIndicator;    /**     * ListVIEw控件实例     */    @VIEwInject(R.ID.lv_List)    private ListVIEw lvList;    /**     * 存储新闻列表的集合     */    private ArrayList<NewsTab.News> mNewsList;    public TabDetailPaper(Activity activity, NewsMenu.NewsTabData newsTabData) {        super(activity);        this.newsTabData = newsTabData;        mUrl = GlobalConstans.SERVER_URL + newsTabData.url;    }    @OverrIDe    public VIEw initVIEws() {        /*        vIEw = new TextVIEw(mActivity);        vIEw.setTextSize(22);        vIEw.setTextcolor(color.RED);        vIEw.setGravity(Gravity.CENTER); // 居中显示        vIEw.setText("页签");         */        VIEw vIEw = VIEw.inflate(mActivity,R.layout.paper_tab_detail,null);        // 加载头条新闻的头布局        VIEw headerVIEw = VIEw.inflate(mActivity,R.layout.List_item_header,null);        VIEwUtils.inject(this,vIEw);        VIEwUtils.inject(this,headerVIEw);        lvList.addheaderVIEw(headerVIEw); // 给ListVIEw添加头布局        return vIEw;    }    @OverrIDe    public voID initData() {        // vIEw.setText(newsTabData.Title); // 修改当前布局的数据        String cache = CacheUtil.getCache(mActivity, mUrl);        if (!TextUtils.isEmpty(cache)){            // 有缓存            processData(cache);        }        getDataFromServer();    }    /**     * 从服务器中获取数据     */    private voID getDataFromServer() {        httpUtils utils = new httpUtils();        utils.send(httpRequest.httpMethod.GET, mUrl, new RequestCallBack<String>() {            @OverrIDe            public voID onSuccess(ResponseInfo<String> responseInfo) {                String result = responseInfo.result;                processData(result);                CacheUtil.setCache(mActivity,mUrl,result);            }            @OverrIDe            public voID onFailure(httpException e, String s) {                e.printstacktrace();                Toast.makeText(mActivity,s,Toast.LENGTH_SHORT).show();            }        });    }    private voID processData(String result) {        Gson gson = new Gson();        NewsTab newsTab = gson.fromJson(result, NewsTab.class);        // 初始化头条新闻数据        mtopNewsList = newsTab.data.topnews;        if (mtopNewsList != null){            mVIEwPaper.setAdapter(new topNewsAdapter());            mIndicator.setVIEwPager(mVIEwPaper); // 将圆形指示器和vIEwpager绑定            mIndicator.setSnap(true); // 快照展示方式            mIndicator.onPageSelected(0); // 将圆点位置归零,保证圆点和页面同步            mIndicator.setonPagechangelistener(new VIEwPager.OnPagechangelistener() {                @OverrIDe                public voID onPageScrolled(int i, float v, int i1) {                }                @OverrIDe                public voID onPageSelected(int i) {                    // 更新头条新闻的标题                    tvTitle.setText(mtopNewsList.get(i).Title);                }                @OverrIDe                public voID onPageScrollStateChanged(int i) {                }            });            // 初始化首页标题            tvTitle.setText(mtopNewsList.get(0).Title);        }        /**         * 初始化新闻列表数据         */        mNewsList = newsTab.data.news;        if (mNewsList != null){            lvList.setAdapter(new NewsAdapter());        }    }    class topNewsAdapter extends PagerAdapter{        /**         * xUtils中的BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public topNewsAdapter() {           mBitmapUtils = new BitmapUtils(mActivity);           // 设置加载中的默认图片           mBitmapUtils.configDefaultLoadingImage(R.drawable.pic_item_List_default);        }        @OverrIDe        public int getCount() {            return mtopNewsList.size();        }        @OverrIDe        public boolean isVIEwFromObject(@NonNull VIEw vIEw, @NonNull Object o) {            return vIEw == o;        }        @NonNull        @OverrIDe        public Object instantiateItem(@NonNull VIEwGroup container, int position) {            ImageVIEw vIEw = new ImageVIEw(mActivity);            NewsTab.topNews topNews = mtopNewsList.get(position);            String topimage = topNews.topimage; // 图片的下载链接            vIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY); // 设置缩放模式:宽高匹配窗体            /**             * 1,根据url下载图片             * 2.将图片设置给ImageVIEw             * 3.将图片作成缓存             * 4.避免内存溢出             * 由于工程量巨大,这里使用xUtils中的BitmapUtils里的API来完成这四个逻辑             */            mBitmapUtils.display(vIEw,topimage);            container.addVIEw(vIEw);            return vIEw;        }        @OverrIDe        public voID destroyItem(@NonNull VIEwGroup container, int position, @NonNull Object object) {            container.removeVIEw((VIEw) object);        }    }    /**     * 新闻列表适配器     */    class NewsAdapter extends BaseAdapter{        /**         * BitmapUtils工具类         */        private BitmapUtils mBitmapUtils;        public NewsAdapter() {            mBitmapUtils = new BitmapUtils(mActivity);            mBitmapUtils.configDefaultLoadingImage(R.drawable.news_pic_default);        }        @OverrIDe        public int getCount() {            return mNewsList.size();        }        @OverrIDe        public NewsTab.News getItem(int position) {            return mNewsList.get(position);        }        @OverrIDe        public long getItemID(int position) {            return position;        }        @OverrIDe        public VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) {            VIEwHolder holder;            if (convertVIEw == null){                convertVIEw = VIEw.inflate(mActivity,R.layout.List_item_news,null);                holder = new VIEwHolder();                holder.ivIcon = (ImageVIEw) convertVIEw.findVIEwByID(R.ID.iv_icon);                holder.tvTitle = (TextVIEw) convertVIEw.findVIEwByID(R.ID.tv_Title3);                holder.tvTime = (TextVIEw) convertVIEw.findVIEwByID(R.ID.tv_time);                convertVIEw.setTag(holder);            }else {                holder = (VIEwHolder) convertVIEw.getTag();            }            NewsTab.News info = getItem(position);            holder.tvTitle.setText(info.Title);            holder.tvTime.setText(info.pubdate);            mBitmapUtils.display(holder.ivIcon,info.listimage);            return convertVIEw;        }    }    static class VIEwHolder{        public ImageVIEw ivIcon;        public TextVIEw tvTitle;        public TextVIEw tvTime;    }}
18.自定义下拉刷新 & 隐藏头布局

现在我们将ListVIEw配置好了,接下来就需要实现下拉刷新数据以及隐藏头布局的效果

新建一个下拉刷新的布局pull_to_refresh_header.xml,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="wrap_content"    androID:orIEntation="horizontal">    <FrameLayout        androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        androID:padding="10dp">        <ImageVIEw            androID:ID="@+ID/iv_arrow"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:layout_gravity="center"            androID:src="@drawable/common_ListvIEw_headvIEw_red_arrow"/>        <Progressbar            androID:ID="@+ID/pb_loading"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:layout_gravity="center"/>    </FrameLayout>    <linearLayout        androID:layout_wIDth="match_parent"        androID:layout_height="wrap_content"        androID:gravity="center"        androID:layout_gravity="center"        androID:orIEntation="vertical">        <TextVIEw            androID:ID="@+ID/tv_state"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:text="下拉刷新"            androID:textcolor="#f00"            androID:textSize="18sp"/>        <TextVIEw            androID:ID="@+ID/tv_time2"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:text="刷新时间"            androID:layout_margintop="5dp"            androID:textcolor="#a000"            androID:textSize="16sp"/>    </linearLayout></linearLayout>
为了在ListVIEw上显示这个刷新效果,在vIEw包下新建一个类RefreshListVIEw,用于封装这些效果,代码如下:
package com.example.zhbj.vIEw;import androID.content.Context;import androID.util.AttributeSet;import androID.vIEw.VIEw;import androID.Widget.ListVIEw;import com.example.zhbj.R;/** * 下拉刷新ListVIEw */public class RefreshListVIEw extends ListVIEw {    /**     * headVIEw对象     */    private VIEw mheadVIEw;    public RefreshListVIEw(Context context) {        this(context, null);    }    public RefreshListVIEw(Context context, AttributeSet attrs) {        this(context, attrs, -1);    }    public RefreshListVIEw(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initheaderVIEw();    }    /**     * 初始化头布局     */    private voID initheaderVIEw(){        mheadVIEw = VIEw.inflate(getContext(),R.layout.pull_to_refresh_header,null);        addheaderVIEw(mheadVIEw); // 给ListVIEw添加头布局    }}
修改paper_tab_detail.xml,修改组件属性,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:orIEntation="vertical">    <!--   有时候滑动ListVIEw整个背景变为黑色,可以加属性cachecolorHint修改缓冲区的颜色 -->    <com.example.zhbj.vIEw.RefreshListVIEw        androID:ID="@+ID/lv_List"        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:cachecolorHint="@androID:color/transparent"        androID:layout_weight="1"/></linearLayout>
修改TabDetailPaper,同步之前定义好的组件,代码如下:
    /**     * ListVIEw控件实例     */    @VIEwInject(R.ID.lv_List)    private RefreshListVIEw lvList;
修改RefreshListVIEw,修改initheaderVIEw()方法,添加隐藏加载条的逻辑,代码如下:
package com.example.zhbj.vIEw;import androID.content.Context;import androID.util.AttributeSet;import androID.vIEw.VIEw;import androID.Widget.ListVIEw;import com.example.zhbj.R;/** * 下拉刷新ListVIEw */public class RefreshListVIEw extends ListVIEw {    /**     * 当前布局的高度     */    private int mMeasuredHeight;    /**     * headVIEw对象     */    private VIEw mheadVIEw;    public RefreshListVIEw(Context context) {        this(context, null);    }    public RefreshListVIEw(Context context, AttributeSet attrs) {        this(context, attrs, -1);    }    public RefreshListVIEw(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initheaderVIEw();    }    /**     * 初始化头布局     */    private voID initheaderVIEw(){        mheadVIEw = VIEw.inflate(getContext(),R.layout.pull_to_refresh_header,null);        addheaderVIEw(mheadVIEw); // 给ListVIEw添加头布局        /*        隐藏头布局        1.获取当前头布局高度        2.设置负paddingtop,布局就会向上走         */        // int height = mheadVIEw.getHeight(); 不能这样获取宽高,因为没有绘制完毕        mheadVIEw.measure(0,0); // 手动测量,宽高传0表示不参与具体宽高的设定,全由系统底层决定        mMeasuredHeight = mheadVIEw.getMeasuredHeight(); // 获取测量后的高度        mheadVIEw.setpadding(0,-mMeasuredHeight,0,0);    }}
19.自定义圆环进度条

现在进度条的逻辑已经实现完毕,为了进一步的美化,这里我们想要自定义一个圆环形的进度条

在drawable目录下新建shape_custom_progress.xml的shape文件,作为自定义的圆环进度条文件,代码如下:
<?xml version="1.0" enCoding="utf-8"?><rotate xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:fromdegrees="0"    androID:todegrees="360"    androID:pivotX="50%"    androID:pivotY="50%">    <shape        androID:shape="ring"        androID:useLevel="false"        androID:innerRadius="16dp"        androID:thickness="3dp">        <gradIEnt            androID:startcolor="#fff"            androID:centercolor="#5f00"            androID:endcolor="#f00" />    </shape></rotate>
修改pull_to_refresh_head.xml,使用indeterminateDrawable属性应用刚才创建好的shape文件,代码如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="wrap_content"    androID:orIEntation="horizontal">    <FrameLayout        androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        androID:padding="10dp">        <ImageVIEw            androID:ID="@+ID/iv_arrow"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:layout_gravity="center"            androID:src="@drawable/common_ListvIEw_headvIEw_red_arrow"/>        <Progressbar            androID:ID="@+ID/pb_loading"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:indeterminateDrawable="@drawable/shape_custom_progress"            androID:layout_gravity="center"/>    </FrameLayout>    <linearLayout        androID:layout_wIDth="match_parent"        androID:layout_height="wrap_content"        androID:gravity="center"        androID:layout_gravity="center"        androID:orIEntation="vertical">        <TextVIEw            androID:ID="@+ID/tv_state"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:text="下拉刷新"            androID:textcolor="#f00"            androID:textSize="18sp"/>        <TextVIEw            androID:ID="@+ID/tv_time2"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:text="刷新时间"            androID:layout_margintop="5dp"            androID:textcolor="#a000"            androID:textSize="16sp"/>    </linearLayout></linearLayout>
点赞收藏分享文章举报

赈川发布了253 篇原创文章 · 获赞 52 · 访问量 3万+私信 关注 总结

以上是内存溢出为你收集整理的Android开发实战《智慧北京》——3.完善视图全部内容,希望文章能够帮你解决Android开发实战《智慧北京》——3.完善视图所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1067909.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存