搭建Activity与Fragment,Fragment与Fragment之间的通信架构

内心独白: 

    曾几何时但凡听到架构之两个字,总能联想到老子说的一句话:"玄之又玄,众妙之门"。说不清,道不明。就像是看不见,摸不着,但又真实存在的东西给我们的那种感觉。

    回顾人类的历史,繁重的劳动让我们意识到工具的必要性和重要性,并学会了去发明和使用工具。当我进行了大量的,甚至是繁重的编程之后,也开始重新意识到架构的必要性和重要性。当然软件工程发展了这么多年,构架与模式之类的东西前辈们早就说过并且践行与呼吁过,并且也留下了很多值得我们学习和研究的构架模式。但于我个人而言,在没有经历过痛苦之前,并没能真正的感受到前辈们所谓的构架并不是在故弄玄虚,而是真正让我们远离痛苦又真实存在的结晶。

    正所谓:"道不远人,远人而非道"。我也力求把自己写的东西尽可能自然,明白的分享出来,以求得与大家一起学习一起进步。

主题目标:搭建Activity与Fragment,Fragment与Fragment之间的通信架构

主板架构图:主板与各卡之间通信的架构方式正是我们要借鉴的架构

 

wKioL1SVmgnSHouDAADSo3mxkQ0217.jpg

 

主题架构图:Activity与Fragment,Fragment与Fragment之间的通信架构可类似于主板与各卡之间的架构

 

wKiom1SVmuuC_PpVAAEfYV2aLGI006.jpg

案例展示:

 (1)项目结构

 

wKioL1SVoDCC5CwUAAG5jfU_GL8207.jpg

(2)效果图

wKiom1SVtdfTO6CGAAEP2b31_NQ420.gif

 

(3)布局文件

activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >
 
    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>
 
</RelativeLayout>
list_fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >
 
    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:background="@drawable/icon1"
        android:contentDescription="@string/list_icon_desc"
        android:scaleType="fitXY" />
 
</RelativeLayout>
detail_fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >
 
  <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
          android:contentDescription="@string/detail_icon_desc"
        android:background="@drawable/icon2"
        android:scaleType="fitXY" />
</RelativeLayout>
share_fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >
 
    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/icon3"
        android:contentDescription="@string/share_icon_desc"
        android:scaleType="fitXY" />
 
</RelativeLayout>
other_fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >
 
    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:background="@drawable/icon4"
        android:contentDescription="@string/other_icon_desc"
        android:scaleType="fitXY" />
 
</RelativeLayout>
AndroidManifest.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zkyit.fragmentframework"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.zkyit.fragmentframework.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

(4)字符串资源文件

strings.xml
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<resources>
 
    <string name="app_name">FragmentFramework</string>
    <string name="list_icon_desc">PPTV</string>
    <string name="detail_icon_desc">墨迹</string>
    <string name="share_icon_desc">去哪儿</string>
    <string name="other_icon_desc">天天动听</string>
 
</resources>

(5)图片资源文件

wKioL1SVwYLwNf_LAAAj47sWg7I705.jpg

wKiom1SVwTLBIRe-AAAi2w5L0fU738.jpg

wKioL1SVwhriS948AAAf4oX64oU307.jpg wKiom1SVwYrAMDeVAAAlykIcHJg233.jpg
icon1.png icon2.png icon3.png icon4.png

(6)逻辑代码文件

com.zkyit.fragmentframework.fragment包
ListFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.zkyit.fragmentframework.fragment;
 
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
 
import com.zkyit.fragmentframework.R;
 
