day01--思路

LoadingPager抽取

学习笔记

如有错误之处请大家帮忙指出纠正__谢谢

-------------------------------------------------------------------------------------------------------------------------------------------

MainActivity中:

1 界面控件 : 顶部 指针 [ 引入指针控件 ],   底部ViewPager

现在设置FragmentPagerAdapter为ViewPager的数据适配器, viewPager中添加的View对象是由getItem( )方法中返回的Fragment中

onCreatView 方法里面的view对象

2   viewPager数据适配器继承自FragmentPagerAdapter

getItem(int position) 返回指针绑定的Fragment对象,我们需要onCreatView方法中返回的view

使用FragmentFactory 生产工厂,根据id生产对应的Fragment对象 (内存中有当前对象,复用之前的Fragment对象,内存中没有才创建)

FragmentFactory 生产工厂 : -->将对象存储到Map集合中 , 在创建对象之前,先从集合中取对象,如果没有才创建

getCount( ) 模块总个数

getPageTitle(int position)给应用设置标题

3     给指针设置数据适配器的时候,每一个fragment界面都有界面展示效果,所以将其进行抽取(BaseFragment),BaseFragment中去管理每一个

Fragment 的展示逻辑

在基类中管理每一个子界面的展示逻辑

4    viewPager设置完数据 适配器后, 将指针绑定到viewPager上 :  pagertab_main.setViewPager(viewpager_main);//绑定指示器

5    创建基类BaseActivity继承自ActionBar 以后每个子类都继承自BaseActivity

  应用中所有的activity界面都需要用到actionbar去管理头(Title),所以让所有activity父类继承至包含了ActionBar的Activity

获取FragmentManager管理者对象

如果对应的activity继承至ActionBarActivity,就一定要去再activity中配置Theme.AppCompat

  1. android:theme="@style/Theme.AppCompat.Light"> 去除黑色的显示背景

6   顶部指针关联底部界面搞定

----------------------------------------------------------------------

7   ,每一个Fragment中都会有以下的四种展示情况,将以下的四套逻辑抽取到BaseFragment中去做管理

(1)成功展示数据的界面效果

(2)获取数据为空

(3)请求网络失败

(4)正在加载

(1),成功展示数据的界面效果 因为每一个Fragment中对应的成功的界面展示效果都不一致,所以对应View对象LoadingPage不能通过xml写死

(2),获取数据为空 ,每一个Fragment中,没有数据时候的展示效果都一致,数据为空的xml可以写死,构建一个数据为空xml布局结构 layout_empty

(3),请求网络失败 ,每一个Fragment中,获取不到数据时候的展示效果都一致,获取数据错误的xml可以写死,构建一个数据错误xml布局结构

layout_error

(4),正在加载,每一个Fragment中,加载数据时候的展示效果都一致,请求网络过程可以将其xml写死,构建一个正在加载xml布局结构 layout_loading

8    如果将这四套逻辑都写到BaseFragment中这个类的体系就显得太臃肿了 , 因此我们将其封装到单独的一个类LoadingPager中去做管理

9     LoadingPager继承自ViewGroup子类 , 因为需要往LoadingPager添加xml布局转化的view对象, 在这里我们就直接继承FrameLayout帧布局了 --> 这个类就等同于自定义控件了 , 就是自定义控件 , 复习三个构造

-------------------------------------------------

-------------

10   LoadingPager类 :

[1]      每种展示状态对应的其实就是一种View对象

(1)成功展示数据的界面效果

(2)获取数据为空

(3)请求网络失败

(4)正在加载

根据状态去决定,LoadingPage中展示那个界面

1,未加载

2,正在加载

3,加载为空

4,加载失败

5,加载成功

通过变量维护当前状态

  1.  1 //根据状态去决定,LoadingPage中展示那个界面
     2 privateint STATE_UNLOAD =0;
     3 privateint STATE_LOADING =1;
     4 privateint STATE_LOAD_EMPTY =2;
     5 privateint STATE_LOAD_ERROR =3;
     6 privateint STATE_LOAD_SUCCESSED =4;
     7 //通过一个变量维护当前状态
     8 privateint current_state = STATE_UNLOAD;
     9 //创建以上4个展示效果的view对象
    10 privateView successedView;
    11 privateView emptyView;
    12 privateView errorView;
    13 privateView loadingView;

