强强学Android_ LoadingPager抽取

                                                                  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抽取 ]
 
强强学Android_ LoadingPager抽取_第1张图片
 
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抽取过程
强强学Android_ LoadingPager抽取_第2张图片
 
-----------------------------------------------------
 
 
 
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 }
View Code

 

 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 }
View Code

 

子类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 }
View Code

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 



来自为知笔记(Wiz)

 

你可能感兴趣的:(强强学Android_ LoadingPager抽取)