安卓004事件驱动机制

 Android事件驱动机制

  一般,用户经常会通过界面与应用交互,Android框架采用事件驱动的形式与用户交互,那如何处理用户界面中触发的事件?

可以通过从用户交互的View设置事件监听器的方式来实现对事件的处理,一个事件监听器是View类中一个包含单一回调方法的接口。当注册了监听器的View发生了对应的监听事件时,Android框架就会回调相应的监听方法。

 

   * 常见的用户事件

     点击事件、选择事件、触屏事件、长按事件、按键事件

1.点击事件

单击事件是事件机制中最常见的事件,通过对控件绑定View.OnClickListener 实现单击事件的监听

点击事件四种书写方式

      & 私有类实现方式

      & 匿名内部类实现方式

      & 布局中对控件添加android:onClick

      & Activity实现监听接口

例如:对按钮的事件监听


2.选择事件

 复选事件

   复选事件的监听接口:CompoundButton.OnCheckedChangeListener

   复选控件CheckBox 有两种状态:选中与未选中状态,对复选控件

* 案例:明密文切换

  通过对CheckBox控件的复选监听,实现对EditText内容明密文切换

 单选事件

   单选事件的监听接口:RadioGroup.OnCheckedChangeListener

   RadioButtonRadioGroup组合使用才能实现单选功能

* 案例:选择字符集

  通过对RadioButton控件的选择监听,实现对字符集的选择

下拉列表选择

   下拉事件的监听接口:AdapterView.OnItemSelectedListener

* 案例:城市选择

  通过对Spinner下拉列表监听,实现对城市的选择


3.长按与触屏事件

  长按事件监听接口:View.OnLongClickListener

  触屏事件监听接口:View.OnTouchListener

* 案例:长按图标设置手机桌面壁纸

clearWallpaper :清除桌面壁纸

setWallpaper(BitMap bitmap) :设置桌面壁纸

设置壁纸要添加权限:

<uses-permission android:name="android.permission.SET_WALLPAPER"/>


4.键盘事件

  Activity实现了KeyEvent.backcall接口

  onKeyDown(int keyCode,  KeyEvent event) :当键按下去触发

  onBackPress():当返回键按下去触发  ,Activity的方法

  模拟器常见的按键:

       Back 返回键

       Home 手机屏幕桌面

       Ctrl+F11      切换模拟器横竖屏幕

       F2 手机菜单

       F3           电话面板

       F8           手机网络开关



1.代码:  activity_click.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".ClickEventActivity" >


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:textSize="26sp"
        android:text="点击事件实现" />
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="70dp"
        >
     <Button 
         android:id="@+id/anonymous_btn"
         android:layout_width="0dp" 
         android:layout_height="wrap_content"
         android:layout_weight="1"
         
         android:text="匿名类"
         />   
     <Button 
         android:id="@+id/inner_btn"
         android:layout_width="0dp" 
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:text="私有类"
         />   
     <Button 
         android:id="@+id/xml_btn"
         android:layout_width="0dp" 
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:onClick="byXml"
         android:text="xml"
         />   
      <!--textSize="10sp": 字体大小应该在12 以上  -->   
     <Button 
         android:id="@+id/activity_btn"
         android:layout_width="0dp" 
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:text="Activity"
         android:textSize="14sp"
         />   
        
    </LinearLayout>


</RelativeLayout>




ClickEventActivity.java

package cn.opera.clickevent;


import cn.opera.clickevent.R;
import android.os.Bundle;
import android.app.Activity;
import android.app.Application;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


public class ClickEventActivity extends Activity implements View.OnClickListener {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_click_event);
/**点击事件的四种实现方式
*   1. 匿名内部类
*     :性能最好,但是可读性不强
*   2. 私有类
*     :假如多个控件共享某个监听器
*   3. xml设置onClick属性
*     :书写最简洁,但是与xml布局的耦合度增强了
*   4. Activity实现点击事件接口
*     假如有多个请求,可以通过该方式分销请求
*   

*/
//1. 匿名内部类
Button anonymousBtn=(Button)findViewById(R.id.anonymous_btn);

