【Android】界面初学详讲(Activity、Intent 过滤器、单选按钮、Spinner、TabHost选项卡)

1,007 阅读5分钟

Android学习历程

Android官方文档

控制外部设备(物联网)

源代码

    <include
        android:id="@+id/calculator"
        layout="@layout/activity_calculator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

在activity_main.xml中使用上述代码标签对,则Include相当于直接复制了一份Calculator的Layout。而与该Layout所关联的activity_calculator.java是无法与activity_main.xml中的calculator.xml相关联的。——也就是说,如果calculator中有一个Button,那么这个Button将不会再与activity_calculator.java有任何联系,而是需要我们在MainActivity.java中重新写入一个函数用于被该Button调用。 2

总结:

而如果需要Calculator.xml与activity_calculator.java相关联,使用Intent跳转Activity之后,将会正常执行。被Include进activity_main.xml后的Calculator.xml将会关联到MainActivity.java



  • Activity

阅读前文以后,再来理解Activity(活动周期)的含义就较为轻松: 1

移动应用体验与桌面体验的不同之处在于,用户与应用的互动并不总是在同一位置开始,而是经常以不确定的方式开始。例如,如果您从主屏幕打开电子邮件应用,可能会看到电子邮件列表,如果您通过社交媒体应用启动电子邮件应用,则可能会直接进入电子邮件应用的邮件撰写界面。