@SuppressLint("NewApi")
public class ListFragment extends Fragment implements OnClickListener {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.list_fragment, null);
        ImageView mIconIv = (ImageView) view.findViewById(R.id.iv_icon);
        mIconIv.setOnClickListener(this);
        return view;
    }
 
    /*
     * 通信回调接口(Fragment跳转到另一个Fragment, 把跳转权交给Activity,让Activity决定如何跳转,
     * 从而降低了Fragment与Fragment之间的耦合性)
     */
    public interface onListFragmentCallback {
        void onListCallback();
    }
 
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.iv_icon:
            /*
             * 这里使用getActivity()来动态获取Fragment所依附的Activity,
             * 目的是为了降低Fragment与Activity的耦合性
             */
            if (getActivity() instanceof onListFragmentCallback) {
                /*
                 * 通过回调将控制权交给实现了回调接口的Activity
                 * (总控制中心,控制与其相关的所有Fragment)
                 * 而不是在这里直接与其它Fragment交互
                 */
                ((onListFragmentCallback) getActivity()).onListCallback();
            }
            break;
 
        default:
 
            break;
        }
    }
}
DetailFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.zkyit.fragmentframework.fragment;
 
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
 
import com.zkyit.fragmentframework.R;
 
@SuppressLint("NewApi")
public class DetailFragment extends Fragment implements OnClickListener {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.detail_fragment, null);
        ImageView mIconIv = (ImageView) view.findViewById(R.id.iv_icon);
        mIconIv.setOnClickListener(this);
        return view;
    }
 
    /*
     * 通信回调接口(Fragment跳转到另一个Fragment, 把跳转权交给Activity,
     * 让Activity决定如何跳转,从而降低了Fragment与Fragment之间的耦合性)
     */
    public interface onDetailFragmentCallback {
        void onDetailCallback();
    }
 
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.iv_icon:
            /*
             * 这里使用getActivity()来动态获取Fragment所依附的Activity, 目的是为了
             * 降低Fragment与Activity的耦合性
             */
            if (getActivity() instanceof onDetailFragmentCallback) {
                /*
                 * 通过回调将控制权交给实现了回调接口的Activity
                 * (总控制中心,控制与其相关的所有Fragment)
                 * 而不是在这里直接与其它Fragment交互
                 */
                ((onDetailFragmentCallback) getActivity()).onDetailCallback();
            }
            break;
 
        default:
 
            break;
        }
 
    }
}
ShareFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.zkyit.fragmentframework.fragment;
 
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
 
import com.zkyit.fragmentframework.R;
 
@SuppressLint("NewApi")
public class ShareFragment extends Fragment implements OnClickListener {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.share_fragment, null);
        ImageView mIconIv = (ImageView) view.findViewById(R.id.iv_icon);
        mIconIv.setOnClickListener(this);
        return view;
    }
 
    /*
     * 通信回调接口(Fragment跳转到另一个Fragment, 把跳转权交给Activity,让Activity决定如何跳转,
     * 从而降低了Fragment与Fragment之间的耦合性)
     */
    public interface onShareFragmentCallback {
        void onShareCallback();
    }
 
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.iv_icon:
            /*
             * 这里使用getActivity()来动态获取Fragment所依附的Activity,
             * 目的是为了降低Fragment与Activity的耦合性
             */
            if (getActivity() instanceof onShareFragmentCallback) {
                /*
                 * 通过回调将控制权交给实现了回调接口的Activity
                 * (总控制中心,控制与其相关的所有Fragment)
                 * 而不是在这里直接与其它Fragment交互
                 */
                ((onShareFragmentCallback) getActivity()).onShareCallback();
            }
            break;
 
        default:
 
            break;
        }
    }
}
OtherFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.zkyit.fragmentframework.fragment;
 
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
 
import com.zkyit.fragmentframework.R;
 
