Android 垃圾分类APP(五)垃圾分类新闻展示

简介: Android 垃圾分类APP(五)垃圾分类新闻展示

垃圾分类新闻展示


前言


 上一篇文章中完成了图像输入进行垃圾分类,这篇文章进行主页面的UI丰富。


正文


  点击天行API,登录之后,找到垃圾分类新闻,点击申请接口。


一、申请新闻接口数据

20210415171820754.png



点击立即申请


20210415172038262.png


申请之后点击立即调试


20210415172120519.png


点击测试请求。


20210415172226305.png


返回数据如下:


{
  "code": 200,
  "msg": "success",
  "newslist": [
    {
      "id": "60bc69482712658255dcef1551721cec",
      "ctime": "2021-04-15 14:25",
      "title": "小区垃圾成山?垃圾分类,咱可不能松劲儿",
      "description": "再过半个月,《北京市生活垃圾管理条例》实施就将迎来一周年。在将近一年的时间里,北京生活垃圾分类进行得如火如荼,成效有目共睹。但是,根据12345热线近期接到的市",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd20210415s/300/w720h380/20210415/aaec-knvsnuf3073914.jpg",
      "url": "http://k.sina.com.cn/article_1893892941_70e2834d02000z095.html"
    },
    {
      "id": "a1deecc9545794fcc7471f0342017f04",
      "ctime": "2021-04-15 14:31",
      "title": "昆山巴城镇四强化“问诊”垃圾分类",
      "description": "消费日报网讯(记者汪宏胜通讯员陆飞)今年3月,昆山市巴城镇嘉馨花园小区被昆山市垃圾分类办公室列为“灰榜”小区,为进一步提升小区分类秩序,提高居民分类意识",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd20210415ac/40/w480h360/20210415/08c3-knvsnuf3088674.jpg",
      "url": "http://k.sina.com.cn/article_2381872931_8df87f2300100sxzn.html"
    },
    {
      "id": "edc277a31fb5dbd8b46f2cf56efe0c79",
      "ctime": "2021-04-15 14:47",
      "title": "义乌后宅开展垃圾分类积分兑换活动",
      "description": "为进一步提高《浙江省生活垃圾管理条例》宣传热度,充分调动全民参与垃圾分类的积极性,推进辖区内垃圾分类工作,4月14日下午,义乌后宅街道金城社区开展垃圾分类积分兑",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd2021415s/63/w950h713/20210415/0140-knvsnuf3234457.jpg",
      "url": "http://k.sina.com.cn/article_7505202169_1bf584bf902000ubei.html"
    },
    {
      "id": "4a90ac4f40a90502547ddc3d15a5908e",
      "ctime": "2021-04-15 15:14",
      "title": "垃圾分类进校园 争当环保小卫士",
      "description": "当日,为培养小朋友的环保意识,进一步普及垃圾分类知识,浙江省杭州市临安区高虹镇新时代文明实践所的党员志愿者,在高虹镇中心幼儿园开展“垃圾分类进校园争当环保小卫",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd20210415s/320/w2048h3072/20210415/7401-knvsnuf3339853.jpg",
      "url": "http://k.sina.com.cn/article_213815211_0cbe8fab020016rcp.html"
    },
    {
      "id": "f29eed1a0f5c026f15aef324b6404a21",
      "ctime": "2021-04-15 15:18",
      "title": "大数据垃圾分类,提高垃圾分类的精细化",
      "description": "随着经济社会的快速发展和生活水平的不断提高,日常产生的垃圾也越来越多,如果不控制,不断增长的垃圾将超过处理设施的处理能力。“垃圾围城”已经成为摆在我们面前的严重",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd10015/580/w828h552/20210415/e4d1-knvsnuf3264346.jpg",
      "url": "http://t.cj.sina.com.cn/articles/view/6901783348/19b60db3400100xeou"
    },
    {
      "id": "f854f2235feeff4dc9a22f2ee3b0f09f",
      "ctime": "2021-04-15 15:21",
      "title": "博澳丽苑小区开展“小宝贝 大行动--垃圾分类 从我做起”主题活动",
      "description": "为了让园区小朋友了解垃圾分类的相关知识,增强学生规范投放垃圾的意识,4月14日下午,博澳丽苑小区开展了“小宝贝大行动--垃圾分类从我做起”主题活动。此次活动是",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd20210415ac/40/w480h360/20210415/8226-knvsnuf3291986.jpg",
      "url": "http://k.sina.com.cn/article_6545302907_18621657b00100xfsm.html"
    },
    {
      "id": "47ae268164053c1b79507e3b1f30b7bf",
      "ctime": "2021-04-15 15:27",
      "title": "石柱首批25名“蓝背心”垃圾分类志愿者上岗",
      "description": "志愿者对厨余垃圾垃圾进行第二次分拣。通讯员隆太良摄  “大爷,您这是可回收物,不能扔到厨余垃圾桶里哟!”“大妈,您好,请让我检查一下袋子里的垃圾分类情况。”",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd2021415s/33/w500h333/20210415/18ef-knvsnuf3416978.jpg",
      "url": "http://k.sina.com.cn/article_1784473157_6a5ce645020026m67.html"
    },
    {
      "id": "d88998492bb1b5c5882c73b6f1e22e60",
      "ctime": "2021-04-15 16:12",
      "title": "南京青奥社区开展“垃圾分类要做好 美好生活在青奥”主题活动",
      "description": "扬子晚报网4月15日讯(记者徐昇)4月10日,南京建邺区双闸街道青奥社区网格员联合双闸派出所民警、党员志愿者、政法网格员在辖区内三个居民小区开展垃圾分类宣传、",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd20210415s/300/w720h380/20210415/c491-knvsnuf3459691.jpg",
      "url": "http://k.sina.com.cn/article_1653603955_628ffe73020012okc.html"
    },
    {
      "id": "c0757bfb20c48c87f28d219688633d4b",
      "ctime": "2021-04-15 16:25",
      "title": "进贤县粮食局开展生活垃圾分类培训",
      "description": "  大江网魅力频道讯为进一步增强粮食系统干职工生活垃圾分类意识,助力进贤县全面建成生活垃圾分类体系,实现生活垃圾分类全覆盖。4月13日下午,进贤县粮食局开展生",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/default/feedbackpics/transform/116/w550h366/20180409/gDCK-fytnfyp1107789.png",
      "url": "http://k.sina.com.cn/article_2341087142_8b8a27a60200105zf.html"
    },
    {
      "id": "1531d80b321e4fcda4d2ea93f022c743",
      "ctime": "2021-04-15 12:58",
      "title": "公共机构生活垃圾咋分类?烟台市心理康复医院开展专项培训",
      "description": "通讯员 丛冰 孙晓梦 齐鲁晚报·齐鲁壹点记者 孙淑玉为深入推进全市公共机构生活垃圾分类和塑料污染治理工作,积极倡导“垃圾分类就是新时尚”理念,切实增强医院职工",
      "source": "垃圾分类新闻",
      "picUrl": "http://n.sinaimg.cn/sinakd2021415s/399/w720h479/20210415/d25a-knvsnuf2768165.jpg",
      "url": "http://k.sina.com.cn/article_5328858693_13d9fee45020015vf8.html"
    }
  ]
}


