内心独白:
曾几何时但凡听到架构之两个字,总能联想到老子说的一句话:"玄之又玄,众妙之门"。说不清,道不明。就像是看不见,摸不着,但又真实存在的东西给我们的那种感觉。
回顾人类的历史,繁重的劳动让我们意识到工具的必要性和重要性,并学会了去发明和使用工具。当我进行了大量的,甚至是繁重的编程之后,也开始重新意识到架构的必要性和重要性。当然软件工程发展了这么多年,构架与模式之类的东西前辈们早就说过并且践行与呼吁过,并且也留下了很多值得我们学习和研究的构架模式。但于我个人而言,在没有经历过痛苦之前,并没能真正的感受到前辈们所谓的构架并不是在故弄玄虚,而是真正让我们远离痛苦又真实存在的结晶。
正所谓:"道不远人,远人而非道"。我也力求把自己写的东西尽可能自然,明白的分享出来,以求得与大家一起学习一起进步。
主题目标:搭建Activity与Fragment,Fragment与Fragment之间的通信架构
主板架构图:主板与各卡之间通信的架构方式正是我们要借鉴的架构
主题架构图:Activity与Fragment,Fragment与Fragment之间的通信架构可类似于主板与各卡之间的架构
案例展示:
(1)项目结构
(2)效果图
(3)布局文件
activity_main.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent" >
list_fragment.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
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" />
detail_fragment.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
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" />
share_fragment.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
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" />
other_fragment.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
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" />
AndroidManifest.xml
package="com.zkyit.fragmentframework"
android:versionCode="1"
android:versionName="1.0" >
android:minSdkVersion="8"
android:targetSdkVersion="19" />
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
android:name="com.zkyit.fragmentframework.MainActivity"
android:label="@string/app_name" >
(4)字符串资源文件strings.xml
FragmentFramework
PPTV
墨迹
去哪儿
天天动听
(5)图片资源文件
icon1.pngicon2.pngicon3.pngicon4.png
(6)逻辑代码文件com.zkyit.fragmentframework.fragment包
ListFragment.java
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
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
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
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
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();
}
}