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

    xiaoxiao2021-03-25  92

    转载请注明出处: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的日常应用到的东西全部写到了,如果你是大神,那么请吐槽….如果你是初学者,那么请多照着代码敲一敲。

    转载请注明原文地址: https://ju.6miu.com/read-24840.html

    最新回复(0)