anonymousBtn.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
/**瞬时显示信息
* context:上下文  
*   分为两种 :
*    整个应用的上下文  :Application的实例 
*    组件级别的上下文 :Activity、Service
*   作用: 引用系统的服务  ,引用系统的资源(图片资源) 
*/
Toast.makeText(ClickEventActivity.this, R.string.anonymous, Toast.LENGTH_SHORT).show();
}
});

//2. 私有类
Button innerBtn=(Button)this.findViewById(R.id.inner_btn);
//设置点击监听事件
innerBtn.setOnClickListener(new MyClickListener());

//3. 对xml按钮控件设置点击监听事件
Button xmlBtn=(Button)findViewById(R.id.xml_btn);
xmlBtn.setOnClickListener(this);

//4. Activity实现点击事件接口
Button activityBtn=(Button)findViewById(R.id.activity_btn);
//设置点击监听事件
activityBtn.setOnClickListener(this);

}
private class MyClickListener implements View.OnClickListener{


@Override
public void onClick(View v) {
//getApplicationContext():引用系统的上下文
Toast.makeText(getApplicationContext(), "私有类", Toast.LENGTH_SHORT).show();
}
}

/**通过布局xml文件的android:onClick属性设置点击监听
* 注意:
*  1. 方法名必须与android:onClick属性值相同,而且是public 、并且要带View输入参数
*  2. 不是所有的控件默认都支持android:onClick属性,
*    比如: Button、ImageView、ImageButton等都支持
*        TextView 默认是不支持android:onClick属性 ,假如要支持 ,需要 设置 android:clickable="true"
*  3. 假如控件即在xml布局中设置android:onClick属性,又对该控件设置了点击监听的方法,如何回调?
*     只调用监听器的方法 ,而xml属性关联的方法不回调

*/
public  void byXml(View v){
Toast.makeText(getApplicationContext(), "XML", Toast.LENGTH_SHORT).show();
}


/**
*  4. Activity实现点击事件接口
*  v:View  :当前操作的控件View
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.activity_btn://假如是Activity的按钮
Toast.makeText(getApplicationContext(), "Activity实现", Toast.LENGTH_SHORT).show();
break;
case R.id.xml_btn://假如点击的是 xml命令按钮
Toast.makeText(getApplicationContext(), "XML+Activity实现", Toast.LENGTH_SHORT).show();
break;
case R.id.anonymous_btn:



default:
break;
}


}




}






2.代码:   activity_event.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_yellow"
    android:orientation="vertical" >


    <!-- 通过CheckBox复选控件实现明密文切换 -->


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >


        <EditText
            android:id="@+id/info_edt"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:inputType="textPassword"
            android:text="android" />


        <CheckBox
            android:id="@+id/checkBox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="明文显示" />
    </LinearLayout>


    <View
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:background="@android:color/darker_gray" />
    <!-- 通过RadioGroup 与RadioButton  单选组  实现字符集的选择 -->


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


        <RadioButton
            android:id="@+id/radio0"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="GBK" />


        <RadioButton
            android:id="@+id/radio1"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="UTF-8" />


        <RadioButton
            android:id="@+id/radio2"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="ISO8859" />
    </RadioGroup>
   <!--android:entries:下拉列表条目     -->
    <Spinner
        android:id="@+id/city_spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/citys"
         />
    
        <View
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        android:background="@android:color/darker_gray" />
    <!-- 通过View的长按 实现 手机壁纸的设置  -->
    <ImageView 
        android:id="@+id/image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/girl1"
        />


</LinearLayout>



EventActivity.java

package cn.itcat.event;


import java.io.IOException;


import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.Toast;


public class EventActivity extends Activity {



@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_event);
//1. 通过CheckBox实现明密文转换
changeInfo();
//2. RadioGroup与RadioButton组合一起使用 ,实现字符集的切换
choiceCharset();
//3. 通过Spinner下拉选择城市
selectCity();
//4. 通过View的长按手机壁纸
setPaper();

}
//4. 通过View的长按手机壁纸
private void setPaper() {
final ImageView image=(ImageView)findViewById(R.id.image);
//对图片控件设置长按监听
image.setOnLongClickListener(new View.OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
System.out.println("onLongClick");
//当长按该图片控件时,设置手机壁纸
try {
clearWallpaper();//清除手机壁纸

/**Bitmap :位图格式的图片文件 ,以像素的形式来描述图片 ,比如 :png、jpg、bmp等都是位图文件
* Drawable :可绘制的对象 : 它的子类有 BitmapDrawable 、ClipDrawable等
*/

