拥有属于自己的一套框架和代码库

1、拥有一套属于自己的框架的重要性

拥有属于自己的一套框架和代码库是非常重要的事情。这里面有个词语“属于”,嗯,没错,只有属于自己的事物才能真正掌控着并把它玩转起来。
一套框架、一套成熟的解决方案、一套成熟的代码库是你去谈项目或者和产品经理交涉时候的筹码,它有多少,你心中就有多少底,即使你的学习能力再强,也是不能胜过已经有的代码,因为商业项目讲求的是质量 + 效率,只有经过多次实践而不败的代码才是拥有高质量的,而不是把 demo 实现了就拿来用这么简单。
由于我没有一套属于自己的框架(或称成熟的架构)。所以在做这外包之前就开始写一属于自己的框架。既然是自己的东西,就无需强求高度集成丰富的组建,而是根据实际的业务需求而定制一套框架,所以,框架并不是能万能套用,而是要看需求、看情况而定,盲目使用“漂亮”的框架的后果之一就是造成项目的臃肿。
注:本文说的框架,指的是一应用的体系结构,如:应用骨架 + 网络访问 + 数据库存取 + 消息通知 +UI 显示。
本次构建的框架主要用到以下的组建:

1、Activity + Fragment

单个 Activity 控制多个 fragment,每个 fragment 充当控制器的角色,每个页面对应自己的控制器,控制器控制自己的 view(界面),view 用 java 实现,view 中也绑定自己对应的控制器,页面的跳转使用用 eventbus 通知 activity 进行跳转。

2、ORM 使用 Activeandroid

操作数据库还是使用 ORM 比较好,相对传统的 SqlHelper 更方便简单,不易出错,减少代码工作量。

3、网络请求使用 retrofit,中间自己做了个解析器

网络请求返回的数据自动用 gson 解析并赋入对应的数据结构 bean 类,和 ORM 的性质有点相似,因为 retrofit 只是网络请求并解析,并没有封装好回调到 UI 线程的消息通知机制,所以自己实现了一个。

如果这一切都只是放在 demo 的角度来实现的话,都是很简单的事情。但如果放在一个商业项目里面去实践,便会发现好多问题,这里指的不是单单我上面提到的,而是每一种技术或者解决方案,真的要拿到真实场景去实践才能测试到问题的存在。
在这里面主要探讨一下页面跳转的结构体,我已经快给多个 fragment、fragment 嵌套的问题搞死了。也终于明白到为什么 square
建议不要用 fragment。不过致命的 bug 都解决得七七八八。不过还是存在一些奇怪现象,这得再另外一篇博文去探讨了。用 fragment 始终比用多个 activity 跳转这个老方法好多了。

2、使用 Fragment 实现页面跳转方法

单一 Activity,布局仅需要一个 FrameLayout。
页面切换的代码如下:

// 最底层的页面
private void setFragment(Fragment mTargetFragment){
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(mMainLayout.getId(),mTargetFragment,mTargetFragment.getClass()
          .getName()).
          setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
          .commit();
}

 
    
// 弹出页面
public void popFragmant(Fragment from, Fragment to) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.hide(from)
        .add(mMainLayout.getId(), to, to.getClass().getName())
        .addToBackStack(to.getClass().getName())
        .commit();
}

    
 
    
// 弹出页面, dialog 形式
public void popFragmant(Fragment to) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    if(!to.isAdded()) {
        transaction.add(mMainLayout.getId(), to, to.getClass().getName())
            .addToBackStack(to.getClass().getName())
            .commit();
    }
}

    
 
    
// 关闭页面
public void closeFragment(Fragment mTargetFragment){
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction
        .remove(mTargetFragment)
        .commit();
     getSupportFragmentManager().popBackStack();
}

 
    
// 关闭所有页面
public void closeAllFragment(){
    int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
    for(int i = 0; i < backStackCount; i++) {
        int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();
        getSupportFragmentManager().popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);

    }
}

    
 
    
// 最底层的页面
public void onEvent(Event.SetFragmentEvent event){
    setFragment(event.mFragment);
}

    
 
    
// 弹出页面
public void onEvent(Event.OpenFragmentEvent event){
    popFragmant(event.fromFragment, event.toFragment);
}

 
    