要在应用中使用 Activity,您必须在应用的清单中注册关于 Activity 的信息,并且必须适当地管理 Activity 的生命周期。(——摘自文档
如何在Android Studio(以下简称AS)新建一个空的Activity: 3

确认好Activity的名称以后,AS将会自动新建两个文件以及会在AndroidMainfest.xml中添加< activity >< /activity > 标签对以声明该Activity3

  • Intent 过滤器

Intent 过滤器是 Android 平台的一项非常强大的功能。借助这项功能,您不但可以根据显式请求启动 Activity,还可以根据隐式请求启动 Activity。——摘自文档

以下代码段展示了如何配置一个发送文本数据并接收其他 Activity 的文本数据发送请求的 Activity:

    <activity android:name=".Calculator">
        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="text/plain"/>
        </intent-filter>
    </activity>

<action>指定Activity可以发送数据——也就是说,有了这个为其他Activity响应Intent隐式请求。例如,我需要去往某地,打开手机搜索“地图”便于到达该地。而这里的“搜索'地图'”,相当于Intent隐式请求。而当我搜索出 “高D地图” 或 “百D地图”,说明这两个App的< action android:name="导航" >,从而在“我”发送Intent隐式请求“地图(导航)”时,可以应答。 这也解释了为什么叫做 Intent 过滤器<category>则是设置DEFAULT类型,该类型可以让该Activity能够接收启动请求; <data>表明了该Activity能够发送何种类型的数据。

接下来就是使用Java语言调用Intent过滤器:

public void changeActivity(View view){
	Intent sendIntent = new Intent();
    //sendIntent.setAction(Intent.ACTION_CALL);		//此为左图效果
    sendIntent.setAction(Intent.ACTION_CALL);		//此为右图效果,即刻跳转无需等待~~
    sendIntent.setType("text/plain");
    sendIntent.putExtra(Intent.EXTRA_TEXT,text);
    startActivity(sendIntent);
    //this.finish();		//结束当前Activity
}

由于使用的是action.SEND,所以点击后回询问发送至哪个App(即action android:name="android.intent.action.SEND"的应用):

4 < action android:name="android.intent.action.SEND" />左图 < action android:name="android.intent.action.CALL" />右图

返回则可以使用按钮调用带有this.finish();的函数, 结束当前Calculator Activity以达到返回的效果。



老师的要求是,点击单选按钮以后用Toast提示当前所选: 5 恰好本页文档也是这个功能的讲解,整一个舒舒服服了属于是。

activity_radio_btn.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".radioBtn">

            <RadioGroup
                android:id="@+id/radioGroup"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <RadioButton
                    android:id="@+id/radioButton"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:onClick="onClickRadioBtn"
                    android:text="男" />

                <RadioButton
                    android:id="@+id/radioButton2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:onClick="onClickRadioBtn"
                    android:text="女" />

            </RadioGroup>

</androidx.constraintlayout.widget.ConstraintLayout>

radioBtn.java:

	public void onClickRadioBtn(View view){
        boolean isCheck = ((RadioButton)view).isChecked();

        switch (view.getId()){
            case R.id.radioButton:
                if (isCheck){
                    Toast.makeText(radioBtn.this,"男",Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.radioButton2:
                if(isCheck){
                    Context context = getApplicationContext();
                    CharSequence text = "女";
                    int duration = Toast.LENGTH_SHORT;

                    Toast.makeText(context,text,duration).show();
                    //Toast.makeText().show();		记得 .show()——当时忘记了导致自己找了很久的Bug
                }
                break;
        }
    }

6

1、在values文件夹下新建一个XML用于存放Array (这里直接复制文档的案例)< array-string name="planes_array">是稍后用来查找这个array的名字

7
2、新建一个空的Activity (详见上文) ,命名为spinnerPage: activity_spinnerpage.xml:

<!-- 直接添加在Xml空白处即可-->
		<Spinner
            android:id="@+id/planets_spinner"
            android:layout_width="match_parent"
            android:layout_height="50dp" />
        

3、在spinnerPage.java中,将文档所给的Adapter代码加入到OnCraete()里:
		//setContentView(R.layout.activity_spinner_page);

        Spinner spinner = (Spinner) findViewById(R.id.planets_spinner);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.planes_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

4、运行以后可以看到如图 :

8

与Planets_array一致,继续下一步;


5、为Spinner添加单项响应:

文档中说是需要使用AdapterView.OnItemSelectedListener来实现onItemSelected()的回调方法,但是直接使用的话可能会导致闪退。于是参考了一下老师给的案例发现,使用了OnClickListener接口且继承的是Activity而非初始的AppCompatActivity9

///老师案例中的代码
	private void onTestSpinner() {
		setContentView(R.layout.activity_main_spinner);
		Spinner spinner1 = (Spinner)this.findViewById(R.id.my_Spinner1);
		
		spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
			
			public void onItemSelected(AdapterView<?> arg0, View arg1, int pos, long id) {
				String result = arg0.getItemAtPosition(pos).toString();
				Toast.makeText(MainActivity.this, "选中:"+result, Toast.LENGTH_SHORT).show();
			}
			
			public void onNothingSelected(AdapterView<?> arg0) {
				Toast.makeText(MainActivity.this, "没选中", Toast.LENGTH_SHORT).show();
			}
		});
	}

将案例的代码挪至自己的Spinner项目中发现,打开Activity后可能会闪退,在翻阅网上资料发现导致闪退的原因是spinner.setOnItemClickListener不可以用于Spinner,而是需要使用spinner.setOnItemSelectedListener。完整代码如下:

package com.example.exp_2;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class spinnerPage extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_spinner_page);

        Spinner spinner = (Spinner) findViewById(R.id.planets_spinner);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.planes_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                String result = parent.getItemAtPosition(position).toString();
                Toast.makeText(spinnerPage.this, "选中:"+result, Toast.LENGTH_SHORT).show();
            }
            public void onNothingSelected(AdapterView<?> arg0) {
                Toast.makeText(spinnerPage.this, "没选中", Toast.LENGTH_SHORT).show();
            }
        });

    }
    public void backHome(View view){
        this.finish();
    }
    @Override
    public void onClick(View v) {
    }
}

6、点击测试:

9 成功!



  • TabHost选项卡

由于文档中只存在TabHost的API介绍,没有找到具体的案例,在网上翻阅资料时找到了一个新建TabHost的教程,但是经过测试后,该Activity一打开的话就会直接闪退。搞了半天才发现AS原来一致在报错:

10

11

于是搜索到的解决方法是继承ActivtyGroup

    public class TabDesignActivity extends ActivityGroup{  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            // TODO Auto-generated method stub  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.tab_main);  
              
            mTabHost = (TabHost) findViewById(R.id.tabhost);  
            mTabHost.setup();  
            mTabHost.setup(this.getLocalActivityManager());       
    }  

在自己项目添加完毕以后,运行一下项目:

12

成功运行!而且没有错误。但是这个界面的布局就非常奇怪:

13

于是直接将这个Label去掉就好了: 在AndroidMainfest.XML中,更改Theme标签,如果直接使用android:theme="@android:style/Theme.NoTitleBar"可能会报错,但是发现原本的项目Theme中刚好就存在一个NoActionBar的标签:

15

试着运行一遍:

14

成功!