// Drawable drawable = getResources().getDrawable(R.drawable.ic_girl1);
// BitmapDrawable bitmapDrawable=(BitmapDrawable) drawable;
// Bitmap bitmap=bitmapDrawable.getBitmap();
// setWallpaper(bitmap);//设置壁纸

// 通过操作的图片控件的前景图片属性来设置壁纸
Drawable drawable = image.getDrawable();//取图片控件的前景属性
BitmapDrawable bitmapDrawable=(BitmapDrawable) drawable;
Bitmap bitmap=bitmapDrawable.getBitmap();
setWallpaper(bitmap);//设置壁纸


} catch (Exception e) {
e.printStackTrace();
}

return true;
}
});

//对图片控件设置触摸监听
image.setOnTouchListener(new View.OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("onTouch");
return false;//返回为真,表示请求已经耗尽(结束),告诉android框架不再继续回调后续的监听方法
            //为假,表示当前请求还没有结束,会继续回调后续的其他监听方法
}
});

//对图片控件设置点击监听
image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("onClick");
}
});
}
//3. 通过Spinner下拉选择城市
private void selectCity() {
final Spinner citySpinner=(Spinner)findViewById(R.id.city_spinner);
citySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {


/**当下拉项被选择时,回调该方法
* parent:Spinner
* view:View :当前操作的下拉项视图
* position: 当前选择的下拉项的数据在Adapter适配器中的位置
* id: 当前选择的下拉项的数据的行号 (id属性)
*/
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
//所选的下拉项的数据显示出来
// String city=citySpinner.getAdapter().getItem(position).toString();
//通过数组资源id来获取数组
String[] citys=getResources().getStringArray(R.array.citys);
System.out.println(getResources().getString(R.string.app_name));
System.out.println(getString(R.string.app_name));
String city=citys[position];



Toast.makeText(getApplicationContext(), city+"数组", Toast.LENGTH_SHORT).show();



}
             //当没有任何选项时,回调该方法, 一般是下拉选择出现异常时回调该方法
@Override
public void onNothingSelected(AdapterView<?> parent) {

}
});

}
//2. RadioGroup与RadioButton组合一起使用 ,实现字符集的切换
private void choiceCharset() {
//引用单选组
RadioGroup radioGroup=(RadioGroup)findViewById(R.id.radioGroup1);
//对单选组设置选择状态改变的监听
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
/**当状态改变,则回调该方法
* group:RadioGroup
* checkedId:当前被选中的RadioButton 按钮控件的资源id
*/

@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {


//通过选中的控件的id 来引用控件
// RadioButton radioButton=(RadioButton)findViewById(checkedId);
// RadioButton radioButton=(RadioButton)EventActivity.this.findViewById(checkedId);
//通过直接的父控件对象group来查找子控件 ,
RadioButton radioButton=(RadioButton)group.findViewById(checkedId);

Toast.makeText(getApplicationContext(), radioButton.getText().toString()+"group",
Toast.LENGTH_SHORT).show();


}
});


}
//1. 通过CheckBox实现明密文转换
private void changeInfo() {
//获取编辑框对象
final EditText infoEdt=(EditText)findViewById(R.id.info_edt);
CheckBox checkBox=(CheckBox)findViewById(R.id.checkBox);
//设置复选框的状态改变的监听
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
/**当复选控件选择状态改变,则回调该方法 ,实现明密文切换
* buttonView:CheckBox
* isChecked:是否选中
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
//把隐藏的编辑框的文本还原为明文
infoEdt.setTransformationMethod(new HideReturnsTransformationMethod());
}else{
//把编辑框的文本以密文显示
infoEdt.setTransformationMethod(new PasswordTransformationMethod());
}

}
});


}

/**当按键按下去 ,回调该方法,该方法 是KeyEvent.Callback 的方法  Activity实现了KeyEvent.Callback接口
* keyCode:按键码  
* event:按键事件
*/
private long currentTime=0;//当前时间
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
System.out.println("按键码"+keyCode);
//返回键的按键码是4  
if(keyCode==4){
if(System.currentTimeMillis()-currentTime>=2000){
System.out.println(System.currentTimeMillis());
Toast.makeText(getApplicationContext(), "在两秒之内,再按一次,退出系统",
Toast.LENGTH_SHORT).show();
currentTime=System.currentTimeMillis();

}else{
finish();//当按下返回键时,销毁该Activity  ,退出系统的方法
}

}
// return super.onKeyDown(keyCode, event);
return true;
}

