Android第一行代码-Activity

Posted 钢铁-程序猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android第一行代码-Activity相关的知识,希望对你有一定的参考价值。

android第一行代码

Activity

1、Activity基本用法

一种可以包含用户界面的组件,一个应用可以包含0或多个活动

在创建activity的时候:

  • 1、如果勾选Generate Layout File表示会自动为FirstActivity创建一个对应的布局文件
  • 2、勾选Launcher Activity表示会自动将FirstActivity设置为当前项目的主Activity
  • 3、任何Activity都应该重写onCreate()方法。

2、创建和加载布局

Android程序讲究逻辑和视图分离,最好每一个Activity都能对应一个布局,布局是用来显示页面内容的。

在创建好Layout文件之后,会布局编辑器,窗口左下角有两个切换卡:

  • Design:可视化布局编辑器,在这可以通过拖放的方式编辑布局。
  • Text:通过XML文件的方式编辑布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 1"
        />
</LinearLayout>

上面线性布局中添加了一个Button元素,并在内部增加了几个属性:

  • 1、android:id 给当前的元素定义一个唯一的标识符。
  • 2、在XML中引用一个id,就是用@id/id_name这种语法,如果在XML中定义一个id,则需要使用@+id/id_name这种语法
  • 3、android:layout_width 指定当前元素的宽度。
  • 4、android:layout_height 指定当前元素的高度。warp_content表示当前元素的高度只要能刚好包含里面的内容就行
  • 5、android:text 指定了元素显示的文字内容

右侧工具栏Preview用来预览当前布局

加载布局(在Activity中加载布局)

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //传入布局文件的id
        setContentView(R.layout.first_layout);
    }
}

在setContentView()方法用来给当前的Activity加载布局。一般会传入一个布局文件的id。项目中的任何资源都会在R文件中生成一个相应的资源id。

在AndroidManifest文件中注册(所有的activity都要在AndroidManifest.xml中进行注册)

AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.activitytest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".FirstActivity"></activity>
    </application>

</manifest>

所有的activity都要在AndroidManifest.xml中进行注册才能生效。Activity的声明要放在< application>标签内。这里是通过Activity标签来对Activity进行注册的。

在< activity>标签内,我们使用android:name来指定具体注册哪一个Activity,.FirstActivity是com.example.activitytest.FirstActivity的缩写。因为manifest标签中已经通过package属性制定了程序的包名。所以才可以省略。

配置主Activity(activity标签内部添加标签)

如果不配置主Activity,那么程序就不知道启动哪个Activity。配置主Activity就是要在标签的内部加入标签。并且在这个标签内部添加和

修改后的AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.activitytest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".FirstActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

在Activity中使用Toast

Toast是Android提供的一个很好的提醒方式,可以将一些短小的信息通知给用户,并在一段按后自动消失。

package com.example.activitytest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        //findViewById()这个方法获取在布局文件中定义的元素
        //findViewById方法返回的是一个View对象,我们可以向下转型将其转成Button对象
        Button button1 = findViewById(R.id.button1);
        //通过调用setOnClickListener方法为按钮注册一个监听器
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //makeText静态方法创建一个Toast对象,然后调用show将toast显示出来即可。
                //makeText的三个参数,
                // 第一个参数是Context即Toast要求的上下文,由于活动本身就是一个Context对象,因此这里直接传入FirstActivity.this即可
                //第二个参数是Toast显示的文本内容
                //第三个参数是Toast显示的时长
                Toast.makeText(FirstActivity.this,"You clicked Button 1",Toast.LENGTH_SHORT).show();
            }
        });
    }
}

在活动中使用Menu()

res目录下创建menu目录,在menu文件夹中创建Menu resource file。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/add_item"
        android:title="Add" />
    <item
        android:id="@+id/remove_item"
        android:title="Remove"/>
</menu>

在这里插入图片描述

标签用来创建具体的菜单项,然后通过android:id给这个菜单项指定一个唯一的标识,android:title给菜单项指定一个名称。

