Android期末項目

【第一部分】歷史文章:
Android學習筆記(一)——創建第一個Android項目
Android學習筆記(二)android studio基本控件及佈局(實現圖片查看器)
Android學習筆記(三)android studio中CheckBox自定義樣式(更換複選框左側的勾選圖像)
Android學習筆記(四)Android 中Activity頁面的跳轉及傳值
Android學習筆記(五)——Toast提示、Dialog對話框、Menu菜單
Android學習筆記(六)——自定義ListView佈局+AsyncTask異步任務
Android學習筆記(七)——數據存儲(共享參數SharedPreferences)
Android學習筆記(八)——數據存儲(SD卡文件操作)
Android學習筆記(九)——網絡技術
Android學習筆記(十)——實現新聞列表案例
Android學習筆記(十一)——一些高級控件的使用
Android學習筆記(十二)——數據存儲(SQLite數據庫)
Android學習筆記(十三)——數據存儲(LitePal操作數據庫)
Android學習筆記(十四)——內容提供器
Android學習筆記(十五)——側滑容器(ViewPager)
【第二部分】主要問題解決:
Android Studio(存)讀取不了SD卡上的文件——【已解決】
【第三部分】期末項目:
Android期末項目(一)—— 解析二維數組對象
Android期末項目(二)——歡迎界面(實現倒計時+點擊跳轉+判斷是否登錄)


Android期末大作業——今日頭條

一、主要的功能介紹

模塊 主要功能 相關描述
登錄、註冊頁面 LitePal操作數據庫 數據的插入、查詢操作;數據校驗
引導首頁 封面展示+倒計時進入 定時器
首頁導航 共四個板塊—主頁、西瓜視頻、系統設置、我的 對應四個碎片
主頁 共五個板塊—推薦、國內、體育、社會、軍事 對應五個碎片分別顯示不同類別的新聞
西瓜視頻 播放視頻
系統設置 我的消息、清理緩存、頭條封面、頭條熱榜等 通知、訪問網絡接口、數據解析
我的 掃一掃、上傳頭像、賬號管理、我的收藏、個人資料、登錄等操作 更改密碼、收藏新聞展示、個人資料的設置
發佈按鈕 進行拍照 使用多媒體
上傳頭像 選擇相冊
底部彈出框 個人資料中使用 有相應的字數限制,城市選擇三級聯動等
權限設置 用戶未登錄的狀態 查看相關新聞、頭像框顯示未登錄、賬號管理、我的收藏、個人資料,只有登錄後纔可訪問、用戶不可評論與收藏
驗證碼 註冊的時候 進行判斷用戶輸入的驗證碼是否與生成的一致
用戶登錄成功後 可以進行一系列的操作 更改個人資料,收藏新聞、評論、查看收藏、評論等

二、準備工作

用到的接口:頭條新聞數據、頭條熱榜。

http://v.juhe.cn/toutiao/index?type=top&key=

https://api.storeapi.net/api/68/177?format=json&weibo_top=1594&appid=2307&sign=

注:接口可以到聚合數據去申請。

(一)頭條新聞接口數據分析:

  • uniquekey :唯一標識
  • title :新聞標題
  • date :時間
  • category :新聞類別
  • author_name :新聞名稱
  • url :新聞具體內容url
  • thumbnail_pic_s :新聞圖片url

注:type取值(正好頭部可以顯示不同類別的新聞!!!)

top   yule   tiyu   caijing    guoji   guonei    junshi   keji    shehui  shishang

注:下面是使用Postman測試的接口數據
在這裏插入圖片描述
(二)頭條熱榜接口數據分析:

三、用到的數據存儲

  • 登錄、註冊:使用的是LitePal
  • 收藏新聞:使用的是SQLite
  • 記住密碼:sharepreference
  • 保存用戶信息:sharepreference(用戶顯示用戶名、權限的判斷)
  • 保存個人資料信息:使用的是LitePal
  • 新聞評論:使用的是LitePal

(1)登錄、註冊操作。

  • 註冊:填入用戶名、密碼、確認密碼、驗證碼,進行註冊。
  • 登錄:判斷用戶名是否已經註冊、沒有註冊的話,寫入數據庫。

(2)收藏新聞。

  • 用戶點擊新聞展示頁面中的收藏按鈕,進行新聞的收藏。
  • 進行插入數據庫(新聞標題、新聞具體url、時間、新聞來源、圖片的url)。

