手把手带你撸一个校园APP(五):新闻中心模块

这个项目是很早之前在学校做的,如今再回首。很多代码很是粗糙,逻辑也不尽完善。还望各位看官海涵。

前言

通过上一篇文章的功能设计,我们可以发现新闻通知公告等是APP的最主要功能点。主要是聚合展示学校官网的通知公告,官方微信,微博的重要信息,学校社团的活动,以及学校优秀自媒体的文章等等。

系列文章:

  1. 手把手带你撸一个校园APP(一):项目简介
  2. 手把手带你撸一个校园APP(二):应用启动和欢迎页面
  3. 手把手带你撸一个校园APP(三):用户模块(登录注册等)
  4. 手把手带你撸一个校园APP(四):APP框架及功能设计
  5. 手把手带你撸一个校园APP(五):新闻中心模块
  6. 手把手带你撸一个校园APP(六):失物招领&二手交易模块
  7. 手把手带你撸一个校园APP(七):图说校园模块
  8. 手把手带你撸一个校园APP(八):校园通讯录模块
  9. 手把手带你撸一个校园APP(九):课程表模块(模拟登陆爬取教务处课程信息)
  10. 手把手带你撸一个校园APP(十):APP通用模块(更新,意见反馈等)

实现效果

新闻部分主要是分了“通知公告”,“新闻速递”,“自媒体”,“校园文化”四个栏目,之间可以通过左右滑动进行切换。效果图如下:
科师有约新闻模块

分析

其实这是挺常见的一个新闻资讯模块。我们也可以轻易得出以下内容:

  1. 新闻条目 一般都有标题,配图,作者,发表时间等组成。我们的新闻只是聚合展示使用,可以外加一个资讯链接;
  2. 配图数量并不一致,有无图的,1 张配图的,以及 3 张配图的。我们需要根据配图的数量进行不同布局的设置;
  3. 新闻列表应该拥有下拉刷新,上拉加载的功能。

实现

本项目基于Bmob进行开发,很多地方需要Bmob相关知识。大家如果没了解过的话,可先自行查看 Bmob开发文档

数据库

当初设计数据库字段的时候,很多东西都为了简单,没有做更合理的规划。字段如下:

字段名 描述 类型 主键
objectId 用户id String
title 标题 String
author 作者 String
time 发布时间 String
kind 栏目分类 String
content 内容链接 String
pic1 缩略图一 String
pic2 缩略图二 String
pic3 缩略图三 String
tag 布局样式(图片数量) String

大家如果自己从头来的话,建议适当更改部分字段的类型以及组合方式,会更合理些。比如time改为时间类型,图片改为列表等。本文暂且不表。

安卓

逻辑流程讲解

本模块逻辑设计如下:

  1. 使用CoordinatorTabLayout + ViewPager + Fragment 完成新闻模块主页面的显示;
  2. Fragment 进行网络请求,获取新闻数据并展示,使用 RecyclerView 展示新闻列表,根据缩略图数量对应3种条目布局;
  3. 新闻详情页面使用WebView 用于展示新闻详情。

代码实现

在这里为了能快速开发,我们使用了 CoordinatorTabLayout 。

文章:CoordinatorTabLayout组件库
Github地址:CoordinatorTabLayout
作者:hugeterry

使用 CoordinatorTabLayout 搭建新闻主页面

使用步骤如下:

  1. 在 app 的 build.gradle 中添加依赖
dependencies {
    implementation 'cn.hugeterry.coordinatortablayout:coordinatortablayout:1.2.2'
}
  1. 布局文件中使用
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <cn.hugeterry.coordinatortablayout.CoordinatorTabLayout
        android:id="@+id/cootablayout_news"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v4.view.ViewPager
            android:id="@+id/vp_news"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    </cn.hugeterry.coordinatortablayout.CoordinatorTabLayout>

</RelativeLayout>
  1. 在 java 代码中使用
// 四个栏目标题
String[] mTitles = {"通知公告", "新闻速递", "自媒体", "校园文化"}
// 初始化 Fragment 列表
ArrayList<Fragment> mFragments = new ArrayList<>();
mFragments.add(MainFragment1.getInstance(mTitles[0]));
mFragments.add(MainFragment2.getInstance(mTitles[1]));
mFragments.add(MainFragment3.getInstance(mTitles[2]));
mFragments.add(MainFragment4.getInstance(mTitles[3]));

// 设置Viewpager
mViewPager.setOffscreenPageLimit(4);
mViewPager.setAdapter(new MyPagerAdapter(getChildFragmentManager(), mFragments, mTitles));