[2] 构造中调用initLoadingPage()方法

添加三个已经确定的布局

根据当前状态决定,那个界面显示,那个隐藏 showSafePage();

[3]   showSafePage(){ 作用: 切换到主线程 展示布局 showPage();  };

[4]   showPager( ) 根据当前状态展示界面布局

  1.     

    1 if(loadingView!=null){
    2        loadingView.setVisibility((current_state == STATE_LOADING || current_state == STATE_UNLOAD)?
    3        View.VISIBLE:View.GONE);
    4 }

现在处理请求成功界面: 也是在showPager( )中 ,成功展示的界面需要定义成抽象方法,让自类去实现

在BaseFragment中实现此抽象方法

public abstract View onCreateViewSuccessed() ;

  1.   

     1   //如果成功展示界面的view对象为空
     2   if(successedView == null && current_state == STATE_LOAD_SUCCESSED){
     3         //LoadingPage中不需要去管onCreateViewSuccessed具体实现,要做的就是讲这个成功展示的界面添加到LoadingPage中,然后展示
     4         successedView = onCreateViewSuccessed();
     5         if(successedView!=null){
     6               addView(successedView,layoutParams);
     7          }
     8    }
     9
    10    if(successedView!=null){
    11          successedView.setVisibility(current_state == STATE_LOAD_SUCCESSED?View.VISIBLE:View.GONE);
    12    }

BaseFragment也不知道成功界面显示什么样的,因此继续定义抽象方法,让所有的子类实现展示成功的抽象方法

LoadingPager抽取过程 [ onCreatViewSuccessed抽取 ]

11   获取网络请求结果决定页面显示状态

我们到底显示那个界面需要根据 子类 请求网络的结果( 请求成功 ; 请求失败 ; 请求为空 )而显示对应的界面

将请求网络操作的的结果在LoadingPager中获取

定义show方法中  开启子线程

        网络请求的状态已经封装在onLoad对象中 [ 该方法又是抽象,子类实现 ]

final ResultState onLoad = onLoad();  //子类实现该方法,只有返回结果了,

切换到主线程,将当前状态重新赋值为返回来的结果(现在当前状态已经发生变化,)

调用根据当前状态刷新界面的方法 , 显示界面

使用枚举指定要返回的结果类型

  1.    

     1 public enum ResultState{
     2         STATE_EMPTY(2),
     3         STATE_ERROR(3),
     4         STATE_SUCCESSED(4);
     5
     6         private int state;
     7         private ResultState(int state){
     8             this.state = state;
     9         }
    10
    11         public int getState() {
    12             return state;
    13         }
    14 }

每一个Fragment在请求网络过程中调用的方法,需要放置到子线程中

public abstract ResultState onLoad() ; --> 子类实现

   onLoad抽取过程

-----------------------------------------------------

12   子类分别实现这两个抽象方法

子类中,只有 onLoad() 返回值为枚举的success后 ,子类中的onCreateViewSuccessed()方法才会执行

---------------------------------------------------------------------------------------------------------------