通过这个返回数据,在model包下新建一个TrashNewsResponse类,里面的代码如下:


package com.llw.goodtrash.model;
import java.util.List;
/**
 * 垃圾分类新闻返回实体
 *
 * @author llw
 * @date 2021/4/15 17:24
 */
public class TrashNewsResponse {
    /**
     * code : 200
     * msg : success
     * newslist : [{"id":"60bc69482712658255dcef1551721cec","ctime":"2021-04-15 14:25","title":"小区垃圾成山?垃圾分类,咱可不能松劲儿","description":"再过半个月,《北京市生活垃圾管理条例》实施就将迎来一周年。在将近一年的时间里,北京生活垃圾分类进行得如火如荼,成效有目共睹。但是,根据12345热线近期接到的市","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd20210415s/300/w720h380/20210415/aaec-knvsnuf3073914.jpg","url":"http://k.sina.com.cn/article_1893892941_70e2834d02000z095.html"},{"id":"a1deecc9545794fcc7471f0342017f04","ctime":"2021-04-15 14:31","title":"昆山巴城镇四强化\u201c问诊\u201d垃圾分类","description":"消费日报网讯(记者汪宏胜通讯员陆飞)今年3月,昆山市巴城镇嘉馨花园小区被昆山市垃圾分类办公室列为\u201c灰榜\u201d小区,为进一步提升小区分类秩序,提高居民分类意识","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd20210415ac/40/w480h360/20210415/08c3-knvsnuf3088674.jpg","url":"http://k.sina.com.cn/article_2381872931_8df87f2300100sxzn.html"},{"id":"edc277a31fb5dbd8b46f2cf56efe0c79","ctime":"2021-04-15 14:47","title":"义乌后宅开展垃圾分类积分兑换活动","description":"为进一步提高《浙江省生活垃圾管理条例》宣传热度,充分调动全民参与垃圾分类的积极性,推进辖区内垃圾分类工作,4月14日下午,义乌后宅街道金城社区开展垃圾分类积分兑","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd2021415s/63/w950h713/20210415/0140-knvsnuf3234457.jpg","url":"http://k.sina.com.cn/article_7505202169_1bf584bf902000ubei.html"},{"id":"4a90ac4f40a90502547ddc3d15a5908e","ctime":"2021-04-15 15:14","title":"垃圾分类进校园 争当环保小卫士","description":"当日,为培养小朋友的环保意识,进一步普及垃圾分类知识,浙江省杭州市临安区高虹镇新时代文明实践所的党员志愿者,在高虹镇中心幼儿园开展\u201c垃圾分类进校园争当环保小卫","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd20210415s/320/w2048h3072/20210415/7401-knvsnuf3339853.jpg","url":"http://k.sina.com.cn/article_213815211_0cbe8fab020016rcp.html"},{"id":"f29eed1a0f5c026f15aef324b6404a21","ctime":"2021-04-15 15:18","title":"大数据垃圾分类,提高垃圾分类的精细化","description":"随着经济社会的快速发展和生活水平的不断提高,日常产生的垃圾也越来越多,如果不控制,不断增长的垃圾将超过处理设施的处理能力。\u201c垃圾围城\u201d已经成为摆在我们面前的严重","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd10015/580/w828h552/20210415/e4d1-knvsnuf3264346.jpg","url":"http://t.cj.sina.com.cn/articles/view/6901783348/19b60db3400100xeou"},{"id":"f854f2235feeff4dc9a22f2ee3b0f09f","ctime":"2021-04-15 15:21","title":"博澳丽苑小区开展\u201c小宝贝 大行动--垃圾分类 从我做起\u201d主题活动","description":"为了让园区小朋友了解垃圾分类的相关知识,增强学生规范投放垃圾的意识,4月14日下午,博澳丽苑小区开展了\u201c小宝贝大行动--垃圾分类从我做起\u201d主题活动。此次活动是","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd20210415ac/40/w480h360/20210415/8226-knvsnuf3291986.jpg","url":"http://k.sina.com.cn/article_6545302907_18621657b00100xfsm.html"},{"id":"47ae268164053c1b79507e3b1f30b7bf","ctime":"2021-04-15 15:27","title":"石柱首批25名\u201c蓝背心\u201d垃圾分类志愿者上岗","description":"志愿者对厨余垃圾垃圾进行第二次分拣。通讯员隆太良摄  \u201c大爷,您这是可回收物,不能扔到厨余垃圾桶里哟!\u201d\u201c大妈,您好,请让我检查一下袋子里的垃圾分类情况。\u201d","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd2021415s/33/w500h333/20210415/18ef-knvsnuf3416978.jpg","url":"http://k.sina.com.cn/article_1784473157_6a5ce645020026m67.html"},{"id":"d88998492bb1b5c5882c73b6f1e22e60","ctime":"2021-04-15 16:12","title":"南京青奥社区开展\u201c垃圾分类要做好 美好生活在青奥\u201d主题活动","description":"扬子晚报网4月15日讯(记者徐昇)4月10日,南京建邺区双闸街道青奥社区网格员联合双闸派出所民警、党员志愿者、政法网格员在辖区内三个居民小区开展垃圾分类宣传、","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd20210415s/300/w720h380/20210415/c491-knvsnuf3459691.jpg","url":"http://k.sina.com.cn/article_1653603955_628ffe73020012okc.html"},{"id":"c0757bfb20c48c87f28d219688633d4b","ctime":"2021-04-15 16:25","title":"进贤县粮食局开展生活垃圾分类培训","description":"  大江网魅力频道讯为进一步增强粮食系统干职工生活垃圾分类意识,助力进贤县全面建成生活垃圾分类体系,实现生活垃圾分类全覆盖。4月13日下午,进贤县粮食局开展生","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/default/feedbackpics/transform/116/w550h366/20180409/gDCK-fytnfyp1107789.png","url":"http://k.sina.com.cn/article_2341087142_8b8a27a60200105zf.html"},{"id":"1531d80b321e4fcda4d2ea93f022c743","ctime":"2021-04-15 12:58","title":"公共机构生活垃圾咋分类?烟台市心理康复医院开展专项培训","description":"通讯员 丛冰 孙晓梦 齐鲁晚报·齐鲁壹点记者 孙淑玉为深入推进全市公共机构生活垃圾分类和塑料污染治理工作,积极倡导\u201c垃圾分类就是新时尚\u201d理念,切实增强医院职工","source":"垃圾分类新闻","picUrl":"http://n.sinaimg.cn/sinakd2021415s/399/w720h479/20210415/d25a-knvsnuf2768165.jpg","url":"http://k.sina.com.cn/article_5328858693_13d9fee45020015vf8.html"}]
     */
    private int code;
    private String msg;
    private List<NewslistBean> newslist;
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public List<NewslistBean> getNewslist() {
        return newslist;
    }
    public void setNewslist(List<NewslistBean> newslist) {
        this.newslist = newslist;
    }
    public static class NewslistBean {
        /**
         * id : 60bc69482712658255dcef1551721cec
         * ctime : 2021-04-15 14:25
         * title : 小区垃圾成山?垃圾分类,咱可不能松劲儿
         * description : 再过半个月,《北京市生活垃圾管理条例》实施就将迎来一周年。在将近一年的时间里,北京生活垃圾分类进行得如火如荼,成效有目共睹。但是,根据12345热线近期接到的市
         * source : 垃圾分类新闻
         * picUrl : http://n.sinaimg.cn/sinakd20210415s/300/w720h380/20210415/aaec-knvsnuf3073914.jpg
         * url : http://k.sina.com.cn/article_1893892941_70e2834d02000z095.html
         */
        private String id;
        private String ctime;
        private String title;
        private String description;
        private String source;
        private String picUrl;
        private String url;
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getCtime() {
            return ctime;
        }
        public void setCtime(String ctime) {
            this.ctime = ctime;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public String getSource() {
            return source;
        }
        public void setSource(String source) {
            this.source = source;
        }
        public String getPicUrl() {
            return picUrl;
        }
        public void setPicUrl(String picUrl) {
            this.picUrl = picUrl;
        }
        public String getUrl() {
            return url;
        }
        public void setUrl(String url) {
            this.url = url;
        }
    }
}


数据就有了。


二、垃圾分类新闻接口请求


我希望在主页面设置一个轮播图,对每天的垃圾分类新闻进行一个轮播,那么首先要完成接口的请求。打开ApiService。在里面添加一个接口,如下:


