Android期末项目(超详细附下载链接)

xxkfz
• 阅读 1831

【第一部分】历史文章: 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测试的接口数据 Android期末项目(超详细附下载链接) (二)头条热榜接口数据分析:

三、用到的数据存储

  • 登录、注册:使用的是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属性改下即可。 Android期末项目(超详细附下载链接)

五、西瓜视频设计(展示视频列表)

部分关键代码: Android期末项目(超详细附下载链接) Android期末项目(超详细附下载链接)

六、系统设置设计

  • 我的消息 :(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不仅是对前沿开发技术的了解,也是对编程知识的一次提升。

十、项目效果

Android期末项目(超详细附下载链接)

若文章中有错误的地方欢迎大家反馈或者留言,十分感谢!!! 源码获取:关注下方微信公众号即可获取。


个人博客:https://blog.csdn.net/weixin_43759352 微信公众号:【小小开发者】

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这