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调用。
总结:
而如果需要Calculator.xml与activity_calculator.java相关联,使用Intent跳转Activity之后,将会正常执行。被Include进activity_main.xml后的Calculator.xml将会关联到MainActivity.java
-
Activity
阅读前文以后,再来理解Activity(活动周期)的含义就较为轻松:
移动应用体验与桌面体验的不同之处在于,用户与应用的互动并不总是在同一位置开始,而是经常以不确定的方式开始。例如,如果您从主屏幕打开电子邮件应用,可能会看到电子邮件列表,如果您通过社交媒体应用启动电子邮件应用,则可能会直接进入电子邮件应用的邮件撰写界面。
要在应用中使用 Activity,您必须在应用的清单中注册关于 Activity 的信息,并且必须适当地管理 Activity 的生命周期。(——摘自文档)
如何在Android Studio(以下简称AS)新建一个空的Activity:
确认好Activity的名称以后,AS将会自动新建两个文件以及会在AndroidMainfest.xml中添加< activity >< /activity > 标签对以声明该Activity:
-
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"的应用):
< action android:name="android.intent.action.SEND" />左图
< action android:name="android.intent.action.CALL" />右图
返回则可以使用按钮调用带有this.finish();的函数, 结束当前Calculator Activity以达到返回的效果。
老师的要求是,点击单选按钮以后用Toast提示当前所选:
恰好本页文档也是这个功能的讲解,整一个舒舒服服了属于是。
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;
}
}
1、在values文件夹下新建一个XML用于存放Array (这里直接复制文档的案例) :
< array-string name="planes_array">是稍后用来查找这个array的名字
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、运行以后可以看到如图 :
与Planets_array一致,继续下一步;
5、为Spinner添加单项响应:
文档中说是需要使用AdapterView.OnItemSelectedListener来实现onItemSelected()的回调方法,但是直接使用的话可能会导致闪退。于是参考了一下老师给的案例发现,使用了OnClickListener接口且继承的是Activity而非初始的AppCompatActivity:
///老师案例中的代码
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、点击测试:
成功!
-
TabHost选项卡
由于文档中只存在TabHost的API介绍,没有找到具体的案例,在网上翻阅资料时找到了一个新建TabHost的教程,但是经过测试后,该Activity一打开的话就会直接闪退。搞了半天才发现AS原来一致在报错:
于是搜索到的解决方法是继承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());
}
在自己项目添加完毕以后,运行一下项目:
成功运行!而且没有错误。但是这个界面的布局就非常奇怪:
于是直接将这个Label去掉就好了:
在AndroidMainfest.XML中,更改Theme标签,如果直接使用android:theme="@android:style/Theme.NoTitleBar"可能会报错,但是发现原本的项目Theme中刚好就存在一个NoActionBar的标签:
试着运行一遍:
成功!