[Android]AndroidBucket增加碎片SubLayout功能及AISubLayout的注解支持

以下内容为原创,转载请注明:

来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3709957.html

 

之前写过一篇博客,是使用Fragment来实现TabHost的效果,并且模拟TabHost的切换各个fragment生命周期的调用,见http://www.cnblogs.com/tiantianbyconan/p/3360938.html

但是如果要实现的效果是两级的Tab,比如在第一级tab中又有三个子Tab切换不同的布局,

相当于在Fragment中嵌套来Fragment,这个怎么实现?

也有个官方的实现方法,通过使用android-support-v13.jar包中的getChildFragmentManager方法来获取一个Manager。

这里带来我写的一个新的方案,使用SubLayout来实现。

相关源码:https://github.com/wangjiegulu/AndroidBucket/tree/master/src/com/wangjie/androidbucket/customviews/sublayout

下面使用一个例子来说下使用方法,先看下最后的效果(项目使用了我的开源AndroidBucketAndroidInject 请先添加依赖项目,欢迎star/fork):

效果跟以前的例子大同小异,点击第一个tab上的TextView,然后Toast提示EditText上的信息,但是使用方式却是不一样的。

大体的思路是在MainActivity布局中增加一个FrameLayout,然后在切换过程中不停的用相应的布局去替换FrameLayout中。

main.xml布局如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3               android:orientation="vertical"
 4               android:layout_width="fill_parent"
 5               android:layout_height="fill_parent"
 6         >
 7 
 8     <FrameLayout
 9             android:id="@+id/main_content_view"
10             android:layout_width="match_parent"
11             android:layout_height="0dp"
12             android:layout_weight="1.0"
13             />
14 
15     <RadioGroup
16             android:id="@+id/main_tabs_rg"
17             android:layout_width="fill_parent"
18             android:layout_height="65dp"
19             android:background="#aabbcc"
20             android:gravity="center_vertical"
21             android:orientation="horizontal" >
22 
23         <RadioButton
24                 android:id="@+id/main_tab_a_rb"
25                 style="@style/tab_item_background"
26                 android:drawableTop="@drawable/ic_launcher"
27                 android:paddingTop="7dp"
28                 android:textSize="13sp"
29                 android:checked="true"
30                 />
31 
32         <RadioButton
33                 android:id="@+id/main_tab_b_rb"
34                 style="@style/tab_item_background"
35                 android:drawableTop="@drawable/ic_launcher"
36                 android:paddingTop="7dp"
37                 android:textSize="13sp"
38                 />
39 
40         <RadioButton
41                 android:id="@+id/main_tab_c_rb"
42                 style="@style/tab_item_background"
43                 android:drawableTop="@drawable/ic_launcher"
44                 android:paddingTop="7dp"
45                 android:textSize="13sp"
46                 />
47 
48     </RadioGroup>
49 
50 </LinearLayout>

布局很简单,一个FrameLayout用于存放不同界面的布局,3个RadioButton表示下面的每一项Tab按钮。

在MainActivity中代码如下:

@AILayout(R.layout.main)
public class MainActivity extends AIActivity {public static final String TAG = MainActivity.class.getSimpleName();@AIView(R.id.main_content_view)ViewGroup contentView;@AIView(R.id.main_tabs_rg)RadioGroup rg;SubLayoutManager sbManager;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);sbManager = new SubLayoutManager<SubLayout>(context, contentView, TabASubLayout.class, TabBSubLayout.class, TabCSubLayout.class);sbManager.setSwitchListener(new SubLayoutManager.LayoutSwitchListener<SubLayout>() {@Overridepublic void switchSelf(SubLayout subLayout, int position) {Logger.d(TAG, "[switch listener]switchSelf, subLayout: " + subLayout + ", position: " + position);}@Overridepublic void switchCompleted(SubLayout subLayout, int position) {Logger.d(TAG, "[switch listener]switchCompleted, subLayout: " + subLayout + ", position: " + position);}});rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup radioGroup, int i) {int index = -1;switch(i){case R.id.main_tab_a_rb:index = 0;break;case R.id.main_tab_b_rb:index = 1;break;case R.id.main_tab_c_rb:index = 2;break;}if(index < 0 || index >= sbManager.getSubLayoutSize()){return;}sbManager.switchLayout(index);}});sbManager.switchLayout(0); // 默认切换第一页
}@Overrideprotected void onDestroy() {super.onDestroy();sbManager.destoryClear();sbManager = null;}}

