您的位置:首页 > 移动开发 > Android开发

学习Android之路_活动创建、活动切换及活动数据传递Intent_第三天

2019-01-18 21:58 155 查看

学习Android之路_自学

  • 2.2使用Intent在活动之间穿梭
  • 总结:
  • 先从看得到的入手——探究活动

    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();
    }

    总结:

    今天学习了如果创建活动,以及活动之间的切换及数据传输,这是一个很好的开始,然我了解到如何在各个界面中显示内容及切换。今天还学会了布局,虽然只是一个简单的按钮,但是我觉得美好的界面都是由这些小东西组成的,明天还要继续努力加油!

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: