">
当前位置:   article > 正文

2021-10-21 Android-Activity_

一、第一个程序

1. 代码分析

1.1 Manifest.xml

整个项目的配置文件,在程序中定义的所有四大组件都需要在这个文件里注册

<activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

表示对MainActivity活动进行注册

<intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
  • 1
  • 2
  • 3
  • 4
  • 5

表示MainActivity是这个项目的主活动,即手机点击app图标,出来的就是该活动

1.2 MainActivity代码

//继承AppCompatActivity,向下兼容
public class MainActivity extends AppCompatActivity {

    //该方法是活动被创建时必须执行的方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

发现,在MainActivity中,没有HelloWorld字样,但是运行结果显示出了

这是因为,Android程序讲究逻辑和视图分离,因此不推荐在活动中直接编写界面

而是在布局文件中编写界面,然后在活动中引入进来

setContentView(R.layout.activity_main);
  • 1

利用setContentView方法引入activity_main布局

1.3 布局文件

1.4 res目录

  1. 以drawable开头的文件夹都是用来放图片的
  2. 以mipmap开头的文件夹都是用来放应用图标的
  3. 以values开头的文件夹都是用来放字符串、样式、颜色等的
  4. layout文件夹是来放布局文件的
1.4.1 strings.xml
<resources>
    <string name="app_name">My Application</string>
</resources>
  • 1
  • 2
  • 3

定义了一个应用程序名的字符串

引用该字符串的两种方式

