文章目录
刚接触android的一些易忘易忽略操作
⏰ 持续更新。。。最近更新于:2021-07-27
最近重温了一下android基础,打算自己开发一个android的会议软件,以此篇博客来记录这一开始,一起和我重温一下android吧。
这是一篇非零基础android学习的博客,而是一篇android小白的查缺补漏的一篇android的细节补充
此篇文章主要对于一些常规或复杂操作(不常用容易忘记)的记录
就如将大象放进冰箱里一样(将冰箱打开、大象放进冰箱,关上冰箱),下面介绍的一些个人认为有必要记录一下的操作也会像将大象放进冰箱里一样简单
🎉 工具:android studio
🎲 主要基于android7.0或有其他补充
一、在活动中创建菜单
这是本篇文章的第一个操作,原生的菜单可能在开发中不常用,但也可谓是一个知识点呢,看看是如何在一个活动中创建一个菜单的吧。
我尽力将所有步骤简化为放进三步,像冷藏大象一样:
1、在res/menu下创建main.xml文件(打开冰箱)
首先在res目录下新建一个名为menu的目录,再在menu目录下新建一个名为main的Menu resource file。
2、编写菜单布局文件(放入大象)
在我们新建的main.xml中添加如下代码
<menu xmln: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>
这里在布局中创建了一个菜单,菜单里有Add和Remove两个item
3、在activity中重写onCreateOptionsMenu()和onOptionsItemSelected(MenuItem item)方法(关上冰箱)
首先回到我们的主activity中,在activity中重写onCreateOptionsMenu()方法,将menu注册到acitivity上。
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
getMenuInflater().inflate(R.menu.main,menu);
传入了两个参数第一个参数当然是我们事先编辑好的菜单布局xml文件,第二个参数是用于指定我们的菜单项将添加到那个Menu对象中去,这里我们就直接使用重写方法中的menu参数
返回true表示允许菜单显示,false则表示无法显示
这是我们将我们自定义的menu布局注册到了activity中的menu对象里,如果我们想要监听每一个菜单项被选择时发生的动作,我们还需要重写onOptionsItemSelected(MenuItem item)方法。
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.add_item:
Toast.makeTest(this,"you clicked add",Toast.LENGTH_SHORT).show();
break;
case R.id.remove_item:
Toast.makeTest(this,"you clicked remove",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
可以看到下面的运行内容:
看,我们很容易通过三步在活动中创建了一个菜单。
二、使用显示和隐式的Intent(穿梭于活动间)
为啥还要提一下Intent呢,这不是一个最常用的一个东西嘛,但就因为常用并且是拿着一种Intent的使用方法从头用到尾,以至于Intent的其他使用方法就抛在脑后了。
这一节我们就来说说Intent的显示和隐式的几种方法用于活动中:
服务、广播的场景后面陆续补充
,以及用Intent传递数据
0、准备
首先准备两个普通的活动,第一个活动配置了默认启动的活动
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
第二个活动就是一个普通的活动
<activity android:name=".SecondActivity"></activity>
1、最简单的使用方法-使用显示Intent
如何使用Intent使得应用从FirstActivity跳转到SecondActivity,这里我们就在FirstActivity中放置一个按钮并且为按钮绑定一个点击事件,使得点击这个按钮就能够跳转到第二个活动里。代码如下所示:
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//下面代码为显式Intent使用方法
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
首先我们创建一个Intent,并选用构造方法为传入第一个活动
FirstActivity.this为上下文,传入SecondActivity.class为目标活动作为跳转地址,这样的Intent的意图就非常显然了,即从第一个活动为基础打开第二个活动,所以称之为显示Intent。
2、隐晦的使用方法-使用隐式Intent
(1)通常的隐式用法
这里我们的条件和第一种Intent使用的前提一样都有两个活动,并在第一个活动中添加一个按钮用于跳转到第二个活动,但不同的是,此处咱需要让Intent这个意图收敛一点不能让别人一下就能看穿我们的想法,要做一个有小心思的Intent。
这里就需要在AndroidManifest.xml中去配置要跳转到的活动,给他添加包含自定义的action
和category
两个标签,用于标识这个活动可以响应带有指定action和category的Intent,活动二的AndroidManifest如下所示:
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.action.ACTION_START_TEST" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.category.CATEGORY_TEST" />
</intent-filter>
</activity>
自定义的activity用于标识SecondActivity可由含有action值为
com.example.action.ACTION_START_TEST
的Intent启动而自定义的category不是必须的,但他的作用和自定义action相同,可以使得定位条件更加的精细
此时启动SecondActivity的Intent代码应该如下:
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//下面代码为隐式Intent使用方法
Intent intent = new Intent("com.example.action.ACTION_START_TEST"); //指定action
intent.addCategory("com.example.category.CATEGORY_TEST"); //指定categoty
startActivity(intent);
}
});
就如上面的代码所表达的,满足了指定的action和category的Intent就能开启第二个活动。
这里使用的Intent的构造方法是传入一个String类型的action用于指定一个action的名称
addCategory()
方法用来添加一个category
(2)更隐式的用法
对于Intent的简单的隐式使用方法我们已经知道了,但是如果我们想启动别的程序或者系统自带的程序该怎么做呢,我们接下来通过一个需求和案例来了解一下更隐式且更好用的方式是什么样的,它可以用于一个程序调用另外一个程序的某一功能。
**需求:**假如我们自己编写的一个程序需要打开一个网页,这时我们不必自己内置一个浏览器,就可以调用系统的浏览器来打开一个网页:
在第一个活动中添加按钮并绑定事件,实现如下:
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//下面代码为更隐式Intent使用方法
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});
首先我们就如上小节说的那样创建一个指定action为Intent.ACTIOIN_VIEW的Intent,这时android内置的一个action,其常量值为
android.intent.action.VIEW
,并且使用intent设置了一个数据:setData()
方法传入一个Uri对象用于匹配Data符合的intent
这样我们就可以打开手机的浏览器并打开传入的网站了。
如果我们想让我们自己的程序也可以作为一个打开链接的选项,这要如何实现呢
其他代码不变的情况下,这里我们创建第三个活动,并为这个活动设置一个可以action用于标识该活动可以被指定action的Intent启动,我们这里是为了使我们的程序可以在点开连接后与浏览器有相同的选择地位,这里的action与系统浏览器指定的action名称一致,并且设置了一个<data>标签,改标签中指定的内容和Intent中携带的完全一致时,活动才会响应Intent:
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>
这样就实现了一个通过data调用其他应用的intent的小demo,这里我们不仅了解了如何使用Intent调用系统应用,还学习了如何让自己的应用也可以和系统应用公平竞争用户选择权。
对于不同的Intent.ACTION_*与data的组合,还可以调用其他系统应用,例如手机短信、手机电话等
下面是一个呼出手机电话的例子:
button.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ //下面代码为调用电话的方式 Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:120")); startActivity(intent); } });
调用电话的Uri是
tel:120
,不同的程序的uri不同,请根据需要进行查询和使用。
(3)更多<data>标签可配置内容
<data>可配置项 | 描述 |
---|---|
android:scheme | 用于指定数据的协议部分 如:http |
android:host | 用于指定数据的主机名部分 如:www.baidu.com |
android:port | 用于指定数据的端口部分 如:8080 |
android:path | 用于指定主机名和端口之后的部分 如:/list/findAll |
android:mimeTpe | 用于指定可以处理的数据类型 |
3、用Intent传递数据
那么,我们甚至学会了做一个像系统应用一样可以提供给别的程序调用的应用,那别人是怎么将数据传到我们应用的,我们的应用又是怎么接受的呢,原来Intent不仅可以用于启动活动,还可以在启动活动时传递数据。
我们就看一下是怎么操作的吧。
我们就接着上面的SecondActivity那个例子继续来,我们的SecondActivity已经可以通过接受http协议的Data来响应Intent了,但却没有做任何事情(但什么都没有发生),我们就分别的修改一下活动一和活动二的代码:
(1)活动一发送
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//下面代码为活动一种用于发送数据的事件
String data = "hello second activity"; //用于发送给活动二的数据
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
intent.putExtra("extra_data",data);
startActivity(intent);
}
});
上面的代码,除了之前我们用于隐式跳转到活动二的代码外,我们还要使用
putExtra()
来进行数据的传递,putExtra()
方法接受两个参数,第一个参数是一个key,第二个参数就是要传递的数据value
(2)活动二接受
重写onCreate
方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);//设置布局
Intent intent = getIntent(); //获得开启该活动的Intent
String data = intent.getStringExtar("extra_data"); //根据key获得传入的数据
Log.d("extra_data:",data);
}
通过
getIntent()
方法获得启动SecondActivity的Intent,然后调用getStringExtra()
获得键对应的数据值,并打印。
(3)返回数据给上一个活动
上面两个步骤就可以完成了活动之间数据的传递,但是要是想要一个在第二个活动返回到第一个活动时候给第一个活动一个执行结果该怎么做呢,我们再介绍一种用于返回给上一个活动数据的使用方式:
一个活动想要获得跳转至的活动页返回的数据可以使用
startActivityForResult()
方法
startActivityForResult()
方法接受两个参数,一个是用于传递的intent,第二个是请求码,用于在获得返回数据的回调函数中用于判断数据的来源。
还是——在第一个活动中创建一个按钮并绑定事件,使用startActivityForResult()
来进行启动活动二:
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivityForResult(intent,1);
}
});
这里使用
startActivityForResult()
方法来开启活动,只需要保证第二个请求码唯一即可
现在我们要在第二个活动中进行返回结果,这里重写onBackPressed()
方法:当点击返回键时触发
@Override
public void onBackPressed(){
Intent intent = new Intent();
Intent.putExtra("data_return","I am return data");
setResult(RESULT_OK,intent); //返回结果
finish();
}
这里依然使用了Intent用于传递数据,RESULT_OK和RESULT_CANCEL是内置的值
finish()
用于销毁当前的活动
再回到我们第活动一中,重写回调方法onActivityResult()
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
switch(requestCode){ //根据刚开始传入到startActivityForResult()第二个参数的requestCode判断是否是该活动想要得到的结果
case 1:
if(resultCode==RESULT_OK){
String returnedDataa = data.getStringExtra("data_return");
Log.d("returnedData:",returnedData);
}
break;
default:
}
}
以上几个步骤就完成了数据的传递和结果的返回
简要流程:FirstActivity→
startActivityForResult
→SecondActivity→setResult
→FirstActivity→onActivityResult
📘 参考书籍:《第一行代码 android》第二版