LoadingPager代码

  1 /**
  2  * 根据当前状态来显示不同页面的自定义控件
  3  *
  4  * - 未加载 - 加载中 - 加载失败 - 数据为空 - 加载成功
  5  *
  6  * @author Kevin
  7  * @date 2015-10-27
  8  */
  9 public abstract class LoadingPage extends FrameLayout {
 10
 11     private static final int STATE_LOAD_UNDO = 1;// 未加载
 12     private static final int STATE_LOAD_LOADING = 2;// 正在加载
 13     private static final int STATE_LOAD_ERROR = 3;// 加载失败
 14     private static final int STATE_LOAD_EMPTY = 4;// 数据为空
 15     private static final int STATE_LOAD_SUCCESS = 5;// 加载成功
 16
 17     private int mCurrentState = STATE_LOAD_UNDO;// 当前状态
 18
 19     private View mLoadingPage;
 20     private View mErrorPage;
 21     private View mEmptyPage;
 22     private View mSuccessPage;
 23
 24     public LoadingPage(Context context, AttributeSet attrs, int defStyle) {
 25         super(context, attrs, defStyle);
 26         initView();
 27     }
 28
 29     public LoadingPage(Context context, AttributeSet attrs) {
 30         super(context, attrs);
 31         initView();
 32     }
 33
 34     public LoadingPage(Context context) {
 35         super(context);
 36         initView();
 37     }
 38
 39     private void initView() {
 40         // 初始化加载中的布局
 41         if (mLoadingPage == null) {
 42             mLoadingPage = UIUtils.inflate(R.layout.page_loading);
 43             addView(mLoadingPage);// 将加载中的布局添加给当前的帧布局
 44         }
 45
 46         // 初始化加载失败布局
 47         if (mErrorPage == null) {
 48             mErrorPage = UIUtils.inflate(R.layout.page_error);
 49             addView(mErrorPage);
 50         }
 51
 52         // 初始化数据为空布局
 53         if (mEmptyPage == null) {
 54             mEmptyPage = UIUtils.inflate(R.layout.page_empty);
 55             addView(mEmptyPage);
 56         }
 57
 58         showRightPage();
 59     }
 60
 61     // 根据当前状态,决定显示哪个布局
 62     private void showRightPage() {
 63         // if (mCurrentState == STATE_LOAD_UNDO
 64         // || mCurrentState == STATE_LOAD_LOADING) {
 65         // mLoadingPage.setVisibility(View.VISIBLE);
 66         // } else {
 67         // mLoadingPage.setVisibility(View.GONE);
 68         // }
 69         mLoadingPage
 70                 .setVisibility((mCurrentState == STATE_LOAD_UNDO || mCurrentState == STATE_LOAD_LOADING) ? View.VISIBLE
 71                         : View.GONE);
 72
 73         mErrorPage
 74                 .setVisibility(mCurrentState == STATE_LOAD_ERROR ? View.VISIBLE
 75                         : View.GONE);
 76
 77         mEmptyPage
 78                 .setVisibility(mCurrentState == STATE_LOAD_EMPTY ? View.VISIBLE
 79                         : View.GONE);
 80
 81         // 当成功布局为空,并且当前状态为成功,才初始化成功的布局
 82         if (mSuccessPage == null && mCurrentState == STATE_LOAD_SUCCESS) {
 83             mSuccessPage = onCreateSuccessView();
 84             if (mSuccessPage != null) {
 85                 addView(mSuccessPage);
 86             }
 87         }
 88
 89         if (mSuccessPage != null) {
 90             mSuccessPage
 91                     .setVisibility(mCurrentState == STATE_LOAD_SUCCESS ? View.VISIBLE
 92                             : View.GONE);
 93         }
 94     }
 95
 96     // 开始加载数据
 97     public void loadData() {
 98         if (mCurrentState != STATE_LOAD_LOADING) {// 如果当前没有加载, 就开始加载数据
 99
100             mCurrentState = STATE_LOAD_LOADING;
101
102             new Thread() {
103                 @Override
104                 public void run() {
105                     final ResultState resultState = onLoad();
106
107                     // 运行在主线程
108                     UIUtils.runOnUIThread(new Runnable() {
109
110                         @Override
111                         public void run() {
112                             if (resultState != null) {
113                                 mCurrentState = resultState.getState();// 网络加载结束后,更新网络状态
114                                 // 根据最新的状态来刷新页面
115                                 showRightPage();
116                             }
117                         }
118                     });
119                 }
120             }.start();
121         }
122     }
123
124     // 加载成功后显示的布局, 必须由调用者来实现
125     public abstract View onCreateSuccessView();
126
127     // 加载网络数据, 返回值表示请求网络结束后的状态
128     public abstract ResultState onLoad();
129
130     public enum ResultState {
131         STATE_SUCCESS(STATE_LOAD_SUCCESS), STATE_EMPTY(STATE_LOAD_EMPTY), STATE_ERROR(
132                 STATE_LOAD_ERROR);
133
134         private int state;
135
136         private ResultState(int state) {
137             this.state = state;
138         }
139
140         public int getState() {
141             return state;
142         }
143     }
144
145     public static class Person {
146
147         public static Person P1 = new Person(10);
148         public static Person P2 = new Person(12);
149         public static Person P3 = new Person(19);
150
151         public Person(int age) {
152
153         }
154     }
155
156     // public enum Person {
157     // P1,P2,P3;
158     // }
159
160 }