  1. 在代码中通过R.string.my_application
  2. 在XML中通过@string/my_application

1.5 build.gradle

gradle使用一种基于groovy的领域特定语言DSL来声明项目设置

摒弃了传统基于XML的各种繁琐配置

1.5.1 外层目录下的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.2"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
1.5.2 app目录下的build.gradle
plugins {
    id 'com.android.application'
}

android {
    compileSdk 30

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 21
        targetSdk 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
plugins {
    id 'com.android.application'
}
  • 1
  • 2
  • 3

应用了一个插件,一般有两种值可选

  1. com.android.application:表示这是一个应用程序模块
  2. com.android.library:表示这是一个库模式,只能作为代码库依附于别的应用程序模块运行

2.日志工具

Log(android.util.Log)

五个方法

  1. Log.v() 繁琐、意义小的日志 verbose级别
  2. Log.d() 调试信息 debug级别
  3. Log.i() 比较重要的数据 info级别
  4. Log.w() 警告信息 warn级别
  5. Log.e() 错误信息 error

二、活动

1. 基本用法

1.1 手动创建活动

  1. 在activitytest包下新建一个Empty Activity

    不要勾选Generate Layout File和Launcher Activity(手动完成)

    Generate Layout File:自动为当前活动创建一个对应的布局文件

    Launcher Activity:将当前活动设置为项目的主活动

    勾选Backwards Compatibility表示会为项目启用向下兼容的模式

    Backwards Compatibility:表示会为项目启用向下兼容的模式

  2. 手动创建一个布局文件

    在res目录下,新建一个目录layout,在该目录下心急啊一个Layout文件

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SLhIwhUA-1634804487230)(C:\Users\wanqi.li\AppData\Roaming\Typora\typora-user-images\image-20211015105646807.png)]

  3. 在布局文件里加button

    <Button
            android:id="@+id/button_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button 1"
            />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    定义唯一标识符

     android:id="@+id/button_1"
    
    • 1

    当前元素的宽度和父元素一样宽

    android:layout_width="match_parent"
    
    • 1

    当前元素的高度刚好能包含元素里面的内容

    android:layout_height="wrap_content"
    
    • 1

    当前元素的文本

    android:text="Button 1"
    
    • 1
  4. 在活动中加载该布局

    public class FirstActivity extends AppCompatAtivity
    {
        //重写onCreate方法
        @Override
        protected void oCreate(Bundle savedInstanceState)
        {
            super.oCreate(savedInstanceState);
            setContentView(R.layout.first_layout);//调用该方法来加载一个布局
            //由于项目中添加的任何资源会在R文件中生成一个相应的资源id,因此只需调用R.layout.first_layout就可以得到id
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  5. 在AndroidManifest文件中注册

    所有的活动都要在AndroidManifest.xml文件中进行注册才能生效

    Android Studio已经自动注册了

  6. 配置程序的主活动

    <activity android:name=".FirstActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

1.2 在活动中使用Toast

Toast是一种提醒方法,在程序中可以使用它将一些短小的信息通知给用户

这些信息会在一段时间后自动消失,不会占用任何屏幕空间

1.2.1 使用
  1. 定义一个弹出Toast的触发点

    <Button
            android:id="@+id/button_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button 1"
            />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  2. onCreate方法

    public class FirstActivity extends AppCompatAtivity
    {
        //重写onCreate方法
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.oCreate(savedInstanceState);
            setContentView(R.layout.first_layout);//加载布局
            //通过id获得按钮
            Button button1=(Button)findViewById(R.id.button_1);//由于findViewById方法返回一个View对象,因为得转型
            //为按钮注册一个监听器
            button1.setOnClickListener(new View.OnClickListener()
                                       {
                                           @Override
                                           public void OnClick(View v)
                                           {
                                               //当点击按钮的时候
                                               
                                               Toast.makeText(FirstActivity.this,"You clicked it",Toast.LENGTH_SHORT).show();
                                               
                                           }
                                       })
           
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    //用静态方法makeText创建出Toast对象,调用show将Toast显示出来
    Toast.makeText(FirstActivity.this,"You clicked it",Toast.LENGTH_SHORT).show();
    //makeText三个参数:
    //1. Context:Toast要求的上下文(活动本身就是一个Context对象)
    //2. Toast显示的文本内容
    //3. Toast显示的时长,有两个内置常量可以选择
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

1.3 在活动中使用Menu

  1. 新建Menu resource file

    res下新建一个menu文件夹,在文件夹下新建Menu resource file

  2. 编写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_item"
              android:title="Remove"/>
    </menu>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  3. 重写onCreateOptionsMenu方法

    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflater(R.menu.main,menu);
        return true;//表示允许创建的菜单显示出来
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    getMenuInflater()方法能得到MenuInflater对象,再调用它的inflate方法,就可以给当前活动创建菜单

    inflate()方法接收两个参数

    第一个参数用于指定我通过哪个资源文件来创建菜单

    第二个参数用于指定我们的菜单项将添加到哪一个Menu对象中

  4. 定义菜单响应事件

    在FirstActivity中重写onOptionsItemSelected方法

    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch(item.getItemId())//获得菜单项的id,以此来判断我们点击了哪个菜单项
        {
            case R.id.add_item:
                Toast.makeText(this,"You cliked add",Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove_item:
                Toast.makeText(this,"You cliked remove",Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

1.4 销毁一个活动

Activity类提供了一个finish()方法,在活动中调用这个方法就可以销毁当前活动

修改按钮监听器中的代码

button1.setOnClickListener(new View.OnClickListener()
                           {
                               @Override 
                               public void onClick(View v)
                               {
                                   finish();
                               }
                           })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.5 使用Intent在活动之间穿梭

Intent是Android程序中各组件之间进行交互的一种重要方式,不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据

1.5.1 使用显式Intent cls
  1. 编辑布局文件second_layout.xml

    <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android
                  android:orientation="vertical"
                  android:layout_width:"match_parent"
                  android:layout_height:"match_parent">
        <botton
                android:id="@+id/button_2"
                android:layout_width:"match_parent"
                android:layout_height:"wrap_content"
                android:text="Button 2"/>
    
    </LinearLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  2. 按钮事件

    Intent(Context packageContext,Class<?> cls)

    该构造函数接收两个参数:

    Context要求提供一个启动活动的上下文

    Class<?>指定想要启动的目标活动

    通过该构造函数,构建出Intent的意图

    button1.setOnClickListener(new View.OnClickListener()
                               {
                                   @Override
                                   public void onClick(View v)
                                   {
                                       Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
                                       startActivity(intent);
                                   }
                               })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    startActivity方法是专门用于启动活动的,接收一个intent参数,将构建好的Intent传入就可以启动活动目标了

1.5.2 使用隐式Intent

隐式Intent不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找到合适的活动去启动。即那些可以相应我么这个隐式Intent的活动

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

只有和同时匹配Intent中指定的和的时候,活动才能响应Intent

此时没有指定category是因为在xml中我们的category是一种默认的category,在调用startActivity方法时,会自动添加

1.5.3 向下一个活动传递数据

Intent提供了一系列putExtra方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要再把这些数据从Intent取出就可以

存数据:

button1.setOnClickListener(new View.OnClickListener()
                           {
                               @Override
                               public void onClick(View v)
                               {
                                   String data="Hello";
                                   Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
                                   intent.putExtra("extra date",data);//键值
                                   startActivity(intent);
                               }
                           })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

取数据:

public class SecondActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_layout);
        Intent intent=getIntent();//通过getIntent方法获取到用于启动SecondActivity的Intent
        String data=intent.getStringExtra("extra_data");//getStringExtra方法用于获取数据
        Log.d("SecondActivity",data);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
1.5.4 返回数据给上一个活动

startActivityForResult方法期望在活动销毁的时候,能够返回一个结果给上一个活动

该方法接收两个参数

第一个参数Intent,第二个参数是请求码,用于在之后的回调中判断数据的来源

button1.setOnClickListener(new View.OnClickListener()
                           {
                               @Override
                               public void onClick(View v)
                               {
                                   Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
                                   startActivityForResult(intent,1);
                               }
                           })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
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 intent=new Intent();
                                   intent.putExtra("data_return","hello");
                                   setResult(RESULT_OK,intent);//专门用于向上一个活动返回数据的
                                   
                                   finish();
                                   
                               }
                           })
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

setResult(RESULT_OK,intent);//专门用于向上一个活动返回数据的

该方法接收两个参数

第一个参数用于向上一个活动返回处理结果,一般只用RESULT_OK或RESULT_CANCELED这两个值

第二个参数则把带有数据的Intent传递回去

我们是使用startActivityForResult方法来启动SecondActivity活动的

因此在SecondActivity被销毁之后会回调上一个活动的onActivityResult方法

因此需要在FirstActivity中重写这个方法来得到返回的数据

@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data)
{
    switch(requestCode)
    {
        case 1://如果是1
            if(resultCode==RESULT_OK)//如果状态ok
            {
                String returndeData=data.getStringExtra("data_return");//取出来
                Log.d("FirstActivity",returnedData);
            }
            break;
        default:
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

onActivityResult(int requestCode,int resultCode,Intent data)三个参数

requestCode:在启动活动时传入的请求码

resultCode:在返回数据时传入的处理结果

intent:携带着返回数据的Intent

问题:如果用户不是通过点击按钮来回到上一个活动,而是按下back键回到上一个活动,这样就没办法发挥数据了

解决:在SecondActivity中重写onBackPressed()来解决

@Override
public void onBackPressed()
{
    Intent intent=new Intent();
    intent.putExtra("data_return","Hello");
    setResult(RESULT_OK,intent);
    finish();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/235964
推荐阅读
相关标签