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

介绍

上一篇文章中介绍第一种方案,由于种种不足和缺陷,引出了第二种方案。
第二种方案是通过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 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 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 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 activityClass;
        public Bundle bundle;

        PassData(Class 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 登录成功后再跳转到目标页(二))