@SuppressLint("NewApi")
public class OtherFragment extends Fragment implements OnClickListener {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.other_fragment, null);
        ImageView mIconIv = (ImageView) view.findViewById(R.id.iv_icon);
        mIconIv.setOnClickListener(this);
        return view;
    }
 
    /*
     * 通信回调接口(Fragment跳转到另一个Fragment, 把跳转权交给Activity,让Activity决定如何跳转,
     * 从而降低了Fragment与Fragment之间的耦合性)
     */
    public interface onOtherFragmentCallback {
        void onOtherCallback();
    }
 
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.iv_icon:
            /*
             * 这里使用getActivity()来动态获取Fragment所依附的Activity,
             * 目的是为了降低Fragment与Activity的耦合性
             */
            if (getActivity() instanceof onOtherFragmentCallback) {
                /*
                 * 通过回调将控制权交给实现了回调接口的Activity
                 * (总控制中心,控制与其相关的所有Fragment)
                 * 而不是在这里直接与其它Fragment交互
                 */
                ((onOtherFragmentCallback) getActivity()).onOtherCallback();
            }
            break;
 
        default:
 
            break;
        }
    }
}
com.zkyit.fragmentframework包
MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package com.zkyit.fragmentframework;
 
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.Toast;
 
import com.zkyit.fragmentframework.fragment.DetailFragment;
import com.zkyit.fragmentframework.fragment.DetailFragment.onDetailFragmentCallback;
import com.zkyit.fragmentframework.fragment.ListFragment;
import com.zkyit.fragmentframework.fragment.ListFragment.onListFragmentCallback;
import com.zkyit.fragmentframework.fragment.OtherFragment;
import com.zkyit.fragmentframework.fragment.OtherFragment.onOtherFragmentCallback;
import com.zkyit.fragmentframework.fragment.ShareFragment;
import com.zkyit.fragmentframework.fragment.ShareFragment.onShareFragmentCallback;
 
/**
 * 主界面Activity,要控制哪个Fragment,就实现哪个Fragment的回调接口,
 * 案例中实现了onListFragmentCallback,
 * onDetailFragmentCallback, onShareFragmentCallback,
 * onOtherFragmentCallback这几个接口,
 * 接下来就可以在各自的回调方面中控制对应的Fragment,
 * 其它Activity如果要控制某个Fragment,可直接实现其对应的回调接口,
 * 在对应的回调方法中写控制逻辑就可以了
 
 * */
