声明:学习的书籍《Android应用开发揭秘》,这里记录学习该书籍的日志,引用的相关代码与总结描述,没有商业的用途,完全是自我学习的一个记录,刚刚学习不可避免会出现很多问题,若是有错误还请大家多多批评。
一、 按钮(Button)
按钮控件已经在之前的例子学习中使用到,主要的是一个setOnClickListener事件。
二、 菜单(Menu)
一般 Android手机都有menu这个按键来显示相应的菜单,实现菜单效果,需要通过onCreateOptionsMenu来实现,然后对其事件进行相关的监听来实现不同任务,可以通过两种方式来实现:
1. 通过XML布局实现;
实例分析:通过上面两种方式来实现菜单效果,main.xml使用XML布局方式实现,main2.xml使用Menu.add方法实现。
1. 通过XML布局:
首先需要在res目录下建立menu文件夹,并且在该目录下建立menu.xml文件,在该文件中创建需要的菜单。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/about" android:title="关于"/>
<item android:id="@+id/exit" android:title="退出"/>
</menu>
然后对应的Activity01重写onCreateOptionsMenu方法来装载这个menu文件
//创建menu
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = this.getMenuInflater();
//设置menu界面为res/menu/menu.xml
inflater.inflate(R.menu.menu, menu);
return true;
}
最后可以加上对菜单按钮事件的监听
//处理菜单事件
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
//得到当前选中得MenuItem的ID
int item_id = item.getItemId();
switch(item_id){
case R.id.about:
//新建一个Intent对象,Intent的使用参考
Intent intent = new Intent();
//指定intent要启动的类
intent.setClass(Examples_04_13Activity.this, Examples_04_13Activity02.class);
//启动一个新的Activity
startActivity(intent);
//关闭当前的Activity
Examples_04_13Activity.this.finish();
break;
case R.id.exit:
Examples_04_13Activity.this.finish();
break;
}
return true;
}
【扩展点】:关于Intent的理解与使用
Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯。比如说调用startActivity()来启动一个activity,或者由broadcaseIntent()来传递给所有感兴趣的BroadcaseReceiver, 再或者由startService()/bindservice()来启动一个后台的service.所以可以看出来,intent主要是用来启动其他的activity 或者service,所以可以将intent理解成activity之间的粘合剂。
可以参考该文章http://wenku.baidu.com/view/76db47858762caaedd33d452.html
2 通过Menu.add方法:
即在onCreateOptionsMenu方法中通过menu.add方法进行添加,如;
public boolean onCreateOptionsMenu(Menu menu) {
//为menu添加内容
menu.add(0, 0, 0, R.string.ok);
menu.add(0, 0, 1, R.string.back);
return true;
}
实例效果:左图为第一种实现方式,右图为第二种实现方式
三、 对话框(Dialog)
实现对话框效果,主要是使用AlertDialog.Builder类,还可以自定义对话框。
实例关键源码分析:
Dialog dialog = new AlertDialog.Builder(Examples_04_14Activity.this)
.setTitle("登陆提示")//设置标题
.setMessage("这里需要登陆!")//设置内容
.setPositiveButton("确定", //设置确定按钮
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
//点击确定转向登陆框
LayoutInflater factory = LayoutInflater.from(Examples_04_14Activity.this);
//得到自定义对话框
final View DialogView = factory.inflate(R.layout.dialog, null);
AlertDialog dlg = new AlertDialog.Builder(Examples_04_14Activity.this)
.setTitle("登陆框")
.setView(DialogView)//设置自定义对话框的样式
.setPositiveButton("确定", //设置"确定"按钮
new DialogInterface.OnClickListener(){ //设置事件监听
public void onClick(DialogInterface dialog, int whichButton) {
//输入完成后,点击“确定”开始登陆
m_Dialog = ProgressDialog.show(Examples_04_14Activity.this,
"请等待...", "正在为你登录...",true);
new Thread(){
public void run(){
try{
sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
finally{
//登录结束,取消m_Dialog对话框
m_Dialog.dismiss();
}
}
}.start();
}
})
.setNegativeButton("取消", //设置“取消”按钮
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton){
//点击"取消"按钮之后退出程序
Examples_04_14Activity.this.finish();
}
})
.create();//创建
dlg.show();//显示
}
})
.setNeutralButton("退出",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton){
//点击"退出"按钮之后推出程序
Examples_04_14Activity.this.finish();
}
})
.create();//创建按钮
// 显示对话框
dialog.show();
【扩展点】
1. LayoutInflater factory = LayoutInflater.from(Activity01.this);
Inflater英文意思是膨胀。 LayoutInflater的作用类似于 findViewById(),不同点是LayoutInflater是用来找layout文件夹下的xml布局文件,并且实例化!而 findViewById()是找具体某一个xml下的具体 widget控件(如:Button,TextView等)。
补充总结:
(1).一般来讲,我们用LayoutInflater做一件事:inflate。inflate这个方法总共有四种形式,目的都是把xml表述的layout转化为View。
(2).获得LayoutInflater的方法三种:
LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.main, null);
LayoutInflater inflater = LayoutInflater.from(context); (该方法实质就是第一种方法,可参考源代码)
View layout = inflater.inflate(R.layout.main, null);
LayoutInflater inflater = getLayoutInflater();(在Activity中可以使用,实际上是View子类下window的一个函数)
View layout = inflater.inflate(R.layout.main, null);
(3)setContentView和inflate的区别:
public class MyInflate extends Activity{
private TextView tv;
public void OnCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
//tv = (TextView) findViewById(R.id.tv);
LayoutInflater inflate = LayoutInflater.from(this);
View view = inflate.inflate(R.layout.main,null);
setContentView(view);
}
}
上述注释掉的代码和没有注释掉的代码两种情况是相同的。
区别:
setContentView()一旦调用, layout就会立刻显示UI;而inflate只会把Layout形成一个以view类实现成的对象,有需要时再用setContentView(view)显示出来。一般在activity中通过setContentView()将界面显示出来,但是如果在非activity中如何对控件布局设置操作了,这就需要LayoutInflater动态加载。
public View inflate(int Resourece,ViewGroup root)
作用:填充一个新的视图层次结构从指定的XML资源文件中
reSource:View的layout的ID
root: 生成的层次结构的根视图
return 填充的层次结构的根视图。如果参数root提供了,那么root就是根视图;否则填充的XML文件的根就是根视图。
其余几个重载的inflate函数类似。
该区别引用自:http://www.cnblogs.com/sanjinxiong/articles/2125142.html
2. AlertDialog.Builder()的使用
AlertDialog是Dialog的一个直接子类,AlertDialog也是Android系统当中最常用的对话框之一。
一个AlertDialog可以有两个以上的Button,可以对一个AlertDialog设置相应的信息。比如title,massage,setSingleChoiceItems,setPositiveButton,setNegativeButton等等。。。。
但不能直接通过AlertDialog的构造函数来生产一个AlertDialog。研究AlertDialog的源码发现AlertDialog所有的构造方法都是写保护的所以不能通过:AlertDialog alertDialog = new AlertDialog();来得到。只能通过:
AlertDialog.Builder alertDialog =new AlertDialog.Builder(this);
四、 图片视图(imageView)
针对imageVIew对象,通过setImageResource()方法设置要显示图片的资源索引。
实例分析:实现imageView对象,Alpha值的递减。
关键源码:
public class Activity01 extends Activity{
ImageView imageview; //声明ImageView对象
TextView textview;
int image_alpha = 255; //ImageView的alpha值,
Handler mHandler = new Handler();
boolean isrung = false; //控件线程
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
isrung = true;
//获得ImageView的对象
imageview = (ImageView) this.findViewById(R.id.ImageView01);
textview = (TextView) this.findViewById(R.id.TextView01);
//设置imageview的图片资源。同样可以再xml布局中像下面这样写
//android:src="@drawable/logo"
imageview.setImageResource(R.drawable.logo);
//设置imageview的Alpha值
imageview.setAlpha(image_alpha);
//开启一个线程来让Alpha值递减
new Thread(new Runnable() {
public void run(){
while (isrung){
try{
Thread.sleep(200);
//更新Alpha值
updateAlpha();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();
//接受消息之后更新imageview视图
mHandler = new Handler() {
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
imageview.setAlpha(image_alpha);
textview.setText("现在alpha值是:"+Integer.toString(image_alpha));
//更新
imageview.invalidate();
}
};
}
public void updateAlpha(){
if (image_alpha - 7 >= 0){
image_alpha -= 7;
}else{
image_alpha = 0;
isrung = false;
}
//发送需要更新imageview视图的消息
mHandler.sendMessage(mHandler.obtainMessage());
}
}
【扩展点】Handler的使用
handler类允许你发送消息和处理线程消息队列中的消息及runnable对象。handler实例都是与一个线程和该线程的消息队列一起使用,一旦创建了一个新的handler实例,系统就把该实例与一个线程和该线程的消息队列捆绑起来,这将可以发送消息和runnable对象给该消息队列,并在消息队列出口处处理它们。
handler类有两种主要用途:1。按照时间计划,在未来某时刻,对处理一个消息或执行某个runnable实例。2。把一个对另外线程对象的操作请求放入消息队列中,从而避免线程间冲突。
时间类消息通过如下方法使用: post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long)
methods. post之类函数可以传输一个runnable对象给消息队列,并在到达消息队列后被调用。sendmessage之类函数可以传送一个包含数据的message对象,该message对象可以被Handler类的handleMessage(Message) 方法所处理。
post之类函数和sendmessage之类的函数都可以指定消息的执行时机,是立即执行、稍后一段时间执行,还是在某个确定时刻执行。这可以用来实现超时、消息或其他时间相关的操作。
当一个进程启动时,主线程独立执行一个消息队列,该队列管理着应用顶层的对象(如:activities、broadcast receivers等等)和所有创建的窗口。你可以创建自己的一个线程,并通过handler来与主线程进行通信。这可以通过在新的线程中调用主线程的handler的post和sendmessage操作来实现。
一、图片按钮(ImageButton)
ImageButton对象通过setImageDrawable()方法设置显示图片。
基础控件差不多就学习到这里了,下面是一些效果的实现。
学习到P92页