  /**
     * 垃圾分类新闻
     * @param num 数量
     * @return TrashNewsResponse 结果实体
     */
    @GET("/lajifenleinews/index?key=" + KEY)
    Observable<TrashNewsResponse> getTrashNews(@Query("num") Integer num);


然后修改MainContract类,如下所示:


package com.llw.goodtrash.contract;
import android.annotation.SuppressLint;
import com.llw.goodtrash.api.ApiService;
import com.llw.goodtrash.model.TrashNewsResponse;
import com.llw.goodtrash.model.TrashResponse;
import com.llw.mvplibrary.base.BasePresenter;
import com.llw.mvplibrary.base.BaseView;
import com.llw.mvplibrary.network.NetworkApi;
import com.llw.mvplibrary.network.observer.BaseObserver;
/**
 * 主页面访问网络
 *
 * @author llw
 * @date 2021/3/30 15:28
 */
public class MainContract {
    public static class MainPresenter extends BasePresenter<MainView> {
        /**
         * 垃圾分类新闻
         *
         * @param num 数量
         */
        @SuppressLint("CheckResult")
        public void getTrashNews(Integer num) {
            ApiService service = NetworkApi.createService(ApiService.class,0);
            service.getTrashNews(num).compose(NetworkApi.applySchedulers(new BaseObserver<TrashNewsResponse>() {
                @Override
                public void onSuccess(TrashNewsResponse trashNewsResponse) {
                    if (getView() != null) {
                        getView().getTrashNewsResponse(trashNewsResponse);
                    }
                }
                @Override
                public void onFailure(Throwable e) {
                    if (getView() != null) {
                        getView().getTrashNewsFailed(e);
                    }
                }
            }));
        }
    }
    public interface MainView extends BaseView {
        /**
         * 获取垃圾分类新闻返回
         *
         * @param response
         */
        void getTrashNewsResponse(TrashNewsResponse response);
        /**
         * 搜索物品异常返回
         *
         * @param throwable
         */
        void getTrashNewsFailed(Throwable throwable);
    }
}


再回到MainActivity页面,继承MvpActivity。


20210415180350121.png


实现里面的三个方法。


  @Override
    protected MainContract.MainPresenter createPresenter() {
        return new MainContract.MainPresenter();
    }
  /**
     * 获取垃圾分类新闻成功返回
     *
     * @param response
     */
    @Override
    public void getTrashNewsResponse(TrashNewsResponse response) {
        if (response.getCode() == Constant.SUCCESS_CODE) {
            List<TrashNewsResponse.NewslistBean> list = response.getNewslist();
            if (list.size() > 0) {
              //数据显示
            } else {
                showMsg("垃圾分类新闻为空");
            }
        } else {
            showMsg(response.getMsg());
        }
    }
  /**
     * 获取垃圾分类新闻失败返回
     *
     * @param throwable 异常
     */
    @Override
    public void getTrashNewsFailed(Throwable throwable) {
        Log.d(TAG, "获取垃圾分类新闻失败:" + throwable.toString());
    }


然后在initData中调用请求。


  @Override
    public void initData(Bundle savedInstanceState) {
        mPresenter.getTrashNews(10);
    }


那么现在页面上的数据请求和返回就都有了,对于这个数据可以设置两个显示的效果,第一个是顶部的轮播,第二个是页面的列表显示。先来完成轮播的显示。


三、轮播显示


这里我们需要用到一个依赖库,打开你的mvplibrary下的build.gradle,在dependencies{}闭包下添加如下代码:


  //轮播库
    api 'com.youth.banner:banner:2.1.0'

20210415180821123.png


然后Sync Now进行同步,同步之后,进入activity_main.xml,修改页面代码如下:


<!--轮播-->
    <com.youth.banner.Banner
        android:id="@+id/banner"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_200" />


添加位置如下:


20210415181035362.png


下面回到MainActivity,先完成初始化。


  //轮播
    private Banner banner;


在initData方法中绑定控件xml。


20210415181257706.png


banner = findViewById(R.id.banner);


下面写一个显示轮播图的方法


  /**
     * 显示轮播图
     *
     * @param list
     */
    public void showBanner(List<TrashNewsResponse.NewslistBean> list) {
        banner.setAdapter(new BannerImageAdapter<TrashNewsResponse.NewslistBean>(list) {
            @Override
            public void onBindView(BannerImageHolder holder, TrashNewsResponse.NewslistBean data, int position, int size) {
                //显示轮播图片
                Glide.with(holder.itemView)
                        .load(data.getPicUrl())
                        .apply(RequestOptions.bitmapTransform(new RoundedCorners(30)))
                        .into(holder.imageView);
            }
        })
                .addBannerLifecycleObserver(this)//添加生命周期观察者
                .setIndicator(new CircleIndicator(this));
    }


然后在getTrashNewsResponse方法中调用这个显示轮播的方法。


20210415181417395.png


下面运行一下:


20210415181639314.gif


这样就有轮播了,下面来做这个新闻列表的显示。


四、垃圾分类新闻列表


上面的演示效果图想必你已经看到了,那么你就会觉得这三个按钮很突兀,显然不是很搭,同时为了丰富主页面的内容会需要在主页面中添加垃圾分类的新闻列表,这样的话我们可以重新设计一下activity_main.xml的布局,修改后如下:


<?xml version="1.0" encoding="utf-8"?>
<!--协调布局-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">
    <!--应用栏布局-->
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar_layout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_240"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <!--折叠工具栏布局-->
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:collapsedTitleGravity="center"
            app:contentScrim="@color/colorPrimaryDark"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:title="垃圾分类"
            app:toolbarId="@+id/toolbar">
            <!--轮播-->
            <com.youth.banner.Banner
                android:id="@+id/banner"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="1" />
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:contentInsetStart="0dp"
                app:layout_collapseMode="pin"
                app:layout_scrollFlags="scroll|snap"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
    <!--嵌套滑动布局-->
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        android:orientation="vertical"
        android:overScrollMode="never"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_72"
                android:background="@color/white"
                android:gravity="center"
                android:orientation="horizontal">
                <!--文字输入-->
                <com.google.android.material.button.MaterialButton
                    style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
                    android:layout_width="wrap_content"
                    android:layout_height="@dimen/dp_50"
                    android:gravity="center"
                    android:insetTop="@dimen/dp_0"
                    android:insetBottom="@dimen/dp_0"
                    android:onClick="jumpTextInput"
                    android:text="文字"
                    android:textSize="@dimen/sp_16"
                    android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar"
                    app:backgroundTint="@color/colorPrimaryDark"
                    app:cornerRadius="@dimen/dp_12"
                    app:icon="@mipmap/icon_text_input"
                    app:iconGravity="textStart"
                    app:iconSize="@dimen/dp_24" />
                <!--声音输入-->
                <com.google.android.material.button.MaterialButton
                    style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
                    android:layout_width="wrap_content"
                    android:layout_height="@dimen/dp_50"
                    android:layout_marginStart="@dimen/dp_16"
                    android:layout_marginEnd="@dimen/dp_16"
                    android:gravity="center"
                    android:insetTop="@dimen/dp_0"
                    android:insetBottom="@dimen/dp_0"
                    android:onClick="jumpVoiceInput"
                    android:text="语音"
                    android:textSize="@dimen/sp_16"
                    android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar"
                    app:backgroundTint="@color/colorPrimaryDark"
                    app:cornerRadius="@dimen/dp_12"
                    app:icon="@mipmap/icon_voice_input"
                    app:iconGravity="textStart"
                    app:iconSize="@dimen/dp_24" />
                <!--图像输入-->
                <com.google.android.material.button.MaterialButton
                    style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
                    android:layout_width="wrap_content"
                    android:layout_height="@dimen/dp_50"
                    android:gravity="center"
                    android:insetTop="@dimen/dp_0"
                    android:insetBottom="@dimen/dp_0"
                    android:onClick="jumpImageInput"
                    android:text="图像"
                    android:textSize="@dimen/sp_16"
                    android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar"
                    app:backgroundTint="@color/colorPrimaryDark"
                    app:cornerRadius="@dimen/dp_12"
                    app:icon="@mipmap/icon_image_input"
                    app:iconGravity="textStart"
                    app:iconSize="@dimen/dp_24" />
            </LinearLayout>
            <!--垃圾分类新闻列表-->
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv_news"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/dp_2" />
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>


下面先增加一个样式,打开app模块的res → values → styles.xml。在里面添加一个样式