// 设置顶部 展开后 4 张背景图
mImageArray = new int[]{
        R.mipmap.keshi1,
        R.mipmap.keshi4,
        R.mipmap.img_bg_news3,
        R.mipmap.img_bg_news4};
// 设置顶部 收缩后 4 种背景色
mColorArray = new int[]{
        android.R.color.holo_blue_light,
        android.R.color.holo_red_light,
        android.R.color.holo_orange_light,
        android.R.color.holo_green_light};
// 设置 CoordinatorTabLayout 属性
mCoordinatorTabLayout.setTransulcentStatusBar(mActivity)
        .setTitle("")
        .setImageArray(mImageArray, mColorArray)
        .setupWithViewPager(mViewPager);
网络请求,数据填充
  1. 建立数据库对应表 bean 类
public class NewsBean extends BmobObject {
    private String title;
    private String author;
    private String time;
    private String tag;
    private String pic1;
    private String pic2;
    private String pic3;
    private String content;
    
    // ....get set 方法
}
  1. 网络请求数据,并填充
mAdapter = new NNNAdapter();
newsBeanList = new ArrayList<>();
BmobQuery<NewsBean> query = new BmobQuery<NewsBean>();
query.order("-time");
// kind: [a="通知公告", b="新闻速递", c="自媒体", d="校园文化"]
query.addWhereEqualTo("kind", "a");
query.setLimit(10);
query.findObjects(new FindListener<NewsBean>() {
    @Override
    public void done(List<NewsBean> object, BmobException e) {
        if (e == null) {
            for (NewsBean newsBean : object) {
                newsBeanList.add(newsBean);
                LogUtils.e(newsBean.getAuthor());
            }
            mAdapter.setData(newsBeanList);
        } else {
        }
    }
});
mRecyclerView.setAdapter(mAdapter);
  1. 图片数量不同对应不同的布局
public class NewsBean extends BmobObject implements IMultiItem {

    @Override
    public int getLayoutRes() {
        if ("3".equals(tag)) {
            return R.layout.item_news_type3;
        } else if ("2".equals(tag)) {
            return R.layout.item_news_type2;
        } else {
            return R.layout.item_news_type1;
        }
    }
    // 省略其它...
}
  1. 新闻详情页面
    Fragment 中给 RecycleView 设置点击事件,传递网址到详情Activity
mAdapter.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(@NonNull View view, int position) {
        Intent intent = new Intent(getActivity(), NewsWebActivity.class);
        intent.putExtra("url", newsBeanList.get(position).getContent());
        startActivity(intent);
    }
});

网页详情页面 NewsActivity 中只有一个WebView。接收上个页面传递过来的参数,并且展示页面。这里做了一些初始化操作,大家在别处需要的话,也可以直接复制过去

String url = getIntent().getStringExtra("url");
if (TextUtils.isEmpty(url)) {
    Toast.makeText(this, "该新闻已经失效!", Toast.LENGTH_SHORT).show();
    return;
}
MyWebViewClient myWebViewClient = new MyWebViewClient();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    wvNews.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
wvNews.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//设置js可以直接打开窗口,如window.open(),默认为false
wvNews.getSettings().setJavaScriptEnabled(true);//是否允许执行js,默认为false。设置true时,会提醒可能造成XSS漏洞
wvNews.getSettings().setSupportZoom(true);//是否可以缩放,默认true
wvNews.getSettings().setBuiltInZoomControls(true);//是否显示缩放按钮,默认false
wvNews.getSettings().setUseWideViewPort(true);//设置此属性,可任意比例缩放。大视图模式
wvNews.getSettings().setLoadWithOverviewMode(true);//和setUseWideViewPort(true)一起解决网页自适应问题
wvNews.getSettings().setAppCacheEnabled(true);//是否使用缓存
wvNews.getSettings().setDomStorageEnabled(true);//DOM Storage
wvNews.setWebChromeClient(new WebChromeClient());
wvNews.setWebViewClient(myWebViewClient);
wvNews.loadUrl(url);

// ....
private class MyWebViewClient extends WebViewClient {
    //重写父类方法,让新打开的网页在当前的WebView中显示
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
}

至此,新闻模块页面基本完成。还有就是本文挺长的,很感谢你可以看到这里。

如果本文对你有所帮助,还望可以随手赏一个点赞哈 ~ ~

发布了70 篇原创文章 · 获赞 176 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zheng_weichao/article/details/104227390