package com.example.activitytest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class FirstActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        //findViewById()这个方法获取在布局文件中定义的元素
        //findViewById方法返回的是一个View对象,我们可以向下转型将其转成Button对象
        Button button1 = findViewById(R.id.button1);
        //通过调用setOnClickListener方法为按钮注册一个监听器
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //makeText静态方法创建一个Toast对象,然后调用show将toast显示出来即可。
                //makeText的三个参数,
                // 第一个参数是Context即Toast要求的上下文,由于活动本身就是一个Context对象,因此这里直接传入FirstActivity.this即可
                //第二个参数是Toast显示的文本内容
                //第三个参数是Toast显示的时长
                Toast.makeText(FirstActivity.this,"You clicked Button 1",Toast.LENGTH_SHORT).show();
            }
        });
    }
    
    //重写方法可以使用快捷键Ctrl+O
    //Menu是一个接口
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //Inflater [ɪnf'leɪtər] 打气筒,充气机,网络
        //getMenuInflater()方法可以获得MenuInflater对象
        //然后调用它的inflate()方法就可以给当前活动创建菜单
        //inflate第一个参数指定我们通过哪一个资源文件来创建菜单,这里指定main.xml
        //第二个参数指定我们的菜单项添加到哪一个Menu对象中
        getMenuInflater().inflate(R.menu.main,menu);
        //表示允许将创建的菜单显示出来
        //false表示创建的菜单将无法显示
        return true;
    }

    //定义菜单响应事件
    //MenuItem是一个接口
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.add_item:
                Toast.makeText(this, "You clicked add", Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove_item:
                Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }
}

三、使用Intent在活动之间穿梭

如果有多个活动,在启动器中点击应用的图标只会进入到该应用的主活动。如何跳转其他活动呢?

Intent分为两种:显示Intent和隐式Intent

1、使用显示Intent

创建第二个Activity即SecondActivity,并生成对应的layout文件,AndroidStudio会自动在AndroidManifest中进行注册,由于不是主活动,不需要在AndroidManifest.xml中的activity标签中配置< intent-filter>标签中的内容。一系列操作结束后,如何启动这第二个活动?

Intent [ɪn’tent] 专注、意图
Intent是Android程序中各组件之间进行交互的一个重要的方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间进行传递数据。

Intent一般可被用于启动活动、启动服务以及发送广播等场景。

显示Intent

Intent的多个构造函数的重载:

  • Intent(Context packageContext,Class<?> cls),第一个参数Context要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动活动的目标活动

startActivity()方法是专门用于启动活动的。他接收一个Intent参数,把构建好的Intent传入startActivity()方法就可以启动目标活动。

//在主活动的onCreate函数中添加如下代码即可点击button1按钮启动SecondActivity了。
button1.setOnClickListener(new View.OnClickListener(){
	@Override
	public void onClick(View v){
		//FirstActivity作为上下文,SecondActivity为目标活动
		//那么我们的意图就非常明显了,即在FirstActivity的基础上打开SecondActivity,并通过startActivity来执行
		Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
		startActivity(intent);
	}
})

隐式Intent(不指明具体想要启动哪个活动)

不明确指出我们想要启动哪一个活动,而是指定一系列更为抽象的action和category等信息,然后交给系统去分析这个Intent,并帮我们找出合适的活动去启动。

通过在< activity>标签下配置< intent-filter>的内容,可以指定当前活动能够响应的action和category

如:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.example.activitytest.ACTION_START" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

从上面的配置在AndroidManifest.xml的action可以看出,指明了当前活动可以响应com.example.activitytest.ACTION_START这个action。而< category>标签则包含了一些附加信息,更精确指明了当前活动能够响应的Intent中还可能带有的category,只有< action> < category>中的内容同时能够匹配上Intent中指定的action和category的时候,这个活动才能响应该Intent

比如FirstActivity的onCreate下面的代码就可以启动上面所定义的activity:

button1.setOnClickListener(new View.onClickListener(){
	@Override
	public void onClick(View v){
		//因爲上面xml文件指明了activity的action為com.example.activitytest.ACTION_START
		//创建Intent(意向),要傳入相應參數
		//就會調用相應的activity
		Intent intent = new Intent("com.example.activitytest.ACTION_START");
		startActivity(intent);
	}
})
更多隐式Intent的用法