(3)保存個人資料信息。

  • 插入數據庫信息(用戶名、暱稱、介紹、性別、地區等)

四、主頁設計(展示新聞列表)

4.1、使用的主要控件:

  • FrameLayout (碎片,各類新聞的切換)
  • ImageView (底部導航的圖片)
  • TextView(底部的導航標題)

發生的事情:顯示新聞列表——>點每一個新聞列表中的刪除圖標——>對話框彈出(問你:確定刪除嗎?)——>確定的話(該條新聞從數據源中移出)——>點擊每一條新聞——>跳到新聞詳情頁面——>在新聞詳情頁面對新聞進行收藏操作(涉及到頁面之間的傳值,存數據庫操作)——>爲後面的查看收藏做好準備!!!

4.2、推薦碎片:推薦類新聞的實現fragment_tuijian.xml

1、在fragment_tuijian.xml中添加ListView。

2、列表項使用的主要控件。(共6個)

  • TextView :顯示新聞標題、新聞的來源、新聞的時間。
  • ImageView:顯示新聞的圖片、刪除圖標圖片。
  • View :列表項與列表項之間的水平橫線。
水平橫線的設計:
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#DCDCDC" />

3、具體實現,參考老師上課的那個(第六課)——其實沒有什麼區別!!!

4.3、以上用到的知識點

  • 佈局的設計
  • ListView列表的應用(三要素:數據源、控件、數據適配器)
  • json數據解析(用的是上課時講的那種方式)
  • 活動之間的跳轉及傳值
  • OkHttp訪問網絡
  • AsyncTask異步任務
  • FrameLayout的使用(參考老師的那個:這是財經新聞。。。的那個案例!!!)
  • WebView展示新聞詳情頁面
    等等吧!!!

4.4、點擊新聞跳轉到新聞詳情頁面

  • 點擊新聞列表中的每一項後,進行跳轉頁面;把新聞的標題、新聞具體內容url、時間、新聞來源、圖片url等數據傳遞。
  • 在新聞詳情頁面,進行獲取到以上傳過去的值,用WebView顯示新聞的具體內容。
  • 在新聞詳情頁面中,添加收藏按鈕。

4.5、新聞詳情頁面點擊收藏圖標(用戶登錄後)

  • 當點擊收藏按鈕時,插入數據庫,這裏用的時SQLite的方式。
  • 插入數據庫的目的,用戶在我的板塊可以查看所收藏的新聞。

4.6、新聞的評論(用戶登錄後)

在新聞詳情頁中,輸入評論內容,點擊發送按鈕,即可評論。

4.7、點擊右上角的發佈按鈕

  • 點擊後,從底部彈出頁面欄,點擊拍小視頻,可以打開相機。

4.8、其他

對於不同的類別的新聞展示,其實具體代碼與推薦類的新聞代碼一樣,只需要把新聞接口的type屬性改下即可。
在這裏插入圖片描述

五、西瓜視頻設計(展示視頻列表)

部分關鍵代碼:
在這裏插入圖片描述
在這裏插入圖片描述

六、系統設置設計

  • 我的消息 :(Notification通知相關的使用)
  • 清理緩存
  • 夜間模式
  • H5廣告過濾
  • 頭條封面 (跳到引導頁面)
  • 廣告設置 :
  • 頭條熱榜 :訪問網絡接口進行展示
  • 我的發現

6.1、清理緩存
點擊清理緩存按鈕:

im_qinglihuancun.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try{
                    String size = ClearCache.getTotalCacheSize(getContext());
                    ClearCache.clearAllCache(getContext());
                    Toast.makeText(getContext(), size + "緩存清除完成", Toast.LENGTH_SHORT).show();

                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });

ClearCache.java