  <!--主页面样式-->
    <style name="MainTheme" parent="AppTheme">
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>


添加位置如下:


20210416152132587.png


然后打开AndroidManifest.xml,将这个样式设置给MainActivity。


20210416152328738.png


下面关于主页面的代码还不着急写,首先要完成这个列表数据的显示,这里还是会有item的布局和适配器,首先创建item的布局,在layout下新建一个item_trash_new_rv.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="wrap_content"
    android:layout_marginBottom="@dimen/dp_1"
    android:id="@+id/item_trash_news"
    android:foreground="?attr/selectableItemBackground"
    android:background="@color/white"
    android:orientation="vertical"
    android:padding="@dimen/dp_16">
    <!--标题-->
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:singleLine="true"
        android:text="标题"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_16"
        android:textStyle="bold" />
    <!--内容描述-->
    <TextView
        android:id="@+id/tv_description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_title"
        android:layout_marginTop="@dimen/dp_8"
        android:text="内容描述"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_14" />
</RelativeLayout>


现在对于这个item的内容就只有标题和内容,可以酌情增加时间或者图标什么的。


然后就是适配器,在adapter下新建一个TrashNewsAdapter类,里面的代码如下:


package com.llw.goodtrash.adapter;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodtrash.R;
import com.llw.goodtrash.model.TrashNewsResponse;
import java.util.List;
/**
 * 垃圾分类新闻列表适配器
 *
 * @author llw
 * @date 2021/4/16 10:36
 */
public class TrashNewsAdapter extends BaseQuickAdapter<TrashNewsResponse.NewslistBean, BaseViewHolder> {
    public TrashNewsAdapter(int layoutResId, @Nullable List<TrashNewsResponse.NewslistBean> data) {
        super(layoutResId, data);
    }
    @Override
    protected void convert(BaseViewHolder helper, TrashNewsResponse.NewslistBean item) {
        helper.setText(R.id.tv_title, item.getTitle())
                .setText(R.id.tv_description, item.getDescription())
                .addOnClickListener(R.id.item_trash_news);
    }
}


下面可以到MainActivity中去写代码了,首先是变量的声明。