上面的SubLayout相当于一个Fragment,SubLayoutManager用于管理多个SubLayout之间的切换。SubLayoutManager可以通过new获取。

其中构造方法中:

public SubLayoutManager(Context context, ViewGroup contentView, Class<? extends T>... slszzs) {

参数二:contentView表示在MainActivity中预留给SubLayout显示的FrameLayout。

参数三:是个可变长参数,可以在后面(有序)追加所有需要切换的SubLayout的Class对象。

第一次初始化后各个SubLayout对象不会马上生成,只会在切换到改页面时才会生成该对象,会执行SubLayout的initLayout()方法,这个方法只会调用一次(类似onCreate()方法)

需要切换页面时只需要执行SubLayoutManager的switchLayout()方法,传入SubLayout的position就可以了,这个position跟参数三的顺序一致。

 

接下来看下几个SubLayout是怎么去实现的,因为三个SubLayout大致相同,所以只分析一个就可以了:

TabASubLayout代码如下:

 1 @AILayout(R.layout.tab_a)
 2 public class TabASubLayout extends AISubLayout {
 3     public static final String TAG = TabASubLayout.class.getSimpleName();
 4 
 5 
 6 //    @AIView(R.id.tab_a_tv)
 7 //    TextView tv;
 8     @AIView(R.id.tab_a_et)
 9     EditText et;
10 
11     public TabASubLayout(Context context) {
12         super(context);
13 //        setContentView(R.layout.tab_a);
14 
15     }
16 
17     @Override
18     public void initLayout() {
19         super.initLayout();
20         Logger.d(TAG, "initLayout...");
21     }
22 
23     @AIClick({R.id.tab_a_tv})
24     public void onClickCallbackSample(View view) {
25         Toast.makeText(context, "clicked: " + ((TextView)view).getText() + ", " + et.getText(), Toast.LENGTH_SHORT).show();
26     }
27 
28     @Override
29     public void onResume() {
30         super.onResume();
31         Logger.d(TAG, "onResume...");
32     }
33 
34     @Override
35     public void onPause() {
36         super.onPause();
37         Logger.d(TAG, "onPause...");
38     }
39 
40 }

代码很简单,继承AISubLayout即可,AISubLayout是AndroidInject中AndroidBucket的子类,实现了SubLayout的注解的支持。当然你也可以直接继承SubLayout,这样的话就不能使用注解了,看上面的被注释的代码,可以通过setContentView来设置对应的布局,可以通过findViewById来获取控件对象。

它也有onResume和onPause方法,当前页A被切换到B的话会调用A的onPause,然后调用B的onResume(如果之前B没有被初始化过,则先调用initLayout再调用onResume方法)

下面来看看log打印的日志:

 

// 以下为启动应用,默认加载TabA

05-05 08:22:32.216 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch start-----------------------
05-05 08:22:32.216 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch before.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=null}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=null}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=null}]
05-05 08:22:32.336 1086-1086/com.wangjie.sublayouttest D/TabASubLayout﹕ initLayout...
05-05 08:22:32.336 1086-1086/com.wangjie.sublayouttest D/TabASubLayout﹕ onResume...
05-05 08:22:32.336 1086-1086/com.wangjie.sublayouttest D/MainActivity﹕ [switch listener]switchCompleted, subLayout: com.wangjie.sublayouttest.TabASubLayout@b4dff088, position: 0
05-05 08:22:32.336 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch after.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=com.wangjie.sublayouttest.TabASubLayout@b4dff088}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=null}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=null}]
05-05 08:22:32.336 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch end-----------------------


// TabA切换到TabB
05-05 08:22:37.926 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch start-----------------------
05-05 08:22:37.926 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch before.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=com.wangjie.sublayouttest.TabASubLayout@b4dff088}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=null}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=null}]
05-05 08:22:37.946 1086-1086/com.wangjie.sublayouttest D/TabASubLayout﹕ onPause...
05-05 08:22:37.986 1086-1086/com.wangjie.sublayouttest D/TabBSubLayout﹕ initLayout...
05-05 08:22:37.996 1086-1086/com.wangjie.sublayouttest D/TabBSubLayout﹕ onResume...
05-05 08:22:37.996 1086-1086/com.wangjie.sublayouttest D/MainActivity﹕ [switch listener]switchCompleted, subLayout: com.wangjie.sublayouttest.TabBSubLayout@b4de1d80, position: 1
05-05 08:22:37.996 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch after.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=com.wangjie.sublayouttest.TabASubLayout@b4dff088}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=com.wangjie.sublayouttest.TabBSubLayout@b4de1d80}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=null}]
05-05 08:22:37.996 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch end-----------------------


// TabB切换到TabC
05-05 08:22:41.486 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch start-----------------------
05-05 08:22:41.486 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch before.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=com.wangjie.sublayouttest.TabASubLayout@b4dff088}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=com.wangjie.sublayouttest.TabBSubLayout@b4de1d80}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=null}]
05-05 08:22:41.496 1086-1086/com.wangjie.sublayouttest D/TabBSubLayout﹕ onPause...
05-05 08:22:41.516 1086-1086/com.wangjie.sublayouttest D/TabCSubLayout﹕ initLayout...
05-05 08:22:41.516 1086-1086/com.wangjie.sublayouttest D/TabCSubLayout﹕ onResume...
05-05 08:22:41.516 1086-1086/com.wangjie.sublayouttest D/MainActivity﹕ [switch listener]switchCompleted, subLayout: com.wangjie.sublayouttest.TabCSubLayout@b4e17840, position: 2
05-05 08:22:41.516 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch after.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=com.wangjie.sublayouttest.TabASubLayout@b4dff088}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=com.wangjie.sublayouttest.TabBSubLayout@b4de1d80}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=com.wangjie.sublayouttest.TabCSubLayout@b4e17840}]
05-05 08:22:41.526 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch end-----------------------

 

// TabC切换到TabA
05-05 08:22:44.086 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch start-----------------------
05-05 08:22:44.086 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch before.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=com.wangjie.sublayouttest.TabASubLayout@b4dff088}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=com.wangjie.sublayouttest.TabBSubLayout@b4de1d80}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=com.wangjie.sublayouttest.TabCSubLayout@b4e17840}]
05-05 08:22:44.086 1086-1086/com.wangjie.sublayouttest D/TabCSubLayout﹕ onPause...
05-05 08:22:44.136 1086-1086/com.wangjie.sublayouttest D/TabASubLayout﹕ onResume...
05-05 08:22:44.136 1086-1086/com.wangjie.sublayouttest D/MainActivity﹕ [switch listener]switchCompleted, subLayout: com.wangjie.sublayouttest.TabASubLayout@b4dff088, position: 0
05-05 08:22:44.136 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ switch after.........: [DelayObj{clazz=class com.wangjie.sublayouttest.TabASubLayout, delayObj=com.wangjie.sublayouttest.TabASubLayout@b4dff088}, DelayObj{clazz=class com.wangjie.sublayouttest.TabBSubLayout, delayObj=com.wangjie.sublayouttest.TabBSubLayout@b4de1d80}, DelayObj{clazz=class com.wangjie.sublayouttest.TabCSubLayout, delayObj=com.wangjie.sublayouttest.TabCSubLayout@b4e17840}]
05-05 08:22:44.136 1086-1086/com.wangjie.sublayouttest D/SubLayoutManager﹕ -----switch end-----------------------

 

转载于:https://www.cnblogs.com/tiantianbyconan/p/3709957.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

更新说明

按暂时的设想&#xff0c;这个 blog 近期主要会更新三个方面的内容。 其一&#xff0c;是关于 Andrew Ng 在 coursa 上开设的 Machine Learning 的课程。 我不打算放课堂的笔记或者实录&#xff0c;而是主要分析一些作业的小项目的实现思路以及一些补充性的内容。有机会的话也试…

Java设计模式6:策略模式

策略模式 策略模式的用意是针对一组算法&#xff0c;将每一个算法封装到具有共同接口的独立类中&#xff0c;从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。 策略模式的结构 策略模式是对算法的包装&#xff0c;是把使用算法的责任和算法本…

WordPress 获取当前页面 ID 的几大方法

https://zhangzifan.com/wordpress-get-id.html 在很多的 WordPress 主题或者插件功能的开发中&#xff0c;我们总是需要获取到 WordPress 给每个页面定义的 ID&#xff0c;不然也某些情况下是无法确定这是哪一个页面&#xff0c;针对于文章或者页面的 ID 获取基本可以使用 get…

王者荣耀交流协会第四次Scrum立会

拍照的是王磊同学&#xff0c;没有出镜。 开会时间&#xff1a;2017年10月30日下午18&#xff1a;45-19&#xff1a;16 共计31分钟 开会地点&#xff1a;一食堂二楼靠近窗户倒数第四排 今日完成工作进度&#xff1a; 袁玥同学完成了点击按钮刷新时间的功能代码&#xff1b; 王…

Python在信号与系统(1)——Hilbert兑换,Hilbert在国家统计局的包络检测应用,FIR_LPF滤波器设计,格鲁吉亚也迫使高FM(PM)调制...

谢谢董老师&#xff0c;董老师是个好老师。 心情久久不能平静&#xff0c;主要是高频这门课的分析方法实在是让我难以理解&#xff0c;公式也背只是&#xff0c;还是放放吧。 近期厌恶了Matlab臃肿的体积和频繁的读写对我的Mac的损害&#xff0c;所以学习了一下Python这一轻量级…

如何在WP-Config中设置WordPress错误日志

https://baijiahao.baidu.com/s?id1622279671500148245&wfrspider&forpc 你想在wp-config文件中设置WordPress错误日志吗&#xff1f;WordPress中的wp-config文件不仅控制您的WordPress网站设置&#xff0c;它也是一个非常有用的调试工具&#xff0c;可帮助您查找和修…

[再寄小读者之数学篇](2014-04-22 平方差公式在矩阵中的表达)

设 $A,B$ 都是 $n$ 阶复方阵, 且 $A^2B^22AB$. 证明: (1) $AB-BA$ 不可逆; (2) 如果 $\rank(A-B)1$, 那么 $ABBA$. 转载于:https://www.cnblogs.com/zhangzujin/p/3712973.html

C#:ref和out的联系及区别。

总结以上四条得到ref和out使用时的区别是&#xff1a;①&#xff1a;ref指定的参数在函数调用时候必须初始化&#xff0c;不能为空的引用。而out指定的参数在函数调用时候可以不初始化&#xff1b;②&#xff1a;out指定的参数在进入函数时会清空自己&#xff0c;必须在函数内部…

wordpress启用侧边栏小工具

http://www.seo628.com/1872.html wordpress后台默认不显示小工具选项&#xff0c;开发者需要启用小工具功能并把小工具在相应的前台位置调用出来&#xff0c;这样才能在后台直接拖动生成侧边栏。 激活小工具 激活小工具需要在functions.php中注册至少一个侧边栏 register_s…

comparator接口与Comparable接口的区别

Comparable & Comparator 都是用来实现集合中元素的比较、排序的&#xff0c;只是 Comparable 是在集合内部定义的方法实现的排序&#xff0c;Comparator 是在集合外部实现的排序&#xff0c;所以&#xff0c;如想实现排序&#xff0c;就需要在集合外定义 Comparator 接口的…

详解 Spotlight on MySQL监控MySQL服务器

前一章详解了Spotlight on Unix 监控Linux服务器 &#xff0c;今天再来看看Spotlight on MySQL怎么监控MySQL服务器。 注&#xff1a;http://www.cnblogs.com/Javame/p/3685512.html 第一步: 下载并安装mysql-connector-3.5x Spotlight on MySQL 连接mysql必须使用mysql-connec…

lua------------------Unity3D研究院编辑器之打开unity不可识别的文件(十三)

Unity3D研究院编辑器之打开unity不可识别的文件&#xff08;十三&#xff09; 雨松MOMO 【Unity3D拓展编辑器】 围观8597次 9 条评论 编辑日期&#xff1a;2017-03-02 字体&#xff1a;大 中 小 有些特殊后缀名的文件在unity里是不可识别的。如下图所示&#xff0c;这里我把文本…

一起Polyfill系列:Function.prototype.bind的四个阶段

昨天边参考es5-shim边自己实现Function.prototype.bind&#xff0c;发现有不少以前忽视了的地方&#xff0c;这里就作为一个小总结吧。 一、Function.prototype.bind的作用 其实它就是用来静态绑定函数执行上下文的this属性&#xff0c;并且不随函数的调用方式而变化。 示例&am…

Window 通过cmd查看端口占用、相应进程、杀死进程等的命令【转】

一、 查看所有进程占用的端口 在开始-运行-cmd,输入&#xff1a;netstat –ano可以查看所有进程 二、查看占用指定端口的程序 当你在用tomcat发布程序时&#xff0c;经常会遇到端口被占用的情况&#xff0c;我们想知道是哪个程序或进程占用了端口&#xff0c;可以用该命令 ne…

盘点18个免费的WordPress主题后台选项开发框架

https://yusi123.com/3205.html/3 13.Warp Framework Warp框架不仅支持WordPress和Joomla,还可以可扩展到其他的适用Web程序。使用Warp框架你可以轻松的定制你需要的功能。 该框架是来自Yootheme团队。看看他们出的主题&#xff0c;你就知道这个绝对是精品了。精心设计的界面和…

lua----------------使用VS2015搭建lua开发环境的一些侥幸成功经验,

所以本篇博文介绍在Windows平台下&#xff0c;使用VS2015搭建lua开发环境的一些侥幸成功经验&#xff0c;安装过程参考网上教程&#xff0c;安装过程如下&#xff08;参考http://www.byjth.com/lua/33.html&#xff09; 一 生成lua5.3.lib 1、下载并编译lua源码 首先进入lua官…

中国剩余定理求解“六位教授必须首次都停止上课”问题

问题&#xff1a; 六位教授在周一至周六开始上课&#xff0c;这六位教授分别每2,3,4,1,6,5天授课一次&#xff0c; 该学校禁止周天上课&#xff0c;因此周天必须停课&#xff0c;问什么时候所有六位教授首次发现他们必须同时停课&#xff1f;(中国剩余定理知识求解) 求解&#…

wordpress 主题开发

https://www.cnblogs.com/welhzh/p/6937243.html wordpress 主题开发 https://yusi123.com/3205.html https://themeshaper.com/2012/10/22/the-themeshaper-wordpress-theme-tutorial-2nd-edition/ https://codex.wordpress.org/Theme_Frameworks https://lorelle.wordpre…

CentOS6.4下安装TeamViewer8

今天测试selenium调用firefoxdriver&#xff0c;该驱动无法在无界面环境中运行&#xff0c;需要远程连接到服务器进行操作&#xff0c;于是有了下面安装TeamViewer的过程。 先前尝试很多次也没有运行起来TeamViewer8&#xff0c;主要问题是安装后启动时候&#xff0c;没有出现授…

关于std::ios::sync_with_stdio(false)

std::ios::sync_with_stdio(false); 很多C的初学者可能会被这个问题困扰&#xff0c;经常出现程序无故超时&#xff0c;最终发现问题处在cin和cout上&#xff0c;&#xff08;甚至有些老oier也会被这个问题困扰&#xff0c;每次只能打scanf和printf&#xff0c;然后一堆的占位符…