BaseFragment

 1 public abstract class BaseFragment extends Fragment {
 2
 3     private LoadingPage mLoadingPage;
 4
 5     @Override
 6     public View onCreateView(LayoutInflater inflater, ViewGroup container,
 7             Bundle savedInstanceState) {
 8         // 使用textview显示当前类的类名
 9         // TextView view = new TextView(UIUtils.getContext());
10         // view.setText(getClass().getSimpleName());
11         mLoadingPage = new LoadingPage(UIUtils.getContext()) {
12
13             @Override
14             public View onCreateSuccessView() {
15                 // 注意:此处一定要调用BaseFragment的onCreateSuccessView, 否则栈溢出
16                 return BaseFragment.this.onCreateSuccessView();
17             }
18
19             @Override
20             public ResultState onLoad() {
21                 return BaseFragment.this.onLoad();
22             }
23
24         };
25
26         return mLoadingPage;
27     }
28
29     // 加载成功的布局, 必须由子类来实现
30     public abstract View onCreateSuccessView();
31
32     // 加载网络数据, 必须由子类来实现
33     public abstract ResultState onLoad();
34
35     // 开始加载数据
36     public void loadData() {
37         if (mLoadingPage != null) {
38             mLoadingPage.loadData();
39         }
40     }
41 }

子类Fragment_用于展示当前页面

 1 public class AppFragment extends BaseFragment {
 2
 3     //只有成功才走此方法
 4     @Override
 5     public View onCreateSuccessView() {
 6         return null;
 7     }
 8
 9     @Override
10     public ResultState onLoad() {
11         return ResultState.STATE_ERROR;
12     }
13
14 }

来自为知笔记(Wiz)

时间: 2024-10-12 13:13:58

day01--思路的相关文章

linux开机获取不到IP排查思路

最近发现linux主机重启老是获取不到IP,每次都要手动dhclient eth0一下,很麻烦. 想了下,可能有问题 于是乎,就有这个排查思路: 1.查看开机时是否将网卡连接上来: 2.在虚拟机内使用命令查看,是否开机启动network服务,主要看3,5两个级别,最好开启: 3. 另外还需要看下网卡配置文件,是否配置正确,主要看 ONBOOT:开机启动网卡.这一项要是yes BOOTPROTO:网络分配方式,静态,这里需要小写,例如dhcp(dhcp自动获取),static(以静态IP方式存在)

《好好说话》:常见沟通场景的应对误区与应答思路、应答句式。4星。

全书针对谈话的常见场景,分析双方的本质问题和应答方的常见应对误区.应该的应答思路与句式.对沟通双方的思路的分析比较有功力. 感觉是从大专辩论赛的角度来组织全书的结构的.我更同意马东在序言中的说法,这本书更应该叫<好好思考>.不过如果从“好好思考”的角度来写书,全书的结构和重点要做一些变化. 书中把语言沟通的五种常见场景(沟通.说服.谈判.演讲.辩论)称作五个维度,还画了一个五边形,我认为这是全书最大的败笔,这里说“五种场景”比“五个维度”跟合适,用表格比用五边形更合适. 个人感觉:在大部分的场

Nginx+PHP (Fastcgi)常见502和504解决思路分享

公司一台测试服务器,最近出现504和502问题:(环境LNMP,php编译安装,Fastcgi模式),问题不难解决,但这里分享一下自己的排查思路和处理问题的方式. 504 Gateway Time-out,nginx 502 bad gateway 一.分析问题: Nginx 504 Gateway Time-out的含义是没有请求到可以执行的PHP-CGI. Nginx 502 Bad Gateway的含义是请求的PHP-CGI已经执行,但是由于读取资源的等没有执行完毕而导致PHP-CGI进程