  private RecyclerView rvNews;
    private List<TrashNewsResponse.NewslistBean> mList = new ArrayList<>();
    private TrashNewsAdapter mAdapter;
    private CollapsingToolbarLayout collapsingToolbarLayout;
    private AppBarLayout appBarLayout;


然后新建一个initView方法,将之前在initData中的代码也移到这个方法里面。方法代码如下:


  /**
     * 页面初始化
     */
    private void initView() {
        banner = findViewById(R.id.banner);
        collapsingToolbarLayout = findViewById(R.id.toolbar_layout);
        appBarLayout = findViewById(R.id.appbar_layout);
        rvNews = findViewById(R.id.rv_news);
        //伸缩偏移量监听
        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            boolean isShow = true;
            int scrollRange = -1;
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (scrollRange == -1) {
                    scrollRange = appBarLayout.getTotalScrollRange();
                }
                if (scrollRange + verticalOffset == 0) {//收缩时
                    collapsingToolbarLayout.setTitle("垃圾分类");
                    isShow = true;
                } else if (isShow) {//展开时
                    collapsingToolbarLayout.setTitle("");
                    isShow = false;
                }
            }
        });
        //设置列表
        mAdapter = new TrashNewsAdapter(R.layout.item_trash_new_rv, mList);
        mAdapter.setOnItemChildClickListener((adapter, view, position) -> {
            showMsg("点击了第" + position + "个");
        });
        rvNews.setLayoutManager(new LinearLayoutManager(context));
        rvNews.setAdapter(mAdapter);
        //请求垃圾分类新闻数据
        mPresenter.getTrashNews(10);
    }