Intent让多个应用程序之间的功能共享成为可能,比如你打电话,没必要自己去实现一个拨打电话功能,只需要调用系统的拨打电话功能即可。

button1.setOnClickListener(new View.OnClickListener(){
	@Override
	public void onClick(View v){
		//Intent.ACTION_VIEW在Intent类中定义为
		//public static final String ACTION_VIEW = "android.intent.action.VIEW";
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setData(Uri.parse("tel:10086"));
		startActivity(intent);
	}
});

在上面的代码中首先指定了意向的action为Intent.ACTION_VIEW。setData制定了当前正在操作的数据,而这些数据通常都是以字符串的形式传入到Uri.parse()方法中解析产生的。

<activity android:name=".ThirdActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="tel" />
    </intent-filter>
</activity>

如果在Intent中设置了Data,我们可以在中再配置一个标签,用于精确制定当前活动能够响应什么类型的数据。标签中主要可以配置以下内容:

  • 1、andorid:scheme:用于指定数据的协议部分,如上例中的http部分
  • 2、android:host:用于指定数据的主机名部分,如上例中的www.baidu.com
  • 3、android:port:用于指定数据的端口部分,一般紧随在主机名之后
  • 4、android:path:用于制定主机名和端口之后的部分,如一段网址中跟在域名之后的内容
  • 5、andorid:mimeType:用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

只有标签中指定的内容和Intent中携带的Data完全一致时,当前活动才能够响应该Intent

向下一个活动传递数据(放入Intent,从Intent取出)

在启动活动的时候传递数据的思路很简单,Intent中提供了一系列putExtra()方法的重载,可以吧我们想要传递的数据暂存在Intent中,启动另外一个活动的时候,只需要把数据从Intent中再取出即可

例子:
想把FisrtActivity中的一个字符串传递到SecondActivity中。

button1.setOnClickListener(new View.OnClickListener() {
   @Override
    public void onClick(View v) {
        String data = "Hello SecondActivity";
        Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
        intent.putExtra("extra_data",data);
        startActivity(intent);
    }
});

在SecondActivity将传递的数据取出,并打印:

public class SecondActivity extends AppCompatActivity {

	//Bundle主要用于传递数据,它保存的是数据,是以key-value(键值对)的形式存在的
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_layout);
        Intent intent = getIntent();
        String data = intent.getStringExtra("extra_data");
        Log.d("SecondActivity",data);
    }
}

getIntent()用于获取到用于启动SecondActivity的Intent,然后调用getStringExtra()方法来获取传递的数据。

返回数据给上一个活动(startActivityForResult())

Activity中还有一个startActivityForResult()也是用来启动活动的,但是这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。
startActivityForResult方法的两个参数:

  • 1、Intent
  • 2、请求码,用于在之后的回调中判断数据的来源。

例子:
修改FirstActivity中按钮的点击事件

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

        Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
       	
        startActivityForResult(intent,1);
    }
});

startActivityForResult()方法用来启动SecondActivity,请求码只要唯一即可。

SecondActivity中给按钮添加点击事件,并在点击事件中添加返回数据的逻辑。

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_layout);
        Button button2 = (Button)findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                //把数据放入Intent中
                intent.putExtra("data_return","Hello FirstActivity");
                //专门向上一个活动返回处理结果
                setResult(RESULT_OK,intent);
                finish();
            }
        });
    }
}

setResult()方法专门用于向上一个活动返回数据。有两个参数:

  • 第一个参数用于向上一个活动返回处理结果,一般是RESULT_OK或RESULT_CANCELED
  • 第二个为Intent,调用finish()来销毁当前活动。

由于使用startActivityForResult()来启动SecondActivity,在SecondActivity被销毁之后会回调上一个活动的onActivityResult()方法。因此需要在FirstActivity中重写这个方法来得到返回的数据。

@Override
protected void onActivityResult(int requestCode, 以上是关于Android第一行代码-Activity的主要内容,如果未能解决你的问题,请参考以下文章

Android第一行代码学习笔记---手动创建活动

Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段

(Android第一行代码)活动的启动模式

(Android第一行代码实验一)活动的最佳实践

《第一行代码 第二版》Android开发学习笔记 java

Android第一行学习代码笔记四---使用Intent在活动之间穿梭