一、Demo结构简介
进入正题:先上两张项目结构图
1、AbsActivityGroup是本Demo的核心框架,封装了很多功能。
2、AbsSubActivity是子Activity的核心框架,重写了一些方法,这样可以支持一个子Activity既可以在同一个ActivityGroup里面向其他子Activity跳转,也支持向Group外部的普通Activity跳转,而跳转方法的不同取决于目标的Activity是否继承了AbsSubActivity。
3、MainActivityGroup是主ActivityGroup,继承自AbsActivityGroup。
4、OutActivity是一个普通的Activity,不是MainActivityGroup的内部子Activity。
5、其他的都是子Activity,继承自AbsSubActivity,其中A、B、C、D、E开头的表明该子Activity分别对应MainActivityGroup的A、B、C、D、E五个标签选项卡,每个选项卡都可以对应多个子Activity。
6、SimpleActivty是特殊的子Activity,它可以存在于任何标签下,其实前面的也可以,但因为名字约束了就将其固定在一个标签下了,实际开发中选项卡共用同一个子Activity的情况也不是很多。
二、框架特色
1、功能强大:每个选项卡都可以对应多个子Activity,这个是普通TabActivity做不到的。
2、非常方便,实现的ActivityGroup只要继承AbsActivityGroup并实现它的5个回调方法即可;
同理,实现的子Activity只要继承AbsSubActivity即可,不需要重写任何方法。
3、支持各种跳转:选项卡之间的相互切换;
同一标签卡下的子Activity内部跳转,带结果返回的内部跳转;
向ActivityGroup外部的普通Activity的跳转以及带结果返回的跳转;
支持选项卡再按一次返回该选项卡的第一个界面的功能。
4、支持记忆性:所有内部返回操作不会重新onCreate新的子Activity,所有向前跳转都是onCreate新的Activity。
三、使用方法及注意事项(以下内容暂不涉及框架原理)
1、主ActivityGroup的layout代码(示例):
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/layout_full"
- android:orientation="vertical"
- android:background="#ffffff">
- <LinearLayout
- android:id="@+id/activity_group_container"
- style="@style/layout_vertical"
- android:layout_weight="8.5">
- </LinearLayout>
- <RadioGroup
- style="@style/bottombar_radioGroup"
- android:id="@+id/activity_group_radioGroup"
- android:checkedButton="@+id/activity_group_radioButton0"
- android:background="#ff0000"
- android:layout_weight="1">
- <RadioButton
- style="@style/bottombar_radioButton"
- android:id="@id/activity_group_radioButton0"/>
- <RadioButton
- style="@style/bottombar_radioButton"
- android:id="@+id/activity_group_radioButton1"/>
- <RadioButton
- style="@style/bottombar_radioButton"
- android:id="@+id/activity_group_radioButton2"/>
- <RadioButton
- style="@style/bottombar_radioButton"
- android:id="@+id/activity_group_radioButton3"/>
- <RadioButton
- style="@style/bottombar_radioButton"
- android:id="@+id/activity_group_radioButton4"/>
- </RadioGroup>
- </LinearLayout>
复制代码
说明:一些细节已被我用style封装起来了,
写这个布局要注意放子Activity的布局和radioGroup的id要写成和我这里的一样,
也就是上面的 android:id="@+id/activity_group_container" 和android:id="@+id/activity_group_radioGroup"
代码中的8.5和1的两个weight数值,是这两部分的显示比例,大家可以根据自己项目的需求进行调整。
2、MainActivityGroup的实现(代码注释比较详细,我就不废话了)
- // 继承AbsActivityGroup并实现其五个抽象方法即可
- public class MainActivityGroup extends AbsActivityGroup{
-
- // 第一个需要实现的方法,直接返回ActivityGroup实现类的layou布局即可
- // 注意该布局一定要有个id为activity_group_container的布局用来放子Activity的布局
- @Override
- protected int getLayoutResourceId() {
- return R.layout.activity_group_bottom5_layout;
- }
-
- // 第二个需要实现的方法,返回layout布局下选项卡对应的radioButton的id
- @Override
- protected int[] getRadioButtonIds() {
- return new int[] { R.id.activity_group_radioButton0,
- R.id.activity_group_radioButton1,
- R.id.activity_group_radioButton2,
- R.id.activity_group_radioButton3,
- R.id.activity_group_radioButton4 };
- }
-
- // 第三个需要实现的方法,上面一个方法中的radioButton对应的图标,注意图标的尺寸要自己调整到合适大小
- @Override
- protected int[] getRadioButtonImageIds() {
- return new int[] { R.drawable.icon2, R.drawable.icon2, R.drawable.icon2,
- R.drawable.icon2, R.drawable.icon2, };
- }
-
- // 第四个需要实现的方法,radioButton对应的文字,也就是选项卡标签的文字,
- // 最好不要太长,否则要到布局文件里调整文字大小到适应界面
- @Override
- protected String[] getRadioButtonTexts() {
- return new String[]{"A","B","C","D","E"};
- }
-
- // 第五个需要实现的方法,返回每个选项卡对应的第一个子Activity(注意要继承自AbsSubActivity)
- @SuppressWarnings("unchecked")
- @Override
- public Class<? extends Activity>[] getClasses() {
- Class<? extends Activity>[] classes = new Class[] { A1Activity.class,
- B1Activity.class, C1Activity.class, D1Activity.class,
- E1Activity.class };
- return classes;
- }
-
- }
复制代码
3、子Activity的实现(以A1Activity为例)
- public class A1Activity extends AbsSubActivity{
-
- private TextView tv;
- private EditText et;
- private Button btn1,btn2,btn3,btn4,btn5;
-
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- tv = ((TextView)findViewById(R.id.test));
- et = (EditText) findViewById(R.id.et);
- btn1 = ((Button)findViewById(R.id.btn));
- btn2 = ((Button)findViewById(R.id.btn2));
- btn3 = ((Button)findViewById(R.id.btn3));
- btn4 = ((Button)findViewById(R.id.btn4));
- btn5 = ((Button)findViewById(R.id.btn5));
-
- tv.setText("A1Activity");
- btn1.setText("跳到A2Activity(startActivity方式)");
- btn2.setText("跳到A2Activity(ForResult方式)");
- btn3.setText("跳出Group到OutActivity(startActivity方式)");
- btn4.setText("跳出Group到OutActivity(ForResult方式)");
- btn1.setOnClickListener(myClickListener);
- btn2.setOnClickListener(myClickListener);
- btn3.setOnClickListener(myClickListener);
- btn4.setOnClickListener(myClickListener);
- btn5.setOnClickListener(myClickListener);
-
- }
- private OnClickListener myClickListener = new OnClickListener(){
-
- @Override
- public void onClick(View v) {
- if(v == findViewById(R.id.btn)){
- startActivity(new Intent(A1Activity.this,A2Activity.class));
- } else if(v == findViewById(R.id.btn2)){
- startActivityForResult(new Intent(A1Activity.this,A2Activity.class),1);
- } else if(v == findViewById(R.id.btn3)){
- startActivity(new Intent(A1Activity.this,OutActivity.class));
- } else if(v == findViewById(R.id.btn4)){
- startActivityForResult(new Intent(A1Activity.this,OutActivity.class),2);
- } else if(v == findViewById(R.id.btn5)){
- finish();
- }
- }
-
- };
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if(requestCode == 1 && resultCode == 1){
- et.setText("从A2Activity回来了 ");
- } else if(requestCode == 2 && resultCode == 2){
- et.setText("从OutActivity回来了 "+data.getStringExtra("data"));
- }
-
- }
-
- }
复制代码
大家都能看得懂的代码,除了继承自AbsSubActivity外,其余和普通Activity的代码一样,
但因为框架重写了跳转方法,所以以上代码中按钮的监听事件里的子Activity间的跳转就顺利实现了。
不过设置返回结果稍显不一样,普通Activity(OutActivity)是这样的:
Intent intent = getIntent();
intent.putExtra("data",et.getText().toString().trim());
setResult(2,intent);
finish();
而子Activity不能调用finish();所以我在框架里封装了另一个方法供调用:
fromIntent.putExtra("data",et.getText().toString().trim());
gobackWithResult(1,fromIntent);
而如果不需要设置返回结果,可以调用另一个封装好的方法goback();
四、框架源码:
由于本教程的核心不是讲框架的原理,加之这个框架说大不大,说小不小,所以只加了一部分必要的注释,大家自己看看吧,相信大家是能够看得懂的
不好意思各位,由于篇幅的原因影响到帖子排版,源码就不贴了,大家下载附件下来自己看吧