【Android】使用反射机制优化导航页面

正文

在Android中,页面跳转的实现很简单,无非就是下面的两行代码。

	Intent intent = new Intent(MainActivity.this, TargetActivity.class);
	startActivity(intent);

所谓导航页面,也就是多个承载页面跳转功能的控件的集合罢了,就像这样:

导航页
点击其中的任意一项,都能跳转到一个新的页面。要实现这样的功能,很简单吧!使用列表让数据按需显示,然后为Item设置点击事件不就行了吗?
这么简单谁不会啊

	navAdapter.setOnItemClickListener(new OnItemClickListener() {
		@Override
		public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
			Intent intent = new Intent(MainActivity.this, TargetActivity.class);
            startActivity(intent);
        }
	});

啊,不对,不同的页面显示的数据不一样。还需要传入一个tag,让目标页面根据这个tag加载不同的数据。

	navAdapter.setOnItemClickListener(new OnItemClickListener() {
    	@Override
        public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
        	Intent intent = new Intent(MainActivity.this, TargetActivity.class);
            intent.putExtra("tag","xxx");
            startActivity(intent);
        }
    });
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_target);
        String tag = getIntent().getStringExtra("tag");
        switch (tag) {
            //根据tag做不同的处理...
        }
    }

这是导航时比较常见的一种情况,也就是目标页面的整体布局、功能逻辑基本相同,只有数据或较少功能存在差异,页面可以复用的情况。

那么问题来了
那么问题来了,当目标页面差异较大,不可复用时,应该怎么处理呢?
啊这,不是一样的套路吗?无非就是跳转之前先判断,再跳转呗。

	navAdapter.setOnItemClickListener(new OnItemClickListener() {
		@Override
		public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
			Intent intent = new Intent();
        	switch (data.get(position).getTitle()) {
        		case "主机":
            		intent.setClass(MainActivity.this, TargetActivity.class);
                	break;
            	case "游戏":
                	intent.setClass(MainActivity.this, AnotherActivity.class);
                	break;
            	default:
                	break;
        	}
       		startActivity(intent);
		}
	});

这才写了两个跳转,就已经感觉到代码十分难看了。如果有数十个跳转,试问谁会想写这么一长串的switch块呢?需求再给你改一改,还不得当场去世。

当场去世
那么问题又来了,这里的跳转逻辑其实是一致的,就是先判断,再跳转,那就不能整理成一个便于管理的方法呢?答案是,可以。这里就要请出我们本文的主角——反射机制了。
众所周知,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。
所以如果我把跳转的逻辑封装成一个个命名规范的方法,然后在跳转判断时,借助反射机制调用相应的方法不就可以了吗?就像这样:

1、首先,我们要定制一个协议,或者说规则来约束命名。
2、创建一个SkipHelper类,将跳转各个页面的方法按规则定义。

public class SkipHelper {

    public static void SkipToTargetPage(Context context) {
        Intent intent = new Intent(context, TargetActivity.class);
        context.startActivity(intent);
    }

    public static void SkipToAnotherPage(Context context) {
        Intent intent = new Intent(context, AnotherActivity.class);
        context.startActivity(intent);
    }

}

3、与后端开发人员协调,为数据添加一个新字段pageUrl,这是我们获取对应方法的关键,它的传值必须符合规则

public class NavBean {

    private String title;
    private int imgResId;
    //新增此字段
    private String pageUrl;
    
}

4、修改跳转的方法。首先获取到数据的pageUrl属性,然后根据规则组装成对应的方法名,最后使用反射机制获取方法并调用。

	navAdapter.setOnItemClickListener(new OnItemClickListener() {
    	@Override
        public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
            String methodName = "SkipTo" + data.get(position).getUrl() + "Page";
            try {
            	//反射获取对应跳转方法
                Method method = SkipHelper.class.getMethod(methodName, Context.class);
                //执行方法
                method.invoke(null, MainActivity.this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

5、调整数据,测试成果。

	private void initData() {
        data.add(new NavBean("主机", R.drawable.ic_game2,"Target"));
        data.add(new NavBean("游戏", R.drawable.ic_game,"Target"));
        data.add(new NavBean("音乐", R.drawable.ic_music,"Target"));
        data.add(new NavBean("绘画", R.drawable.ic_draw,"Another"));
        data.add(new NavBean("运动", R.drawable.ic_sport,"Another"));
        data.add(new NavBean("视频", R.drawable.ic_video,"Another"));
        data.add(new NavBean("电影", R.drawable.ic_movie,"Another"));
        data.add(new NavBean("知识", R.drawable.ic_know,"Another"));
    }

结果
大功告成

结语

关于反射,这应该是自我学Java以来,除了加载数据库以外,真正意义上学习和使用了反射机制。啊,这么久了,总算拨云见日,真是太逊了。
关于规则。文中定义的规则看似可有可无,但在实际开发中还是比较重要的,由于业务上跳转到的页面可能不是Android原生页面,还有可能是Web页面、H5页面等等,在处理时会更为复杂,因此规则的定义不可小觑。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值