本文目的:由于第一次学习较为完整的项目,故作记录以系统地整理APP开发知识

先看看整个项目结构:

  • activity, fragment, 不用说了。可以看做MVC中的controller
  • db, 存储json缓存用的,model就是一些bean类比如首页Item的对象,点开详情的文章对象
  • util嘛一些工具类。里面可以对已有的HTTP工具再次进行封装。
  • view就是一些自定义的或者第三方view类。
  • Kpplication就是自己写的application类,里面进行了第三方工具的初始化,其他没什么。
manifest也很简单。就是网络请求、网络状态、和写外部存储的权限(有了写,默认就可以读)。
我们从splashActivity开始看起:
  1. 先用FULLSCREEEN和HIDE_NAVIGATION两个给decorView设置上
  2. 初始化启动图imageview,getFileDir获得splash.jpg, 文件不存在则用默认图,存在则用BitmapFactory.decodeFile(splashFile.getAbsolutePath() )解析该文件
  3. 不管splash存不存在,我们都要进行get请求,获得最新的启动图的url,拿着这个url我们再次进行请求,并把该图片保存成文件。
  4. 此时我们主线程在播放启动图的动画:
  • 在anim文件夹下写scale动画,或者直接在代码new一个ScaleAnimation对象

    • fillAfter: true表示动画结束后图像persist;fromXScale和toXScale表示从多少倍放大到多少倍。pivotX="0.5"表示从X轴的中心开始效果
    • 设置Duration为3000毫秒,然后加上setAnimationListener,onAnimationEnd中写上动画结束后的操作。
  • 动画完成进入MainActivity, 通过overridePendingTransition更改进入activity的动画。调用finish()干掉启动页。
然后我们到了MainActivity:
  1. 首先看看布局,这里用的是Drawerlayout, 主布局放在上面,menu布局放在下面(menu这里用的fragment,我们应该替换成design库的navigationView)
  2. 看看onCreate代码。首先当然是初始化View了,这里根据是否是夜间模式,toolbar和statusBar的颜色进行了初始化。
  3. 主布局由toolbar和SwipeRefreshLayout组成,所以要对swipeRefreshLayout进行初始化,这里设置了颜色,和onRefreshListener
  4. 此处onRefresh中简单地new了一个MainFragment,目测可以优化。刷新结束需要调用setRefreshing(false),这个方法会移除刷新的圆环。
  5. 然后配置了ActionBarDrawerToggle,吧drawerlayout和toolbar关联起来。mDrawerlayout.setDrawerListener(drawerToggle).
  6. 最后就是用mainFragment来replace主布局啦。记得加上tag哦

  7. 着往下看,我们会看到MainActivity包含很多跟UI有关的操作,比如关闭drawer,
    设置SwpieRfreshEnable,toolbar的setTitle,但是mainActivity实际上没调用过。这些方法写成public,
    然后我们在mainFragment中获得mActivity对象,就可以方便的调用。mActivity在baseFragment中获得就行了。

  8. 有一个onOptionsItemSelected(MenuItem
    item)就是来监听menu的点击事件啦。这里主要是一个夜间模式,通过改变toolbar的backgroundColor和
    setStatusBarClor,通过findFragmentByTag或者Id找到主fragment和内容fragment,调用其
    updateTheme方法(fragment中解释),然后记得把夜间模式保存到sharedPreference就行了。
  9. 最后理所当然的复写了onBackPressed方法实现按两次退出的效果。记得先关闭drawer;用到snackbar, 记得根据夜间模式可以来setBackgroundColor
