Android事件传递

练习心得

  1. 事件传递优先级:listener > view回调 > activity回调,如果在回调环节事件处理方法返回true,则事件被消费,不在向后传递,反之会一直向后传递(* 监听器时间返回true也会向后传递*);如果是继承关系的传递,不会传给父类
  2. 自定义view一定要重写带AttributeSet的构造方法,否则编译时汇报inflateException
  3. 如果activity中重写onKeyDown方法没有调用super.onKeyDown(keyCode, event)复用父类方法,则比如按手机返回键不会触返回上一个activity或者退出应用,所以一定要用super复用父类方法
  4. View或者Activity的回调方法onKeyDown只有硬件键盘事件才会触发响应,软键盘不会触发

代码样例

Activity

/**
 * Created by Rambo
 */
public class MyActivity extends MainActivity {

    private EditText myEditText = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        myEditText = (EditText)findViewById(R.id.myEditText);
        myEditText.setKeyListener(new KeyListener() {
            @Override
            public int getInputType() {
                return 0;
            }

            @Override
            public boolean onKeyDown(View view, Editable editable, int i, KeyEvent keyEvent) {
                // listener的事件消费优先级高于回调,事件会传递给对应View的回调,即便return true也会传递
                Log.v(TAG, "myEditText-KeyListener");
                return false;
            }

            @Override
            public boolean onKeyUp(View view, Editable editable, int i, KeyEvent keyEvent) {
                return false;
            }

            @Override
            public boolean onKeyOther(View view, Editable editable, KeyEvent keyEvent) {
                return false;
            }

            @Override
            public void clearMetaKeyState(View view, Editable editable, int i) {

            }
        });

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // 事件会传递给其父类的onKeyDown方法
        Log.v(TAG, "MyActivity.onKeyDown");
        return false;
    }
} 

自定义View

/**
 * Created by Rambo 
 */

public class MyEditText extends EditText implements Contants {
    public MyEditText(Context context) {
        super(context);
    }

    public MyEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        super.onKeyDown(keyCode, event);
        Log.v(TAG, "MyEditText.onKeyDown");
        // 返回false,事件会传递给包含其的Activity
        return false;
    }
}

上述事件消费方法返回值均为false,所以会进行事件传递,运行结果如下:


事件传递

将MyEditText.onKeyDown的返回值改为true,可以看到事件直接被消费掉了,不会再传递给包含其的Activity,运行结果如下:

事件消费
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android事件传递机制一直都是一个痛点,希望这篇文章能够给你点不一样的 基础知识—>源码分析—>进阶—>应用场...
    李是猴子搬来的救兵阅读 2,880评论 5 13
  • 总结,细化,推演 一、总结 四个事件,三个方法,两套机制 1.1 四个事件 Down Move Up/Cancel...
    剑舞潇湘阅读 1,281评论 -3 19
  • 掌握事件分发传递机制的使用场景,分析各种场景下的事件冲突(表现在点击滑动失效等),开发与扩展自定义控件的功能,同时...
    theFullHorizon阅读 1,294评论 1 0
  • 一.简述 android上所有的事件操作都是基于用户对屏幕的触摸与滑动进行分解,进而对用户不同的操作进行监听;如:...
    梦语少年阅读 501评论 0 4
  • 有些东西在不同领域是相通的,刚开始不懂它、不理解它,只是因为还没到那个可以理解它的层次。android的事件传递。...
    糖兜兜兜阅读 448评论 0 0