然后直接在initData中调用initView就可以。


  @Override
    public void initData(Bundle savedInstanceState) {
        //页面初始化
        initView();
    }


然后再写一个显示列表数据的方法


  /**
     * 显示新闻列表
     *
     * @param list
     */
    private void showList(List<TrashNewsResponse.NewslistBean> list) {
        mList.clear();
        mList.addAll(list);
        mAdapter.notifyDataSetChanged();
    }


然后在getTrashNewsResponse中调用。


20210416153317998.png


下面就可以直接运行。


20210416153839670.gif


这样的效果是不是很Nice呢,其实并不难,关键是你想不想去弄。


现在这个新闻有了,那么关于新闻详情页的话,就点击列表的item,然后传url过去,然后在里面用WebView去加载就好了,OK,下面就来写吧。


五、新闻详情页


在ui包下新建一个NewsDetailsActivity,对应的布局是activity_news_details.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:fitsSystemWindows="true"
    android:orientation="vertical">
    <!--标题-->
    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        app:navigationIcon="@mipmap/icon_back"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/white">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="新闻详情"
            android:textColor="@color/black"
            android:textSize="18sp" />
    </com.google.android.material.appbar.MaterialToolbar>
    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>


就是简单的配置WebView,下面回到MainActivity,在initView方法中,修改点击列表item时触发的代码。


  mAdapter.setOnItemChildClickListener((adapter, view, position) -> {
            //跳转到新闻详情页面
            Intent intent = new Intent(context, NewsDetailsActivity.class);
            intent.putExtra("url", mList.get(position).getUrl());
            startActivity(intent);
        });


添加位置如下图:


20210416161600799.png


运行一下:


20210416161821643.png


本篇文章文就到这里了。

相关文章
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
672 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
310 0
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
1545 4
|
数据采集 JSON 网络安全
移动端数据抓取:Android App的TLS流量解密方案
本文介绍了一种通过TLS流量解密技术抓取知乎App热榜数据的方法。利用Charles Proxy解密HTTPS流量,分析App与服务器通信内容;结合Python Requests库模拟请求,配置特定请求头以绕过反爬机制。同时使用代理IP隐藏真实IP地址,确保抓取稳定。最终成功提取热榜标题、内容简介、链接等信息,为分析热点话题和用户趋势提供数据支持。此方法也可应用于其他Android App的数据采集,但需注意选择可靠的代理服务。
738 11
移动端数据抓取:Android App的TLS流量解密方案
|
JSON 数据格式
《仿盒马》app开发技术分享-- 分类右侧商品列表(18)
上一节我们实现了分类页左侧二级分类列表功能,并实现了顶部列表&弹窗跟左侧列表的联动,这一节我们需要在它们联动的基础上继续添加右侧列表的联动效果
195 4
|
JSON 数据挖掘 数据格式
《仿盒马》app开发技术分享-- 分类左侧列表(17)
上一节我们实现了分类页面的顶部导航栏全选弹窗列表,并实现了跟顶部列表的点击选中联动效果,这一节我们要实现的功能是,分类模块的左侧列表,它同样也需要跟弹窗列表的点击,顶部列表的点击有联动的效果
186 4
《仿盒马》app开发技术分享-- 分类模块顶部导航列表弹窗(16)
上一节我们实现了分类页面的顶部导航栏列表,并且实现了首页金刚区跟首页导航栏的联动,这一节我们实现导航栏列表的弹窗功能,需要学习的知识点有自定义弹窗,同时我们的数据源需要跟分类页保持一一致。
226 1
|
JSON 前端开发 数据挖掘
《仿盒马》app开发技术分享-- 分类模块顶部导航列表(15)
上一节我们实现了购物车商品列表的大部分功能,实现了商品的添加、删除、增减、价格计算等业务,并且都跟云端进行通信。现在我们继续对项目进行改造,这一节我们要改造的内容是分类页,这个页面我们在之前的非端云一体化项目中实现过。现在要改造成端云一体的模式,并且我们的金刚区也要实现分类页的点击联动
195 0
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
719 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
750 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡

热门文章

最新文章