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事件传递)