美文网首页
Android 登录成功后再跳转到目标页(二)

Android 登录成功后再跳转到目标页(二)

作者: 烧伤的火柴 | 来源:发表于2019-12-03 09:58 被阅读0次

    介绍

    上一篇文章中介绍第一种方案,由于种种不足和缺陷,引出了第二种方案。
    第二种方案是通过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也遵循单一原则了,没有那么多的责任了。

    相关文章

      网友评论

          本文标题:Android 登录成功后再跳转到目标页(二)

          本文链接:https://www.haomeiwen.com/subject/taefgctx.html