package cn.edu.hznu.com.utils;
import android.content.Context;
import android.os.Environment;
import java.io.File;
import java.math.BigDecimal;
public class ClearCache {
    /**
     * 獲取緩存大小
     * @param context
     * @return
     * @throws Exception
     */
    public static String getTotalCacheSize(Context context) throws Exception {
        long cacheSize = getFolderSize(context.getCacheDir());
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            cacheSize += getFolderSize(context.getExternalCacheDir());
        }
        return getFormatSize(cacheSize);
    }

    /***
     * 清理所有緩存
     * @param context
     */
    public static void clearAllCache(Context context) {
        deleteDir(context.getCacheDir());
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            deleteDir(context.getExternalCacheDir());
        }
    }

    private static boolean deleteDir(File dir) {
        if (dir != null && dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }

    // 獲取文件
    //Context.getExternalFilesDir() --> SDCard/Android/data/你的應用的包名/files/ 目錄,一般放一些長時間保存的數據
    //Context.getExternalCacheDir() --> SDCard/Android/data/你的應用包名/cache/目錄,一般存放臨時緩存數據
    public static long getFolderSize(File file) throws Exception {
        long size = 0;
        try {
            File[] fileList = file.listFiles();
            for (int i = 0; i < fileList.length; i++) {
                // 如果下面還有文件
                if (fileList[i].isDirectory()) {
                    size = size + getFolderSize(fileList[i]);
                } else {
                    size = size + fileList[i].length();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }

    /**
     * 格式化單位
     *
     * @param size
     * @return
     */
    public static String getFormatSize(double size) {
        double kiloByte = size / 1024;
        if (kiloByte < 1) {
//            return size + "Byte";
            return "0K";
        }

        double megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + "KB";
        }

        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + "MB";
        }

        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
                + "TB";
    }

}

七、我的設計

  • 頭像上傳
  • 掃一掃
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI"));
intent.putExtra("LauncherUI.From.Scaner.Shortcut", true);
intent.setFlags(335544320);
intent.setAction("android.intent.action.VIEW");
getContext().startActivity(intent);
  • 賬號管理
    進行密碼更改的操作
  • 我的收藏
    展示收藏的新聞數據
  SQLiteDatabase db = myDatabaseHelper.getReadableDatabase();
                    Cursor cursor = db.rawQuery("select * from coll_news_table", null);
                    if (cursor.getCount() != 0) {
                        if (cursor.moveToFirst()) {
                            do {
                                String title = cursor.getString(cursor.getColumnIndex("title"));
                                String date = cursor.getString(cursor.getColumnIndex("date"));
                                String author = cursor.getString(cursor.getColumnIndex("author"));
                                String imgurl = cursor.getString(cursor.getColumnIndex("imgurl"));
                                String url = cursor.getString(cursor.getColumnIndex("url"));
                                News news = new News(imgurl, title, url, date, author);
                                list.add(news);
                            } while (cursor.moveToNext());
  • 個人資料
    用戶名、暱稱、介紹、性別、地區。
    在介紹添加了 輸入字數的限制功能(20字以內):
 ed_jieshao.addTextChangedListener(new TextWatcher() {
            private CharSequence wordNum;//記錄輸入的字數
            private int selectionStart;
            private int selectionEnd;
            private int num=20;
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                wordNum= s;//實時記錄輸入的字數
            }
            @Override
            public void afterTextChanged(Editable s) {
                int number = num - s.length();
                //TextView顯示剩餘字數
                ed_zishu.setText("剩餘" + number+"字");
                selectionStart=ed_jieshao.getSelectionStart();
                selectionEnd = ed_jieshao.getSelectionEnd();
                if (wordNum.length() > num) {
                    //刪除多餘輸入的字(不會顯示出來)
                    s.delete(selectionStart - 1, selectionEnd);
                    int tempSelection = selectionEnd;
                    ed_jieshao.setText(s);
                    ed_jieshao.setSelection(tempSelection);//設置光標在最後
                }
            }
        });
  • 版本升級
  AlertDialog.Builder builder=new AlertDialog.Builder(getContext()); //創建一個AlertDialog的構造器
                    builder.setIcon(R.drawable.tanhao);   //設置圖標
                    builder.setTitle("溫馨提示");  //設置標題
                    builder.setMessage("當前已是最新版本");  //設置消息內容
                    builder.create().show();
  • 退出登錄

八、遇到的問題

在使用前面第二個數據接口的時候,數據解析一直報錯,出現空指針異常。得不到數據。

通過詢問老師:最終得到了解決方案😀,數據成功顯示。

Android期末項目(一)—— 解析二維數組對象

九、總結

通過本學期的Android課程的學習,基本掌握了Android應用程序的開發的一般流程,對常用的控件基本掌握及用法,對其事件的監聽方法也基本掌握。學習Android不僅是對前沿開發技術的瞭解,也是對編程知識的一次提升。

十、項目效果

在這裏插入圖片描述

若文章中有錯誤的地方歡迎大家反饋或者留言,十分感謝!!!

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