這個項目是很早之前在學校做的,如今再回首。很多代碼很是粗糙,邏輯也不盡完善。還望各位看官海涵。
前言
通過上一篇文章的功能設計,我們可以發現新聞通知公告等是APP的最主要功能點。主要是聚合展示學校官網的通知公告,官方微信,微博的重要信息,學校社團的活動,以及學校優秀自媒體的文章等等。
系列文章:
- 手把手帶你擼一個校園APP(一):項目簡介
- 手把手帶你擼一個校園APP(二):應用啓動和歡迎頁面
- 手把手帶你擼一個校園APP(三):用戶模塊(登錄註冊等)
- 手把手帶你擼一個校園APP(四):APP框架及功能設計
- 手把手帶你擼一個校園APP(五):新聞中心模塊
- 手把手帶你擼一個校園APP(六):失物招領&二手交易模塊
- 手把手帶你擼一個校園APP(七):圖說校園模塊
- 手把手帶你擼一個校園APP(八):校園通訊錄模塊
- 手把手帶你擼一個校園APP(九):課程表模塊(模擬登陸爬取教務處課程信息)
- 手把手帶你擼一個校園APP(十):APP通用模塊(更新,意見反饋等)
實現效果
新聞部分主要是分了“通知公告”,“新聞速遞”,“自媒體”,“校園文化”四個欄目,之間可以通過左右滑動進行切換。效果圖如下:
分析
其實這是挺常見的一個新聞資訊模塊。我們也可以輕易得出以下內容:
- 新聞條目 一般都有標題,配圖,作者,發表時間等組成。我們的新聞只是聚合展示使用,可以外加一個資訊鏈接;
- 配圖數量並不一致,有無圖的,1 張配圖的,以及 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改爲時間類型,圖片改爲列表等。本文暫且不表。
安卓
邏輯流程講解
本模塊邏輯設計如下:
- 使用CoordinatorTabLayout + ViewPager + Fragment 完成新聞模塊主頁面的顯示;
- Fragment 進行網絡請求,獲取新聞數據並展示,使用 RecyclerView 展示新聞列表,根據縮略圖數量對應3種條目佈局;
- 新聞詳情頁面使用WebView 用於展示新聞詳情。
代碼實現
在這裏爲了能快速開發,我們使用了 CoordinatorTabLayout 。
文章:CoordinatorTabLayout組件庫
Github地址:CoordinatorTabLayout
作者:hugeterry
使用 CoordinatorTabLayout 搭建新聞主頁面
使用步驟如下:
- 在 app 的 build.gradle 中添加依賴
dependencies {
implementation 'cn.hugeterry.coordinatortablayout:coordinatortablayout:1.2.2'
}
- 佈局文件中使用
<?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>
- 在 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);
網絡請求,數據填充
- 建立數據庫對應表 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 方法
}
- 網絡請求數據,並填充
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);
- 圖片數量不同對應不同的佈局
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;
}
}
// 省略其它...
}
- 新聞詳情頁面
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;
}
}
至此,新聞模塊頁面基本完成。還有就是本文挺長的,很感謝你可以看到這裏。
如果本文對你有所幫助,還望可以隨手賞一個點贊哈 ~ ~