接下来就是比较重要的MainFragment:
  1. 布局嘛不用说就是一个listView或者recyclerView。后者通过判断itemType可以加载不同的布局达到header或者footer的效果
  2. 这里header是一个图片循播的控件。里面包含TopEntities(放在顶部的一些文章对象),点击事件就跟其他的Item一样了,都是用intent传递id和title来打开详情页。
  3. 然后就是list的初始化,用setOnScrollListener控制滑动到最后几项时来加载更多(第一次加载是加载今天的,加载更多中拿到日期来查询历史文章就行)
  4. item点击事件和header中一样的,传递一个带有id和title的entity过去,打开详情页的activity。

  5. 后看看数据加载:-如果有网络:请求news/latest的文章数据,获取数据后通过SQLiteOpenHelper来
    getWritableDatabase.执行SQL语句保存json数据。缓存json数据后,就要解析了。我们根据不同的json数据创建对应的对
    象。这里是Latest文章对象类(用GsonFormat工具很方便)。new一个Gson,
    把response的String和Latest.class传入,于是我们就方便地获得了一个Latest对象,
    对象里面有对应的方法获得一个ArticleEntities的数组,把他加到list的adapter中,通知一下(添加和通知的方法可以封装)就OK
    了。
  6. -如果没有网络:获得SQLiteOpenHelper以getReadableDatabase,对
    SQLiteDatabase进行rawQuery,返回cursor,用cursor来找到json数据。。具体流程不太清楚。准备用第三方的ORM数
    据库greenDao。
  7. 再看看加载更多方法:加载更多是写在list的onScroll中的。判断滚动到最后倒数第二个就可以执行了。拿着json中的date,对news/before这个API进行请求即可。解析的时候传入的是Before.class,也就是历史文章对象,其他一样。
  8. 最后是updateTheme也就是夜间模式方法。调用的是list的adapter中的同名方法。这个方法只是重新获取了isDarkMode这个值,然后notifyDataSetChanged(这么简单就行了?有连锁反应?)
看看MainFragment中list的Adapter: 
  1. 首先这是继承自baseAdapter的,构造方法就一个context(数据通过自己写的addList方法传入文章对象的List)
  2. 然后看看updateTheme:先获得了isDarkMode值,然后notifyDataSetChanged(..这句话我是不是说过?)
详情页的Activity:
  1. 详情页是通过webView显示的。根布局是CoordinatorLayout,我称之为协调布局。然后依次是AppBarLayout包裹着
    CollapsingToolbarLayout, 正如名字一样,CollapsingToolbarLayout中,应有一个Toolbar,
    而imageview放在toolbar上面(固定格式);AppBarLayout下面是content布局(可以用include方法包含进去),它
    是一个NestedScrollView,看名字,应该是一个带有滑动事件的Scrollview,有一个属性叫layout_behavior,

    值是系统自带的固定的string。NestedScrollView中就是一个webview,用来显示主要的文章内容。考你一道题,如果想加入
    FloatingActionButton,布局应该放在哪?答案是放在AppBarLayout下方,用
    app:layout_anchor="@id/app_bar"和app:layout_anchorGravity="bottom|end"来控制
    其位置。

  2. 首先是喜闻乐见的初始化,从intent中获得文章entity对象(里面包含title和id),然后是toolbar,这
    里是第二级activity,所以要setDisplayHomeAsUpEnabled(不觉得这个方法名太长了吗?),然后
    setNavigationOnClickListener,里面就是onBackPressed.
    然后就是标题栏了。这里要用CollapsingToolbarLayout来设置title。还有个setContentScrimColor和
    setStatusBarScrimColor(Scrim是沙罩的意思)。
  3. 然后就是webview的设置了,先
    getSettings获得webSettings对象,setJavaScriptEnabled不解释了,别随便
    开;setCachemode(WebSettings.LOAD_CACHE_ELSE_NETWOR),
    有cache就加载,没有就network;setDomStorageEnabled、setDatabaseEnabled、
    setAppCacheEnabled统统开启,虽然不知道有什么效果。
  4. 初始化完成就如果有网可以进行网络访问了,拿到文章对象entity的id,直接访问news/,获得数据后,以id为key,response作为value。保存在数据库。没有网的话老规矩,以id来查询json数据,并进行解析。
  5. 解析:还是先根据json数据写好文章Content对象,new个Gson,用fromJson方法传入json数据和Content.class, 然后你就获得Content对象啦
  6. 首先用图片加载器把图片加载了,url直接从content对象中get就行了;然后是webview的加载:就是HTML的字符串头部加上css的样式,这里样式是固定的,所以放到了assets文件中:
    String html = "<html><head>" + css + "</head><body>" + content.getBody() + "</body></html>";
    html = html.replace("<div class=\"img-place-holder\">", "");
    mWebView.loadDataWithBaseURL("x-data://base", html, "text/html", "UTF-8", null);