@SuppressLint("NewApi")
public class MainActivity extends Activity implements onListFragmentCallback,
        onDetailFragmentCallback, onShareFragmentCallback,
        onOtherFragmentCallback {
    private FragmentManager mFragmentManager;// Fragment管理器
    private FragmentTransaction mFragmentTransaction;// Fragment事务
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 目的是为了防止屏幕旋转与重新创建Fragment,从而导致创建多个相同的Fragment
        if (savedInstanceState == null) {
            addDefaultFragment();
        }
 
    }
 
    @Override
    public void onListCallback() {
        // 控制ListFragment的回调 ,把控制ListFragment的代码写到这回
        // 假如这里要把Activity的界面替换成DetailFragment
        repalceDetailFragment();
    }
 
    @Override
    public void onDetailCallback() {
        // 控制DetailFragment的回调 ,把控制DetailFragment的代码写到这回
        // 假如这里要把Activity的界面替换成ShareFragment
        repalceShareFragment();
    }
 
    @Override
    public void onShareCallback() {
        // 控制ShareFragment的回调 ,把控制ShareFragment的代码写到这回
        // 假如这里要把Activity的界面替换成OtherFragment
        repalceOtherFragment();
    }
 
    @Override
    public void onOtherCallback() {
        // 控制OtherFragment的回调 ,把控制OtherFragment的代码写到这回
        // 假如这里要把Activity的界面替换成ListFragment
        repalceListFragment();
    }
 
    /*
     * 为当前Activity添加默认的Fragment
     */
    private void addDefaultFragment() {
        mFragmentManager = getFragmentManager();
        mFragmentTransaction = mFragmentManager.beginTransaction();
        Fragment listFragment = new ListFragment();
        mFragmentTransaction.add(R.id.fl_content, listFragment);
        mFragmentTransaction.commit();
        // 设置Logo,title,提示
        getActionBar().setLogo(R.drawable.icon1);
        setTitle(getResources().getString(R.string.list_icon_desc));
        Toast.makeText(this, getResources().getString(R.string.list_icon_desc),
                0).show();
    }
 
    /*
     * 为当前Activity添加ListFragment
     */
    private void repalceListFragment() {
        mFragmentManager = getFragmentManager();
        mFragmentTransaction = mFragmentManager.beginTransaction();
        Fragment listFragment = new ListFragment();
        mFragmentTransaction.replace(R.id.fl_content, listFragment);
        /*
         * 添加Fragment到Fragment的回退栈,以实现用户点回退键时,
         * 能再次显示出上一个Fragment,
         * 类似于多个Activity跳转后,点击回退键时的逻辑与效果,
         * 不需要则可以不加这句代码
         */
        mFragmentTransaction.addToBackStack(null);
        mFragmentTransaction.commit();
        // 设置Logo,title,提示(作测试之用)
        getActionBar().setLogo(R.drawable.icon1);
        setTitle(getResources().getString(R.string.list_icon_desc));
        Toast.makeText(this, getResources().getString(R.string.list_icon_desc),
                0).show();
    }
 
    /*
     * 为当前Activity添加DetailFragment
     */
    private void repalceDetailFragment() {
        mFragmentManager = getFragmentManager();
        mFragmentTransaction = mFragmentManager.beginTransaction();
        Fragment detailFragment = new DetailFragment();
        mFragmentTransaction.replace(R.id.fl_content, detailFragment);
        /*
         * 添加Fragment到Fragment的回退栈,以实现用户点回退键时,
         * 能再次显示出上一个Fragment,
         * 类似于多个Activity跳转后,点击回退键时的逻辑与效果,
         * 不需要则可以不加这句代码
         */
        mFragmentTransaction.addToBackStack(null);
        mFragmentTransaction.commit();
        // 设置Logo,title,提示(作测试之用)
        getActionBar().setLogo(R.drawable.icon2);
        setTitle(getResources().getString(R.string.detail_icon_desc));
        Toast.makeText(this,
                getResources().getString(R.string.detail_icon_desc), 0).show();
    }
 
    /*
     * 为当前Activity添加ShareFragment
     */
    private void repalceShareFragment() {
        mFragmentManager = getFragmentManager();
        mFragmentTransaction = mFragmentManager.beginTransaction();
        Fragment shareFragment = new ShareFragment();
        mFragmentTransaction.replace(R.id.fl_content, shareFragment);
        /*
         * 添加Fragment到Fragment的回退栈,以实现用户点回退键时,
         * 能再次显示出上一个Fragment,
         * 类似于多个Activity跳转后,点击回退键时的逻辑与效果,
         * 不需要则可以不加这句代码
         */
        mFragmentTransaction.addToBackStack(null);
        mFragmentTransaction.commit();
        // 设置Logo,title,提示(作测试之用)
        getActionBar().setLogo(R.drawable.icon3);
        setTitle(getResources().getString(R.string.share_icon_desc));
        Toast.makeText(this,
                getResources().getString(R.string.share_icon_desc), 0).show();
    }
 
    /*
     * 为当前Activity添加OtherFragment
     */
    private void repalceOtherFragment() {
        mFragmentManager = getFragmentManager();
        mFragmentTransaction = mFragmentManager.beginTransaction();
        Fragment otherFragment = new OtherFragment();
        mFragmentTransaction.replace(R.id.fl_content, otherFragment);
        /*
         * 添加Fragment到Fragment的回退栈,以实现用户点回退键时,
         * 能再次显示出上一个Fragment,
         * 类似于多个Activity跳转后,点击回退键时的逻辑与效果,
         * 不需要则可以不加这句代码
         */
        mFragmentTransaction.addToBackStack(null);
        mFragmentTransaction.commit();
        // 设置Logo,title,提示(作测试之用)
        getActionBar().setLogo(R.drawable.icon4);
        setTitle(getResources().getString(R.string.other_icon_desc));
        Toast.makeText(this,
                getResources().getString(R.string.other_icon_desc), 0).show();
    }
 
}
posted @ 2017-03-11 09:22  天涯海角路  阅读(1309)  评论(0)    收藏  举报