手把手帶你擼一個校園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;
    }
}

至此,新聞模塊頁面基本完成。還有就是本文挺長的,很感謝你可以看到這裏。

如果本文對你有所幫助,還望可以隨手賞一個點贊哈 ~ ~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章