//当按下返回键,则回调该方法,该方法是Activity的方法
@Override
public void onBackPressed() {
System.out.println("onBackPressed");
// finish();结束,销毁当前的Activity
super.onBackPressed();
}

//当两秒钟之内连续按返回键退出系统     



}




3.代码  

activity_advanced_ui.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bg_yellow"
    tools:context=".AdvanceUIActivity" >
    <LinearLayout 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <!-- TextView 默认不支持onClick方法 ,要支持 ,设置 android:clickable=true -->
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="声音开关"
            android:textSize="20sp"
            android:onClick="setVoice"
            android:clickable="true"
            android:textColor="@color/voice_color_select"
            android:layout_marginRight="10dp"
            />
        <ToggleButton 
            android:id="@+id/voice_toggleBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/voice_picture_select"
            android:textOn=""
            android:textOff=""
            
            />
        
    </LinearLayout>


    <Switch
        android:id="@+id/switch1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="wifi开关" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        
        >
   <!--style="@android:style/Widget.ProgressBar.Horizontal  引用系统的样式 设置控件的样式  : -->
        <ProgressBar
            android:id="@+id/progressBar1"
            style="@android:style/Widget.ProgressBar.Horizontal"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:layout_height="wrap_content" />


        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="add"
            style="@android:style/Widget.Button.Inset"
            android:text="增加" />


    </LinearLayout>
    <!-- 滚屏视图    ScrollView:它是FrameLayout的子类,只能拥有一个直接的子控件,只支持垂直滚屏
    <ScrollView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
             >
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        
        </LinearLayout>
        
        
    </ScrollView>
    
     -->
    <!-- 滚屏视图    HorizontalScrollView:它是FrameLayout的子类,只能拥有一个直接的子控件,只支持水平滚屏 -->
    <HorizontalScrollView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
             >
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        <Button 
            android:layout_width="100dp"
            android:layout_height="80dp"
            android:text="控件"
            />
        
        </LinearLayout>
        
        
 </HorizontalScrollView>
    
    


</LinearLayout>



advancedUi.java

package cn.itcast.advanceui;


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Switch;
import android.widget.Toast;
import android.widget.ToggleButton;


public class AdvanceUIActivity extends Activity {
private ToggleButton mToggleButton;
private ProgressBar mprogressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_advance_ui);

mToggleButton=(ToggleButton)findViewById(R.id.voice_toggleBtn);
//对开关按钮设置状态改变的监听
mToggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
/**当开关按钮状态改变,则回调该方法
* buttonView:ToggleButton
* isChecked: 当前控件的状态
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(getApplicationContext(), isChecked?"声音开":"声音关",
Toast.LENGTH_SHORT).show();
}
});


//2. 滑动开关按钮:
Switch switch1=(Switch) findViewById(R.id.switch1);
switch1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(getApplicationContext(), isChecked?"wifi开":"wifi关",
Toast.LENGTH_SHORT).show();
}
});


//3. 设置进度条

mprogressBar=(ProgressBar)findViewById(R.id.progressBar1);
mprogressBar.setMax(10);//设置进度条的最大值


}
//当按下声音开发的TextView时,回调该方法
public void setVoice(View v){
mToggleButton.toggle();//取反

}
//增加进度值  
public void add(View v){
int currentProgress=mprogressBar.getProgress();//取得当前的进度值
mprogressBar.setProgress(currentProgress+1);//设置进度值

// ScrollView scrollView;


}





}










你可能感兴趣的:(android)