学习Android之路_活动创建、活动切换及活动数据传递Intent_第三天
学习Android之路_自学
先从看得到的入手——探究活动
2.1活动
2.1.1活动的基本用法
由于AS在一个工作区间只能打开一个项目,所以需要先关闭当前项目,关闭的方法:导航栏File-Close Project。然后再建一个项目,项目名这边取ActivityTest,包名默认。这次模版需要选择Add No Activity也就是第一个,需要我们自己添加活动(Activity)。点击Finish即可。
先切换到项目模式,进入app/src/main/java/com.erxiao.activitytest目录;
现在右击com.erxiao.activitytest包,选择如下图:
出现如下图,不勾选Generate Layout File 和Launcher Activity这两个选项(如果勾选了Generate Layout File就会自动为FirstActivity创建一个队友的布局文件,勾选Launcher Activity则会将其设置为主活动),Backwards Compatibility为下兼容模式,点击Finish:
添加了之后,AS自动帮我们重写了Activity的onCreate()方法。后面我们需要修改onCreate()方法中的内容。
2.1.2创建和加载布局
最好一个活动都能对应一个布局,现在我们来为第一个活动创建一个布局文件:
右击app/src/main/res目录
New-Directory:
这里需要创建一个文件夹,layout:
在layout目录下右键,选择下图:
弹出一个窗口,名字改成frist_layout,点击Finish:
生成一个文件为frist_layout.xml:
有两种编辑方式,一种是Design可视化界面,一种是Text通过XML文件的方式来编辑的。现在切换到Text下,看到如下代码。
现在我们在代码中添加如下代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button 1" />这里添加了一个Button元素,并在Button元素的内部增加了几个属性。android:id为当前唯一的标识符,使用这个标识符可以在代码中对这个元素进行操作。@+id/button_1 这种写法是在XML文件中定义一个id,如果要引用则使用@id/button_1 少了一个加号,之后是指定了宽度和长度,match_parent 为定义的与父类相同;wrap_content 刚好包含内容就行。android:text 为显示的文本内容。 接下来我们需要重做FirstActivity中的onCreate()方法: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190118215144934.png) 增加上面一行内容,这里调用了setContentView()方法来给当前的活动加载一个布局,方法中使用的是布局文件的id。第二天的时候讲过,项目中添加任何资源都会在R文件中生成一个相应的资源id,因此我们刚才创建的frist_layout.xml布局的id现在已经添加到R文件中了。所以现在只要调用R.layout.frist_layout即可。 ### 2.1.3在AndroidManifest文件中注册 所有活动都要在AndroidManifest.xml中注册才能生效,而FristActivity已经在AndroidManifest中注册过了。但是仅仅注册了还是不能运行,因为没有设置主活动,接下来在标签的内部加入标签,并在这个标签添加主活动的内容,以及活动标题栏的内容android:label:
<activity android:name=".FristActivity" android:label="This is FirstActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>
这样就算完整的写出一个程序,接下来运行一下看看,在界面顶部标题栏显示我们刚才所写的内容,以及界面中编写的按键。
2.1.4在活动中使用Toast
Toast是一种非常好用的提醒方式,这些信息在一段时候后自动消失,并且不会占用屏幕空间,接下来写一下Toast使用方法。
我们就用刚才创建的按键才触发Toast效果,在onCreate()方法中添加如下代码。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.frist_layout); Button button1 = (Button) findViewById(R.id.button_1); button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Toast.makeText(FristActivity.this,"You Clicked Button 1",Toast.LENGTH_LONG).show(); } }); }
这里会提示一个错误移到Button上会显示Cannot resolve symbol Button这个错误,此时我们把光标移到Button上,按下Alt+Enter会出现第二张图那样的,选择第一个Import class即可。
在活动中,可以通过findViewById()方法获取到在布局文件中定义的元素,这里我们传入R.id.button_1,来得到按键的实例,findViewById()返回的是View对象,需要向下转型成Button对象。得到按键实例,我们需要调用setOnClickListener()方法为按键注册一个监听器,如果点击了按钮就会执行监听器中的onClick()方法。所以Toast功能在其中编写。
Toast用法很简单,通过静态方法makeText()创建一个Toast对象,然后调用show()将Toast显示出来即可。makeText()方法的三个参数。第一个是Context,就是Toast要求的上下文,这里直接传入活动本身即可,第二个是显示得内容,第三个是显示的时长,有两个内置的可以选择Toast.LENGTH_SHORT和Toast.LENGTH_LONG。
运行程序后,按下按键会出现如下图所示的提示语:
2.1.5在活动中使用Menu
由于手机屏幕小,所以我们需要使用一种Menu使菜单显示的更灵活,接下来我们就来写下这个灵活的小程序吧。
一样的在res目录下创建menu文件夹,这里就不多说了,不记得的往上翻翻。然后再menu目录上右键,如下图添加一个Menu resource file。
输入名字main,点击OK。
在main.xml中添加如下代码:
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/add_item" android:title="Add"/> <item android:id="@+id/remove_itemm" android:title="Remove"/> </menu>
这里创建了两个菜单项目,定义唯一标识符,以及名称。接着来到FristActivity中重写onCreateOptionsMenu()方法:
public boolean onCreateOptionsMenu(Menu menu){ getMenuInflater().inflate(R.menu.main, menu); return true; }
通过getMenuInflater()方法能够得到MenuInflater对象,再调用它的inflate()方法,就可以在当前活动创建菜单了。这里需要传入R.menu.main。第二个参数用于指定我们的菜单将添加到哪一个Menu对象中,这里直接使用onCreateOptionsMenu()方法直接传入menu参数。返回一个true,表示允许创建的菜单显示出来,如果是false则不显示出来。
接下来写对应菜单按下的功能,在FristActivity中重写onOptionsItemSelected()方法,如下代码所示:
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.add_item: Toast.makeText(FristActivity.this, "You Clicked Add", Toast.LENGTH_LONG).show(); break; case R.id.remove_itemm: Toast.makeText(FristActivity.this, "You Clicked Remove", Toast.LENGTH_LONG).show(); break; } return true; }
运行后如下图:
可以发现右上角多了三个点,那个就是对应的菜单键,按下之后显示Toast内容。
2.1.6销毁一个活动
其实销毁一个活动很简单,Activity提供了一个finish()方法,我们直接调用此方法就可以了:
button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ finish(); } });
效果和手机上的返回按键一样。
2.2使用Intent在活动之间穿梭
什么是Intent?他的作用就是将主活动跳转到其他活动,接下来我们就开始学习这个Intent。
2.2.1使用显式Intent
新创建一个活动,在java/com.erxiao.activitytest包右击New-Activity-Empty Activity,这次我们将名称命名为SecondActivity,并勾选Generate Layout File,创建布局文件,起名为second_layout,但不要勾选Launcher Activity选项。
接下来我们打开second_layout.xml进行布局,添加一个按钮,依旧在LinearLayout中添加按钮Button:
<Button android:id="@+id/button_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button 2" />
SecondActivity的内容保持不变,因为AS自动帮助我们将布局添加到启动方法中,以及AndoridManifest.xml自动帮我们注册上去了。
Intent大致分为两种:显式Intent和隐式Intent,接下来先看下显示Intent怎么使用。
接下来我们直接编辑代码,在FristActivity按钮点击事件中编辑,将按钮事件改成如下:
button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent(FristActivity.this,SecondActivity.class); startActivity(intent); } });
首先我们构建除了一个Intent,传入FristActivity.this作为上下文,传入SecondActivity.class作为目标活动,这样我们的意图就非常明显了,则在FristActivity活动中打开SecondActivity这个活动。然后通过startActivity执行intent。
运行程序,点击按钮跳到SecondActivity这个活动,按下Back键则返回到FristActivity活动。
2.2.2使用隐式Intent
隐式Intent它并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,交给系统去分析这个Intent并帮我们找出合适的活动去打开。
什么叫做合适的活动呢?我们先来打开AndroidManifest.xml,在SecondActivity中添加如下代码:
<activity android:name=".SecondActivity"> <intent-filter> <action android:name="com.erxiao.activitytest.ACTION_START"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
只有和中的内容同时能够匹配上Intent中指定的action和category是,这个活动才能响应该Intent。
接下来修改FristActivity中的按钮事件,代码如下:
button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent("com.erxiao.activitytest.ACTION_START"); startActivity(intent); } });
可以看到这边直接将action的字符串传入进去,表明我们想要打开com.erxiao/activitytest.ACTION_START这个活动,但是为什么没有匹配category呢?因为android.intent.category.DEFAULT是默认的category,在调用startActivity()方法时会自动将这个添加到Intent中去,那么不就两个都匹配成功了么。
每个Intent只能指定一个action,但是可以指定多个category,目前只有一个,现在我们再增加一个category吧。
button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent("com.erxiao.activitytest.ACTION_START"); intent.addCategory("com.erxiao.activitytest.MY_CATEGORY"); startActivity(intent); } });
运行这个修改后的程序,点击按钮后程序崩溃了。第一次遇到程序崩溃,现在我们来看一下问题所在。学会使用logcat界面查看错误日志,我们会看到如下错误:
错误信息提醒我们,没有任何一个活动可以响应我们的Intent,为什么呢?因为刚才在Intent新增了一个category,而SecondActivity的标签中没有声明可以响应这个category,所以就没有活动能响应它了。现在我们在中添加一个category的声明,如下所示:
<activity android:name=".SecondActivity"> <intent-filter> <action android:name="com.erxiao.activitytest.ACTION_START"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="com.erxiao.activitytest.MY_CATEGORY"/> </intent-filter> </activity>
这次我们再运行一下程序,是不是就正常使用了。
2.2.3更多隐式Intent的用法
比如打开一个网页,调用系统的浏览器,修改FristActivity按钮代码,代码如下:
button1.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的action是Intent.ACTION_VIEW,这是一个Android系统内置的动作,其常量值为android.intent.action.VIEW。然后通过Uri.parse()方法,将网址字符串解析成一个Uri对象,再调用Intent的setData()方法将这个Uri对象传递进去。
这边我们创建一个活动,让这个活动也能响应打开网页的Intent。
首先新建一个活动,取名为ThirdActivity,勾选Generate Layout File,布局文件起名为third_layout,然后编辑third_layout.xml,添加如下代码。
<Button android:id="@+id/button_3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button 3" /> 在ThirdActivity的<intent-filter>中配置如下: <activity android:name=".ThirdActivity"> <intent-filter tools:ignore="AppLinkUrlError"> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="http"/> </intent-filter> </activity>
此时运行运行程序出现如下选择,选择浏览器和之前的一样,ActivityTest则是我们刚才创建的活动:
下面我们来调用拨号界面:
button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:10086")); startActivity(intent); } });
然后在data部分指定了协议是tel,号码是10086。
2.2.4向下一个活动传递数据
Intent中提供了一系列putExtra()方法的重载,可以帮我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出就可以了。比如说FristActivity中有一个字符串,现在想把这个字符串传递到SecondActivity中,现在来编写一下FristActivity中按钮的代码:
button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ String data = "Hello SecondActivity"; Intent intent = new Intent(FristActivity.this,SecondActivity.class); intent.putExtra("extra_data",data); startActivity(intent); } });
这里使用了显式Intent的方式来启动SecondActivity,并通过putExtra()方法传递了一个字符串。注意这里putExtra()方法接收两个参数,第一个参数是键,用于后面的Intent取值,第二个参数是要传递的数据。
现在我们编写SecondActivity中将传递的数据取出来,并用日志打印出来,代码如下:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_layout); Intent intent = getIntent(); String data = ((Intent) intent).getStringExtra("extra_data"); Log.d("SecondActivity",data); }
通过getIntent()方法获取用于启动SecondActivity的Intent,然后调用getStringExtra()方法,传入相对应的键值,就可以得到传递来的数据了。字符串用getStringExtra()方法,整型用getIntExtra()方法,布尔型用getBooleanExtra()方法,以此类推。
运行程序,按下按钮,在logcat中查找出打印出来的数据:
2.2.5返回数据给上一个活动
Activity中有一个startActivityForResult()方法是用来启动活动的,同时这个方法在活动销毁时候能够返回一个结果给上一个活动。
我们来修改一下FristActivity按钮事件代码:
button1.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent(FristActivity.this,SecondActivity.class); startActivityForResult(intent,1); } });
这里使用startActivityForResult()方法来启动SecondActivity,请求码只要是一个唯一的值就可以,这里传入了1。接下来写入SecondActivity的按钮注册及事件。并在点击事件中添加返回数据的逻辑,并结束活动,代码如下:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_layout); Button button2 = findViewById(R.id.button_2); button2.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent(); intent.putExtra("data_return","Hello FristActivity"); setResult(RESULT_OK,intent); finish(); } }); }
我们构建了一个Intent来传递数据,然后调用setResult()方法。这个方法是专门用于向上一个活动返回数据。有两个参数,第一个用于向上一个活动返回处理结果,一般使用RESULT_OK或RESULT_CANCELED这两个,第二个则是吧带有数据的Intent传递回去。
由于我们是使用startActivityForResult()方法来启动SecondActivity的,在SecondActivity被销毁之后会回调上一个活动的onActivityResult()方法,因此我们需要的FristActivity中重写onActivityResult()方法,如下:
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { switch (resultCode){ case 1: if(resultCode == RESULT_OK){ String returnedData = data.getStringExtra("data_return"); Log.d("FristActivity",returnedData); } } }
第一个参数,即我们启动活动时的请求码。第二个参数,即我们传入的处理结果。第三个参数,及携带返回数据的Intent。
但是有个问题就是,如果用户使用Back键返回的呢?那么就需要在SecondActivity中重写onBackPressed()方法来解决这个问题了:
public void onBackPressed() { Intent intent = new Intent(); intent.putExtra("data_return","Hello FristActivity"); setResult(RESULT_OK,intent); finish(); }
总结:
今天学习了如果创建活动,以及活动之间的切换及数据传输,这是一个很好的开始,然我了解到如何在各个界面中显示内容及切换。今天还学会了布局,虽然只是一个简单的按钮,但是我觉得美好的界面都是由这些小东西组成的,明天还要继续努力加油!
- Android学习——Intent传递数据
- Android学习——Intent传递复杂数据类型
- Android开发学习之路-回调实现Service向activity传递数据
- Android Activity 之 Intent 数据传递学习笔记
- android基础学习6——intent实现数据传递
- Android学习备忘011——使用Intent传递数据之返回结果
- Android学习之路——Android四大组件之activity(二)数据的传递
- Andoid Intent学习之在各个活动之间传递数据
- android开发学习--------Activity的创建及数据传递f
- Android开发学习之路-回调实现Service向activity传递数据
- Android之使用Intent向下一个活动传递数据
- 记android学习之路----Activity(4)----Activity之间的跳转与数据传递
- android学习杂记(1)--Intent传递对象数据
- Android 使用Intent在活动之间传递数据
- Android学习备忘009——Activity之间用Intent传递数据
- Android学习之路——Android四大组件之activity(二)数据的传递
- 安卓学习第28天:使用Intent在活动之间传递数据以及Activity的生命周期实例
- Android学习日记(yzy):intent传递的多种数据类型
- [Android新手学习笔记05]-如何进行活动Activity之间的跳转以及数据传递
- 学习Android之路_活动的生命周期、启动模式_第三天