学习笔记-Kuaihu(仿知乎日报)的更多相关文章

  1. 微信小程序开发日记——高仿知乎日报(下)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...

  2. 微信小程序开发日记——高仿知乎日报(中)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该教 ...

  3. 微信小程序开发日记——高仿知乎日报(上)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...

  4. 仿知乎日报App

    1.6.Error:Execution failed for task ':app:buildInfoDebugLoader'.> Exception while doing past iter ...

  5. 学习react,动手实现一个小demo(仿知乎问答)

    学习react也有一周的时间,最近自己做了个仿知乎问答的小demo,项目源码在github上:https://github.com/yang302/reactQa 使用技术:bower+gulp+re ...

  6. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  7. ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测

    一.开篇 在博客注册了三年,今天才决定写第一篇博客,警告自己不要懒!!! 二.关于ArcGIS JS 版本选择 在写这篇博客时ArcGIS JS 4.0正式版已经发布.它和3.x版本的不同是,Map不 ...

  8. 微信小程序之知乎日报

    上一次的<微信小程序之小豆瓣图书>制作了一个图书的查询功能,只是简单地应用到了网络请求,其他大多数小程序应有的知识.而本次的示例是知乎日报,功能点比较多,页面也比上次复杂了许多.在我编写这 ...

  9. 扩展中国剩余定理 exCRT 学习笔记

    前言 由于 \(\{\mathrm{CRT}\}\subseteq\{\mathrm{exCRT}\}\),而且 CRT 又太抽象了,所以直接学 exCRT 了. 摘自 huyufeifei 博客 这 ...

随机推荐

  1. IIS mime类型

    参考网站:http://www.iwms.net/n1381c2.aspx 以下例子为iis6.0 下载安卓.苹果安装包时候,需要添加mime类型才可以下载,否则访问不到 安卓 .apk  appli ...

  2. Http请求中POST与GET的区别——前端面试

    一.原理区别 Http定义了与服务器交互的方法,其中最基本的四种是:GET,POST,PUT,DELETE,正对应着对资源的查,改,增,删.URL的全称是资源描述符,我们可以这样认为,一个URL地址, ...

  3. R语言利器之ddply和aggregate

    ddply和aggregate是两个用来整合数据的功能强大的函数. aggregate(x, ...) 关于aggregate()函数的使用在<R语言实战>中P105有简单描述,这里重新说 ...

  4. C语言 数组做函数参数退化为指针的技术推演

    //数组做函数参数退化为指针的技术推演 #include<stdio.h> #include<stdlib.h> #include<string.h> //一维数组 ...

  5. 深入了解view以及自定义控件

    参考文章: http://blog.csdn.net/guolin_blog/article/details/12921889 Android LayoutInflater原理分析,带你一步步深入了解 ...

  6. 2016温碧霞爱情《爱在深秋》HD720P.国语中字

    导演: 林家威编剧: 林家威 / 李非 / 黄国兆主演: 温碧霞 / 谭耀文 / 赵炳锐 / 方皓玟 / 王建成类型: 爱情制片国家/地区: 香港语言: 汉语普通话上映日期: 2016-01-22(中 ...

  7. opencv3中的机器学习算法之:EM算法

    不同于其它的机器学习模型,EM算法是一种非监督的学习算法,它的输入数据事先不需要进行标注.相反,该算法从给定的样本集中,能计算出高斯混和参数的最大似然估计.也能得到每个样本对应的标注值,类似于kmea ...

  8. swift第一季基础语法

    同: 一.基础 同: 1常量和变量 2数据类型和数据类型转换 3别名 不同: 1可选类型optional 2BOOL类型 3元组类型 4断言Assertion 二.基本操作符 同: 1赋值和算术运算及 ...

  9. iOS程序中调用系统自带应用(短信,邮件,浏览器,地图,appstore,拨打电话,iTunes,iBooks )

    在网上找到了下在记录下来以后方便用 在程序中调用系统自带的应用,比如我进入程序的时候,希望直接调用safar来打开一个网页,下面是一个简单的使用:

  10. Jquery each() 如何操作动态添加的DOM元素

    JQ each页面上的DOM元素的时候,如果有一部分的DOM是ajax异步加载的,那么each可能遍历不到元素,异步请求数据的同时不会影响后面的代码执行,今天就遇到这个问题了, 解决方案是讲ajax改 ...