iOS和Android对比系列(二):页面跳转和传参

iOS和Android对比系列(二):页面跳转和传参

[TOC]

iOS

跳转页面方式

  • UIViewController
    • present: - (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
    • dismiss: - (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
  • UINavigationController
    • push: - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
    • pop:
      • - (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated;: 返回到上一个页面
      • - (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;: 返回到指定页面
      • - (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;: 返回到根控制器
  • UITabBarController: 系统自己处理,也可自己手动选中
    • @property(nonatomic) NSUInteger selectedIndex;

页面传递参数

正向传递: 在 .h 文件中设置需要传递的参数

@interface MHConfirmOrderVC : KindergartenBase
@property (nonatomic, strong) ProductObject *product;
@end

注意:正向传递的参数在init方法中获取不到的,在loadView中以及后续的生命周期中可以获取到

反向传递:

方法一:使用代理(协议)

例子:

  • MHMessageListVC 正向传递参数给 MHMessageDetailVC
  • MHMessageDetailVC 反向传递参数给 MHMessageListVC

MHMessageListVC 代码

@interface MHMessageListVC ()<MHMessageDetailVCDelegate>
// ......
@end

@implementation MHMessageListVC

// ......

// 正向传递参数和跳转控制器
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    MHMessageCellLayout *cellLayout = [self.viewModel.dataSource objectAtIndex:indexPath.section];

    MHMessageDetailVC *vc = [[MHMessageDetailVC alloc] init];
    vc.index = indexPath.section; // 传递参数
    vc.delegate = self; // 设置代理
    [self.navigationController pushViewController:vc animated:YES]; // 跳转控制器
}

// 接受反向传递的参数结果
- (void)messageDetailDidLook:(NSInteger)index {
    // ......
}

@end

MHMessageDetailVC 代码

// .h 文件
@protocol MHMessageDetailVCDelegate <NSObject>
@optional
/// 消息已读
- (void)messageDetailDidLook:(NSInteger)index;
@end

@interface MHMessageDetailVC : MHBaseViewController

/// 操作的索引
@property (nonatomic, assign) NSInteger index;
/// 代理
@property (nonatomic, weak, nullable) id<MHMessageDetailVCDelegate> delegate;

@end

// .m 文件
@implementation MHMessageDetailVC

// ......

// 在 viewDidLoad 方法只是一个示例,根据实际情况调用
- (void)viewDidLoad {
    [super viewDidLoad];

    // 反向传递参数,和参数访问
    if (self.delegate && [self.delegate respondsToSelector:@selector(messageDetailDidLook:)]) {
        [self.delegate messageDetailDidLook:_index];
    }
}

@end

方法二:遍历控制器进行设置

思路是获取到当前的控制器栈,然后进行遍历,找到目标控制器,然后进行处理,例子如下:

UIViewController *popToController = nil;
NSArray *controllers = self.navigationController.viewControllers;
for (UIViewController *controller in controllers) {
  if ([NSStringFromClass([controller class]) isEqualToString:@"MHNewWebViewVC"]) {
      popToController = controller;
      break;
  }
}
if (popToController) {
  // 刷新页面
  if ([popToController isKindOfClass:[MHNewWebViewVC class]]) {
      MHNewWebViewVC *popVC = (MHNewWebViewVC *)popToController;
      [popVC reloadWebView]; // 这里除了刷新页面,还可以传递参数(修改属性的值),调用方法等等
  }
  [self.navigationController popToViewController:popToController animated:YES];
} else {
    // ..... 父类方法
}

Android

Activity跳转页面和传参,使用 Intent

格式:

Intent intent = new Intent(当前Activity.this, 目标.class);
startActivity(intent);

跳转页面(不传递参数)

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

跳转页面 (传递简单的参数) putExtra()

使用IntentputExtra() 方法

Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("key", "value");
startActivity(intent);

目标LoginActivityonCreate()方法中获取

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        Log.e(TAG, "onCreate -- " );
        String value = getIntent().getStringExtra("key");
        Log.e(TAG, "getIntent 结果 : " + value );
    }

打印结果:

E/LoginActivity: getIntent 结果 : value

注意:putget值类型需要对应

跳转页面 (传递复杂的参数) BundleputSerializable()

使用 BundleputSerializable()

// 1、自定义的类,实现 Serializable 接口
public class VipService implements Serializable {
    private Long productId;
    private String productName;

    public Long getProductId() {
        return productId;
    }

    public void setProductId(Long productId) {
        this.productId = productId;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }
}

// 2、跳转传参
VipService vipService = new VipService();
vipService.setProductId((long) 100);
vipService.setProductName("测试商品");

Bundle bundle = new Bundle();
bundle.putSerializable("vipKey", vipService);

Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("key", "value");
intent.putExtras(bundle); // 传递自定义类对象
startActivity(intent);

// 3、获取传递的参数
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_login);

   Log.e(TAG, "onCreate -- " );
   String value = getIntent().getStringExtra("key");
   Log.e(TAG, "getIntent 结果 : " + value );

   VipService vipService = (VipService) getIntent().getSerializableExtra("vipKey");
   Log.e(TAG, "vipService - productId : " + vipService.getProductId());
   Log.e(TAG, "vipService - productName : " + vipService.getProductName());
}

打印结果:

E/LoginActivity: getIntent 结果 : value
    vipService - productId : 100
    vipService - productName : 测试商品

跳转页面 (获取结果)

  • 使用方法 startActivityForResult()
  • 监听结果方法 onActivityResult()
  • 两个code: 请求requestCode和结果resultCode

例子:

// 1、使用  startActivityForResult() 方法进行跳转 activity, MainActivity 跳转到 LoginActivity 
VipService vipService = new VipService();
vipService.setProductId((long) 100);
vipService.setProductName("测试商品");

Bundle bundle = new Bundle();
bundle.putSerializable("vipKey", vipService);

Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("key", "value");
intent.putExtras(bundle); // 传递自定义类对象
//  startActivity(intent);
startActivityForResult(intent, LoginActivity.REQUEST_CODE); // 需要获取返回结果

// 2、监听返回结果
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
   super.onActivityResult(requestCode, resultCode, data);
   if (requestCode == LoginActivity.REQUEST_CODE) {
       if (resultCode == LoginActivity.RESULT_CODE) {
           String name = data.getStringExtra("name");
           String desc = data.getStringExtra("desc");

           Log.e(TAG, "接受到页面传参啦 ---- ");
           Log.e(TAG, "name=" + name);
           Log.e(TAG, "desc=" + desc);
       }
   }
}

// 3、请求码和返回码
public static int REQUEST_CODE = 100;
public static int RESULT_CODE = 1000;

// 4、LoginActivity 返回的时候 向 MainActivity 传递参数
Intent intent = new Intent ();
intent.putExtra("name", "返回啦");
intent.putExtra("desc", "页面传参描述");
setResult(RESULT_CODE, intent);
finish();

打印结果:

E/MainActivity: 接受到页面传参啦 ---- 
    name=返回啦
    desc=页面传参描述

对比

  • 正向传递参数的获取:
    • iOS 需要在 loadView 方法中以及之后的生命周期方法中都可以获取到,一般是viewDidLoad
    • Android 需要在 onCreate() 方法中获取
  • 反向传递参数:
    • iOS使用代理协议,后者进行遍历
    • Android使用 startActivityForResult()

iOS传递简单或对象都是和控制器UIViewController挂钩的
Android传递参数都是通过Intent,自定义的类对象还需要使用Bundle传递;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容