介绍
上一篇文章中介绍第一种方案,由于种种不足和缺陷,引出了第二种方案。
第二种方案是通过startActivityForResult 启动登录,当登录成功的时候,将登录结果通过setResult回传给源Activity,然后源Activity根据回传的结果进行跳转到目标页面。
由于有很多个源Activity,而且每个源Activity也需要用startActivityForResult 跳转到其他页面,当其他页面返回结果的时候在onActivityResult也会接收到很多页面回传的结果,为了能让这些多对一关系能够有条不紊的进行,需要引入SparseArray来根据requestCode保存有用的数据。当登录成功的时候在onActivityResult根据requestCode从SparseArray取出数据进行跳转页面和传递数据。
这里为了节省大家的阅读时间, 不在分不传递数据和传递数据的情况,直接介绍传递数据的情况。
定义工具类
public class UiInterceptHelper {
/**
* 没有登录跳转到登录页面
*/
public static final String KEY_LOGIN = "key_login";
public static final String KEY_DATA = "key_data";
private static SparseArray<PassData> activityMap = new SparseArray<>();
private static int serialNum = 0X001;
/**
* 跳转到相应页面,没登录先到登录页面,登录成功后返回到目标页面
* 如果登录了直接到目标页面
* @param activity 起始页面
* @param bundle 传递的数据
* @param cls 目标页面
*/
public static void launchActivityWithLoginForActivity(@NotNull Activity activity, @Nullable Bundle bundle, @NotNull Class<? extends Activity> cls) {
if (!Constant.isLogin) {
activityMap.put(serialNum, new PassData(cls, bundle));
Intent intent = new Intent(activity, LoginActivity.class);
activity.startActivityForResult(intent, serialNum);
serialNum++;
} else {
Intent intent = new Intent(activity, cls);
if (bundle != null) {
intent.putExtra(KEY_DATA, bundle);
}
activity.startActivity(intent);
}
}
/**
* 跳转到相应页面,没登录先到登录页面,登录成功后返回到目标页面
* 如果登录了直接到目标页面
* @param fragment 起始页面
* @param bundle 传递的数据
* @param cls 目标页面
*/
public static void launchActivityWithLoginForFragment(@NotNull Fragment fragment, @Nullable Bundle bundle, @NotNull Class<? extends Activity> cls) {
if (!Constant.isLogin) {
activityMap.put(serialNum, new PassData(cls, bundle));
Intent intent = new Intent(fragment.getActivity(), LoginActivity.class);
fragment.startActivityForResult(intent, serialNum);
serialNum++;
} else {
Intent intent = new Intent(fragment.getActivity(),cls);
if (bundle != null) {
intent.putExtra(KEY_DATA, bundle);
}
fragment.startActivity(intent);
}
}
public static class PassData{
public Class<? extends Activity> activityClass;
public Bundle bundle;
PassData(Class<? extends Activity> activityClass, Bundle bundle) {
this.activityClass = activityClass;
this.bundle = bundle;
}
}
public static PassData getPassData(int requestCode){
return activityMap.get(requestCode);
}
public static void handleResultCallback(int requestCode){
activityMap.remove(requestCode);
if (activityMap.size()==0) {
serialNum = 1;
}
}
public static void releaseData(){
activityMap.clear();
serialNum = 1;
}
}
工具类就是根据是否登录进行不同的页面跳转,而且使用activityMap 管理每个源Activity 或Fragment所有的跳转信息,activityMap中保存的key是requestCode,Value是PassData,PassData保存的是目标页和要传递的数据。
既然是activityMap的管理,那么就一定有保存 获取和删除这些方法。
在项目中一定会有在Fragment跳转目标页的情况,所以我把Fragment的逻辑也写进去了。
定义基类
由于登录结果的处理是共同的,所以可以抽出来放到基类里边。
public class BaseActivity extends AppCompatActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null) {
return;
}
String loginData = data.getStringExtra(KEY_LOGIN);
if (!TextUtils.equals(loginData, "from_Login")) {
return;
}
if (resultCode == Activity.RESULT_OK) {
UiInterceptHelper.PassData passData = UiInterceptHelper.getPassData(requestCode);
if (passData != null && passData.activityClass!=null) {
Intent intent = new Intent(this, passData.activityClass);
intent.putExtra(UiInterceptHelper.KEY_DATA, passData.bundle);
startActivity(intent);
UiInterceptHelper.handleResultCallback(requestCode);
}
}
}
}
KEY_LOGIN表示是从登录返回的结果
resultCode==Activity.RESULT_OK表示登录成功
登录成功的时候通过UiInterceptHelper通过requestCode取出要跳转的页面和传递的数据进行页面跳转。
登录页
public class LoginActivity extends AppCompatActivity {
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Constant.isLogin) {
Toast.makeText(LoginActivity.this, "亲,您已经登录了,请不要重复登录!", Toast.LENGTH_LONG).show();
} else {
if (TextUtils.isEmpty(userNameEditTv.getText()) || TextUtils.isEmpty(passwordEditTv.getText())) {
Toast.makeText(LoginActivity.this, "亲,请输入合法的用户名或者密码!", Toast.LENGTH_LONG).show();
return;
}
Constant.isLogin = true;
Toast.makeText(LoginActivity.this, "亲,登录成功!", Toast.LENGTH_LONG).show();
handleLoginSuccess3();
}
}
});
}
private void handleLoginSuccess3(){
Intent intent = new Intent();
intent.putExtra(KEY_LOGIN,"from_Login");
setResult(RESULT_OK, intent);
finish();
}
}
登录页面主要就是处理登录逻辑,登录成功的时候将结果返回去。
使用
MainActivity.java
public class MainActivity extends BaseActivity {
....
private void lookMyGoods() {
Bundle bundle = new Bundle();
bundle.putString(Constant.KEY_MSG, "通过登录传递的产品");
UiInterceptHelper.launchActivityWithLoginForActivity(this, bundle, MyGoodsActivity.class);
}
private void lookMyFavorite() {
Bundle bundle = new Bundle();
bundle.putString(Constant.KEY_MSG, "通过登录传递的收藏");
UiInterceptHelper.launchActivityWithLoginForActivity(this, bundle, MyFavoriteActivity.class);
}
}
MainActivity 的跳转就很简单都是委托给UiInterceptHelper类了。
MyGoodsActivity.java和MyFavoriteActivity.java
public class MyGoodsActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_goods);
Bundle bundle = getIntent().getBundleExtra(UiInterceptHelper.KEY_DATA);
if (bundle != null) {
String msg = bundle.getString(Constant.KEY_MSG);
if (!TextUtils.isEmpty(msg)) {
Toast.makeText(this, "我的产品--》msg="+msg,Toast.LENGTH_LONG).show();
}
}
}
}
public class MyFavoriteActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_favorite);
Bundle bundle = getIntent().getBundleExtra(UiInterceptHelper.KEY_DATA);
if (bundle != null) {
String msg = bundle.getString(Constant.KEY_MSG);
if (!TextUtils.isEmpty(msg)) {
Toast.makeText(this, "我的收藏--》msg="+msg,Toast.LENGTH_LONG).show();
}
}
}
}
MyGoodsActivity 和 MyFavoriteActivity和原来使用的没区别就是接收上个页面传递的数据。
总结
这种方案在第一种的基础上更加抽象了一些,将要处理的跳转逻辑和数据都抽取出来放到一个工具类UiInterceptHelper中,进行集中的维护和管理,高层调用的时候简单方便。另外LoginAcitivity也遵循单一原则了,没有那么多的责任了。
网友评论