// 关闭页面
public void onEvent(Event.CloseFragmentEvent event){
    closeFragment(event.mFragment);
 }

 
    
// 关闭所有页面
public void onEvent(Event.CloswAllFragmentEvent event){
    closeAllFragment();
}

    
 
    
// 弹出页面, dialog 形式
public void onEvent(Event.PopFragment event){
    popFragmant(event.toFragment);
}

在 Activity 的 onCreate 方法里面初始化并显示第一个页面:

mMainLayout = new FrameLayout(this);

mMainLayout.setId(1);

setContentView(mMainLayout);

mWelcomeFragment = new WelcomeFragment();

setFragment(mWelcomeFragment);

设置最底层页面,显示第一个 welcome 页面,以及 welcome 页面之后跳转到的的主页,这种情况就要把底层页面替换掉,则要用上面的setFragment(Fragment mTargetFragment)
,这里面FragmentTransaction
调用了它里面的replace
方法,所以被替换的页面会被销毁,新换上的页面则是最底层的页面。
在底层页面 A 上面弹出一个页面 B,则需要popFragmant(Fragment from, Fragment to)
方法。

transaction.hide(from)
    .add(mMainLayout.getId(), to, to.getClass().getName())
    .addToBackStack(to.getClass().getName())

这里只是把页面 A 隐藏掉(hide),并且加入到回退栈里。
但如果想弹出一个类似于弹窗这样的页面,即有透明部分的一个页面,则不能调用hide
方法,否则页面 A 会被隐藏掉,这样的话透明就不存在意义了。
这样做的好处有:
1、页面可实例化
2、可设置回调
3、更易于测试
3、页面,逻辑分离
我在 Fragment 里面我做了哪些事情?
Fragment 在这里充当的角色是一个控制器。
由于我是用 JAVA 布局界面,所以我会在 Fragment 里面实例化我的界面类,并在onCreateView
return 这个界面,如:

private WelcomeView mWelcomeView;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    mWelcomeView = new WelcomeView(this);
}

 
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return mWelcomeView;
}

这样我就可以在WelcomeView
里面做布局界面的工作,并同时实现界面的逻辑,这样就不像在 xml 里面纯实现布局,而界面逻辑还需要在 Activity 去 findviewbyid,再去写界面逻辑。
注,上面说的是界面逻辑,而不是数据获取、处理、展示、以及跳转的逻辑。这些逻辑是放在 fragment 里面去做的。如 Fragment 里面实现一个从网络获取数据的方法,获取、处理后,把要展示的数据通过 View 的实例(在这里我们不是有 View 的实例吗)设置到相关的方法,这样就很好做到逻辑和界面分离。
4、遇到的问题
由于多 fragment 嵌套导致的一个问题,onActivityResult
不能成功被调用,这里我也没找到真正的原因,只是找了个解决方法。

@Override
public void onActivityResult( int requestCode,int resultCode, Intent data) {
    mCurrentFragment.onActivityResult(requestCode, resultCode, data);
    super.onActivityResult(requestCode, resultCode, data);
}

在父 fragment 实现onActivityResult
方法,然后在里面调用子 fragment 的onActivityResult
即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,070评论 25 707
  • 最近刚从旧公司离职,为面试在做准备,因为平时开发CV大法用得比较多,很多基础知识掌握得不是很牢靠以及很多工具框架只...
    黎清海阅读 2,180评论 1 19
  • 无人与我立黄昏 无人问我粥可温 无人与我捻熄灯 无人共我书半生 无人陪我夜已深 无人与我把酒分 无人拭我相思泪 无...
    529b59b4e739阅读 333评论 4 13
  • 今天完成了定金目标,解锁了4开头,嗯有点小嗨森,但又想起最初定的目标,嗯明天继续加油! Fighting ! ...
    JJFN叶子阅读 148评论 0 2
  • 透过车窗, 绿的树绿的草健美的田畴, 在风中荡漾鲜活。 我感到了, 钢筋混凝土的呆板, 玻璃幕墙的伪性。 城市就像...
    浅得塾心灵文画阅读 218评论 0 6