大量逻辑判断优化的思路——责任链模式复习总结及其和状态模式对比

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的总结知识点如下: 责任链模式概念和例子 使用的条件 和状态模式的比较分析 责任链的优缺点 纯的责任链和不纯的责任链 javax.servlet.Filter#doFilter()方法源码分析 基于AOP思想,模拟一个拦截器 前面说了一个状态模式,总结过程中发现和这个责任链的使用场景很类似,都是为了解耦大量复杂业务逻辑判断的,那么他们有什么不同呢?回忆状态模式——状态模式允许通过改变对象的内部状态而改变对象自身的行为,这个对象

五子棋计算思路

五子棋分为有禁手和无禁手,有禁手就是在无禁手的规则的基础上加上禁手规则,具体是规则不讲了.所以就人机对战来讲,从无禁手来做,比较好做.这里只讲无禁手的情况.无禁手就是只要能连成5个子,或者5个子以上,就算赢.    而计算机博弈要解决的问题,抽象地讲只有一个问题“下一步怎么走”,对五子棋来讲,就是下一步在哪个点落子.一般的思路在 棋类人机对战的一般原理 - BillySir - 博客园  已经有说.下面重点讲五子棋特有的算法思路. 下一步怎么走,总体思路:    1.如果下一步能赢,就走这一步 

Web 开发后端缓存思路

数据写入缓存: 在数据库与服务端之间利用 redis 这是一个很常见的场景.比如文章的浏览数,每次文章被浏览时,浏览数都 +1.如果每次都回写数据库,不免数据量太大.加上数据库看似简单,其实做了不少关于一致性(请看官了解一下所谓[一致性],[base],[acid])的检查. 而同时,浏览数并不要求保证一致性,只要大概准确就行了. 所以这时候,我们可以先将浏览数写入 redis,满足一定条件后,再回写数据库. 比如,在 controller 中,让每次浏览都在 redis 上 +1,+1 完成后

使用RNN解决NLP中序列标注问题的通用优化思路

/* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 序列标注问题应该说是自然语言处理中最常见的问题,而且很可能是最而没有之一.在深度学习没有广泛渗透到各个应用领域之前,传统的最常用的解决序列标注问题的方案是最大熵.CRF等模型,尤其是CRF,基本是最主流的方法.随着深度学习的不断探索和发展,很可能RNN模型会取代CRF的传统霸主地位,会成为解决序列标注问题的标配解决方案. 本文主要抽象出利用RNN解决序列标注问题的通用优化思路.这个RNN优化思路应该

政府采购电子办公系统总结-思路篇

前言 政府采购电子办公系统是实现招标,投标,评标等过程的电子化管理.在这个系统中我所负责的是招标文件制作和档案管理.这篇文章里我主要介绍一下对于这两部分业务的实现思路. 招标文件制作 实现思路 提炼出招标文件中相对来说容易变化的内容,这些内容因不同的招标项目而异.如:招标项目名称,采购单位,招标开始日期等.这些信息做成表单由用户来填写. 制作一个招标文件模板,在出现上述可变内容的地方写成"{}". 在生成招标文件时获得用户的信息,利用Aspose.Word替换上述模板中的"{

头像服务端设计思路

思路 一 把图片上传到服务端.命名以用户的(用户名md5)作为文件名.要是以前有文件,覆盖以前的文件 二编写一个servlet处理获取头像请求. servlet接收一个用户名md5+大小的参数 根据 用户名md5+大小生成对应的图片 例如 用户名为ada 上传到服务端的位置为 /gravatar/ada.jpg 请求地址:/webstore/headimg/ada.jpg?s=120 对应的服务端文件地址 /gravatar/ada.jpg(原图片) /gravatar/ada/120.jpg

关于Spring JDBC RowMapper的一点改进思路

[注]通常我们使用RowMapper(比如ParameterizedRowMapper),都需要定义好查询字段,如果使用别名就没办法了.还要比如加入group,或者联合查询,也不能够使用,除非不想要非主体Bean之外的字段,那么只能用Map接收返回结果了,或者直接实现RowMapper.基于这一点,提出一个稍微通用的解决思路:所有的Bean都继承一个基类Bean,里面放一个Map(就是存放那些Bean没有指定的字段了,比如sum.count.avg - 各种查询字段或者别名),参考BeanPro