自学Android之Activity:(四)使用Intent在Activity中跳转和传值(下)

转载请注明出处:http://blog.csdn.net/cc_xz/article/details/61205788
前言:

上一篇学习了使用Intent在Activity间进行跳转,以及在跳转的时候进行传值,这些只使用了很少一部分的Intent功能,而本篇我们将继续深入学习Intent的一些其他功能。

在本篇中,你将了解到:
1.隐式跳转Intent。
2.通过Intent打开其他APP。
3.通过Intent跳转至其他Activity后,关闭该Activity时返回数据。
4.通过Intent发送Bundle类型的数据。

准备工作:

首先我们要创建两个Activity,以及他们的Layout,再到Layout中添加需要使用到的组件,代码如下:
MainActivity的Layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/TextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:text="这是主活动" />

    <Button
        android:id="@+id/ButtonIntentHide"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="隐式跳转" />

    <Button
        android:id="@+id/ButtonIntentHttp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开浏览器" />

    <Button
        android:id="@+id/ButtonIntentReturnData"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="返回数据" />
</LinearLayout>

MainActivity:

public class MainActivity extends AppCompatActivity {
    private String TAG = "来自于MainActivity";
    private Button mButtonIntentHide, mButtonIntentHttp, mButtonIntentReturnData;
    private TextView mTextView;

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

        mButtonIntentHide = (Button) findViewById(R.id.ButtonIntentHide);
        mButtonIntentHttp = (Button) findViewById(R.id.ButtonIntentHttp);
        mButtonIntentReturnData = (Button) findViewById(R.id.ButtonIntentReturnData);
        mTextView = (TextView) findViewById(R.id.TextView);

        mButtonIntentHide.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        mButtonIntentHttp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        mButtonIntentReturnData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }
}

TwoActivity的Layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:text="这是第二个Activity" />

    <Button
        android:id="@+id/ButtonIntentReturn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="返回第一个Activity" />
</LinearLayout>

TwoActivity:

public class TwoActivity extends AppCompatActivity {
    private Button mButtonIntentReturn;

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

        mButtonIntentReturn = (Button) findViewById(R.id.ButtonIntentReturn);
        mButtonIntentReturn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }
}

在TextView组件中新添了三个属性,其中marginBottom是从本组件为中心,向下增加10dp的距离。即把下面的组件再往下挤10dp。marginTop同理,是以本组件为中心,往上填补出10dp。gravity是这个组件居中显示。实现效果如下:
这里写图片描述
除此之外以上的代码在之前的文章中都讲解过了,这里便不再复述了。

隐式Intent跳转:

在前一篇的学习中Intent跳转的方式,我们一般称之为显式Intent,很容易理解,我们明确的设定了跳转的源Activity和目标Activity,而隐式Intent,则是通过在AndroidManifest.xml中的Intent过滤器(intent-filter)来对不同的Activity进行标记,从而进行跳转。我想你可能感觉到了,这种方式比较繁琐,根本没有显式Intent使用起来方便(知道类名就可以了,对吧?),这是因为,隐式Intent常常被应用在不同APP之间的跳转。
你想一想,你使用一些程序的时候,在登录时,可以选择通过QQ、微信进行登录,那你使用的程序为什么能打开QQ或微信呢?使用显式Intent通过类名指定?这….不太可能吧?
现在你需要通过前面的知识来创建两个Activity,并且打开AndroidManifest.xml,并在第二个Activity中添加以下代码:

        <activity android:name=".TwoActivity">
            <intent-filter>
                <action android:name="ACTION_START"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.MY_CATEGORY"/>
            </intent-filter>
        </activity>

现在来解释一下,第二行标签名很容易理解,就是创建一个Intent的过滤器,第三行是给这个Activity设置一个名称,在代码中使用过滤器时会使用到。第四行是当我们在代码中找到这个过滤器时,设置了一种过滤方式,即如果使用了隐式Intent,但是没有过滤出合适的Activity,就反馈跳转失败。第五行是我们将使用到的,通过这行来确定究竟要往哪里跳转。

现在来到MainActivity中,在mButtonIntentHide的监听器中添加如下代码:

        mButtonIntentHide.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("ACTION_START");
                intent.addCategory("android.intent.category.MY_CATEGORY");
                startActivity(intent);
            }
        });

这次初始化Intent的参数变成了我们在AndroidManifest.xml对第二个Activity定义的action标签中的内容。即通过此名称,来确定Intent要使用哪个过滤器。然后通过addCategory添加过滤器,即:通过“ACTION_START”找到TwoActivity,然后通过android.intent.category.MY_CATEGORY得知需要执行什么操作,这里是Intent跳转,而MY_CATEGORY是一个自定义名称。
接着到TwoActivity的mButtonIntentReturn的监听器中添加一行代码:

finish();

这行代码的作用是销毁当前的Activity。此时的效果为:

这里写图片描述

打开特定网址:
如果你掌握了隐式Intent跳转,那么相信通过Intent打开浏览器也是很简单的事情,代码如下:

        mButtonIntentHttp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("http://www.baidu.com"));
                startActivity(intent);
            }
        });

这里Intent的参数变成Intent自带的一个参数,它的值为:

public static final String ACTION_VIEW = "android.intent.action.VIEW";

我们可以把它理解为,这是Android系统自带的过滤器,通过这个过滤器我们可以打开Android中的其他应用。而具体打开哪个应用,则是通过setData()中的参数来决定。
这里写图片描述
通过源码我们可以看到,setData()接收一个Uri的类型(统一资源标识符,注意不是Url),那么我们怎么获得一个Uri类型参数呢?就是通过Uri.pares(),通过这个方法我们可以把一个字符串转换成Uri参数。
例如,我们希望打开浏览器,则是http开头,后面是网址。如果希望拨打电话,则是tel开头,后面是电话号码。这里只演示如何打开我们希望看到的网站,打开其他程序的方式都很类型,你可以在网上查看相关教程。
效果如下:

这里写图片描述

返回Activity时获得数据:

如果我们通过源Activity跳转至目标Activity后,用户经过一些操作,仍会回到源Activity中,并且可能还需要带回一些数据,这个时候你可以通过前面所讲的内容完成这个需求,即:在目标Activity中创建Intent,并且给予Intent赋值。这样确实可以实现,不过下面我们要了解的是,直接在源Activity中定义,在返回时会收到某值,并且通过特定的方法来处理这个值。MainActivity中代码如下:

        mButtonIntentReturnData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, TwoActivity.class);
                startActivityForResult(intent, 10);
            }
        });

可以看出,确实只是启动Intent的方法不同了,并且除了Intent以外,还接受一个int类型的Key值。这很容易理解,而Key值的作用,请继续往下看。TwoActivity中的代码如下:

        mButtonIntentReturn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.putExtra("ReturnData", "我觉得你叫第一个Activity更好听");
                setResult(RESULT_OK, intent);
                finish();
            }
        });

你发现了什么?使用Intent的方式变成了setResult(),并且这个方法还接受一个奇怪的参数,我们之前并没有定义这个变量,哦..那肯定是系统自带的变量了,这里你可以使用这个变量来确定你返回的Key值,也可以自己定义int类型的变量作为Key值。
如果你把finish();注释掉再运行程序你会发现什么?根本没有返回到第一个Activity。这是因为startActivityForResult()和setResult()是配套使用的,你并不能使用startActivity()来返回,因为那样MainActivity根本不会收到Key值,startActivityForResult()也就没有意义了。
不过这个时候你可能觉得这样做很繁琐,而且没有什么可以提高处理效率的代码发生,前面所说的10的Key值也没有被应用。不过通过下面的代码,你应该就了解了,下面是MainActivity的代码:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 10:
                if (resultCode == -1) {
                    mTextView.setText(data.getStringExtra("ReturnData"));
                }
                break;
        }
    }

我们将重写一个叫onActivityResult的接口,这个接口在你使用了startActivityForResult()后就会被监听。它给了你三个参数,第一个参数requestCode是在startActivityForResult()中定义的Key值,它用来判断出第三个参数data是由哪个Activity反馈回来的(你可能使用多个startActivityForResult())。而第二个参数resultCode则是在TwoActivity中定义的Key值,用于确定当前的data是由TwoActivity中的哪个Intent发送的反馈(可能有多个)。
当你知道三个参数的作用,上面的代码就很好理解了,首先通过switch判断,来使用requestCode确定源Activity。再通过if判断resultCode是源Activity中哪个Intent。看到这里我想你可以理解了,在TwoActivity中使用的RESULT_OK变量,它的值就是-1。
后面就是把接收到的Intent的值收到,并且赋值给TextView。实现的效果如下:
这里写图片描述

传值Bundle类型的参数:

你可能会发现通过Intent传值是使用键值对的方式传递的,也就是Key值+Value之间相互绑定,通过Key值的判断来取出Value数据,而Bundle也是使用这种方式。
那么你可能要问了,既然我已经掌握了使用Intent传值,那么为什么还要学习Bundle传值呢?
这是因为,由于Intent的传值功能是封装了Bundle,所以使用起来更方便,但是缺点是并不能传递对象。而Bundle虽然可以把对象存储起来,但是其本身并不能在多个Activity或者类中传递。这时候就需要通过Intent配合Bundle来一起使用了。
概况的说:Intent旨在数据传递,bundle旨在存取数据,当然intent也提供一部分数据的存取,但比起bundle就显得不专业,不灵活。
首先来看MainActivity中的代码:

        mButtonIntentReturnData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, TwoActivity.class);
                Bundle bundle = new Bundle();
                bundle.putInt("BundleKey", 99);
                intent.putExtra("IntentKey", bundle);
                startActivityForResult(intent, 10);
            }
        });

可以看到,首先我们创建了一个Bundle的对象,并且使用putInt()存储了一个int类型的值。你可以自己通过Android Stuido的方法浏览功能查看Bundle都可以存储哪些类型的数据。接着Bundle将作为一个参数被放到了Intent中。
这个时候如果你看了Bundle都可以存储哪些数据后可能会发现,并没有找到存储某对象的方法,这是因为,如果要将对象存储到Bundle中,是需要将对象序列化,然后传递序列化值,从而实现的对象传递。此处不表。
然后TwoActivity中的代码如下:

        mButtonIntentReturn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle bundle = getIntent().getBundleExtra("IntentKey");
                int value = bundle.getInt("BundleKey", 1);
                value = value * value;
                Intent intent = new Intent();
                intent.putExtra("ReturnData", "我觉得你叫第一个Activity更好听" + value);
                setResult(RESULT_OK, intent);
                finish();
            }
        });

我们首先通过getIntent()将Bundle取出,然后再通过Key值获取到里面存放的int类型数据,并且存放到一个int变量中。接着对这个值进行处理(….别吐槽我相乘处理….),然后在作为参数放到Intent中,接着返回。
实现效果如下:
这里写图片描述
后记:

相对前面的文章,本篇的篇幅较长,不过个人认为写的也比较细致,基本也通过两篇将Intent的日常应用到的东西全部写到了,如果你是大神,那么请吐槽….如果你是初学者,那么请多照着代码敲一敲。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值