zoukankan      html  css  js  c++  java
  • android事件处理之基于监听

    Android提供了了两种事件处理方式:基于回调和基于监听。

    基于监听:

    监听涉及事件源,事件,事件监听器。用注册监听器的方法将某个监听器注册到事件源上,就可以对发生在事件源上的时间进行监听。

    最简单的的一个例子:单击按钮改变文本框里的文字。

    界面布局:activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <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"
        tools:context="com.example.zjlyyq.shijianchuli.MainActivity">
    
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="还没有任何操作"
            android:id="@+id/et1"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="按钮1"
                android:id="@+id/bt1"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="按钮2"
                android:id="@+id/bt2"/>
        </LinearLayout>
    </LinearLayout>

    MainActivity:

    package com.example.zjlyyq.shijianchuli;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button bt1 = (Button)findViewById(R.id.bt1);
            Button bt2= (Button)findViewById(R.id.bt2);
            //为按钮绑定监听器
            bt1.setOnClickListener(new MyClickListener());
            bt2.setOnClickListener(new MyClickListener());
        }
        //定义一个单击事件的监听器
        class MyClickListener implements View.OnClickListener{
            @Override
            public void onClick(View v) {
                EditText et1 = (EditText)findViewById(R.id.et1);
                et1.setText("bt1被单击了");
            }
        }
    }

    注:以上程序采用内部类的形式。 

    事件由系统自动生成事件对象,事件对象会作为参数传给在事件源上注册的事件监听器。在上面的程序中,并没有事件对象,这是因为事件源触发的事件足够简单,无需封装事件对象,也就没有将数据对象传入监听器。但在更复杂的事件中,例如:键盘事件,触屏事件,包含更多的信息,Android会将时间信息封装成XxxEvent对象。并将对象作为参数传给监听器。

    下面看个复杂点的例子:控制飞机移动

    由于几乎不需要界面布局,该游戏直接使用一个PlaneView作为Activity显示的内容,并未该PlaneView增加触摸监听器即可。

    PlaneView:

    package com.example.zjlyyq.shijianchuli;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.view.View;
    
    /**
     * Created by zjlyyq on 2016/12/10.
     */
    public class PlaneView extends View {
        public float currentX;
        public float currentY;
        public Bitmap plane;
        public PlaneView(Context context) {
            super(context);
            //定义飞机
            plane = BitmapFactory.decodeResource(context.getResources(),R.drawable.plane);
            setFocusable(true);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //创建画笔
            Paint p = new Paint();
            //绘制飞机
            canvas.drawBitmap(plane,currentX,currentY,p);
        }
    }

    MainActivity:

    package com.example.zjlyyq.shijianchuli;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.DisplayMetrics;
    import android.view.Display;
    import android.view.KeyEvent;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.Button;
    import android.widget.EditText;
    
    public class MainActivity extends AppCompatActivity {
        private int speed = 10;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //去掉窗口标题
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            //全屏显示
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
            final PlaneView planeView = new PlaneView(this);
            setContentView(planeView);
    
            //获取窗口管理器
            WindowManager windowManager = getWindowManager();
            Display display = windowManager.getDefaultDisplay();
            DisplayMetrics metrics = new DisplayMetrics();
            //获取屏幕宽和高
            display.getMetrics(metrics);
            //设置飞机初始位置
            planeView.currentX = metrics.widthPixels/2;
            planeView.currentY = metrics.heightPixels - 40;
            //为planeView组件的键盘事件绑定监听器
            planeView.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    switch (event.getKeyCode()){
                        //控制飞机下移
                        case KeyEvent.KEYCODE_PAGE_DOWN:
                            planeView.currentY += speed;
                            break;
                        //控制飞机上移
                        case KeyEvent.KEYCODE_PAGE_UP:
                            planeView.currentY -= speed;
                            break;
                    }
                    //通知palneView组件重绘
                    planeView.invalidate();
                    return true;
                }
            });
            //为planeView组件的触屏事件绑定监听器
            planeView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    float x,y;
                    //获得触屏事件的位置
                    x = event.getX();
                    y = event.getY();
                    planeView.currentY = y;
                    planeView.currentX = x;
                    //通知palneView组件重绘
                    planeView.invalidate();
                    return true;
                }
            });
        }
    }

    这个程序监听器采用匿名内部类的形式,并传入了MotionEvent对象。

  • 相关阅读:
    学习认识Spring原理
    JavaScript
    JSP----九大内置对象
    人到底可以有怎样的意志力,人到底可能有怎样的发挥潜力? ----问自己
    将web项目打成war包部署在tomcat步骤
    微信企业公众号开发之回调模式
    eclipse/myeclipse 中的一些常用的快捷键
    mycelipse中关于编码的配置
    Ext学习系列(1)初识Ext
    AngularJs编写指令
  • 原文地址:https://www.cnblogs.com/zjlyyq/p/6155514.html
Copyright © 2011-2022 走看看