Android 入门之常见的事件(小白速成2)

Android 入门之常见事件(小白速成2)

接着说基本的组件以及常用的命令啦!

常见的事件及其响应

点击事件

在上一篇中,我们讲了给button添加test方法,使他被点击时能够响应。
而我们也可以选择设置监听器,做到不对xml文件修改,只在java文件中做到对按钮响应的设置,代码如下:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button=findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"button被点击",Toast.LENGTH_SHORT).show();
                v.setX(v.getX()+10);//使每次点击后,按钮向右边移动10个单位
            }
        });
    }

依然是对点击事件的一个简单响应。
这就是对button按钮的动态设置,而上一节中对按钮中添加onclick事件是属于配置方式。

我们也可以将方法放在外面(可复用的方式),方便更多次调用:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button=findViewById(R.id.button);
        button.setOnClickListener(myListener);
    }
    private View.OnClickListener myListener =new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(MainActivity.this,"button被点击",Toast.LENGTH_SHORT).show();
            v.setX(v.getX()+10);
        }
    };

长按事件

button.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Toast.makeText(MainActivity.this,"button被长按",Toast.LENGTH_SHORT).show();
                return false;
            }
        });

返回值是false,表示当前的长按事件响应没有消耗这个事件,所以还可以被别的操作监视器响应。说人话就是:如果这个按钮不仅绑定了长按事件,也绑定的单击事件,那么在我长按之后,也会被判定为单击事件(先输出我长按了按钮,再输出我单击了按钮);但是如果返回值是true,当前的长按响应已经把这个长按行为消耗完,便不会再被单击事件响应了。

滑动事件

滑动事件也叫触摸事件
相比较于长按事件,它也具有布尔类型的返回值,并且多了一个参数 event ,这个event用来记录事件发生现场的情况。(例如单击的坐标位置)

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewGroup viewGroup =findViewById(R.id.layout01);
        final Button button =findViewById(R.id.button);
        viewGroup.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int actionType =event.getAction();
                if(actionType ==MotionEvent.ACTION_DOWN){
                    System.out.println("被按下。。。");
                }else if(actionType ==MotionEvent.ACTION_MOVE){
                    System.out.println("被移动。。。");
                    button.setX(event.getX());
                    button.setY(event.getY());
                }else if(actionType ==MotionEvent.ACTION_UP){
                    System.out.println("被松开。。。");
                }

                return true;
            }
        });

注:在这里我给layout组件取id为layout01,所以可以在这里查找到,当我在layout区域内点击的时候就能有响应,并且使按钮随着鼠标移动而移动。

焦点事件

当一个元素获取到焦点和失去焦点的时候便会触发响应

button.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                System.out.println("焦点事件");
            }
        });

我们可以在模拟器上通过键盘的tab键来选择按钮,让它获得焦点。

键盘事件

三个参数,其中keyCode 代表了每次点击键盘所对应的ascii码。

button.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                System.out.println(keyCode);
                return false;
            }
        });

以上就是基本的事件。

添加动画以及线程阻塞

添加动画事件

//为button1添加动画操作
        Button button1 = findViewById(R.id.button);
        //在水平方向移动
        TranslateAnimation animation =new TranslateAnimation(0,150,0,0);
        animation.setRepeatCount(30);//重复三十次
        animation.setDuration(2000);//完成一次的时间 2s
        button1.setAnimation(animation);

这个操作可以使button1在我们运行模拟器时进行左右移动,TranslateAnimation方法的参数就是横纵坐标的起始位置和终止位置。

线程阻塞

但是我们如果添加另一个按钮 button2 ,并且给 button2 添加动作,在点击button2后就会产生线程阻塞,使button1不能正常移动。
原因:一个视图中的多个view组件运行在同一个UI线程当中,多个view组件的监听器的执行会相互影响。
解决方案:采取多线程
但是多线程不能对组件进行设置,例如修改button显示的值,只有创建view的那个主线程可以修改。
多线程代码如下:

 Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick( final View v) {
                //用post可读性差,维护性差
                
                System.out.println("+++"+Thread.currentThread().getId());

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("线程开始执行。。。");
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("线程执行结束。。。");
                    }
                }).start();

            }
        });

如果要对button2的名字等属性进行修改,可以采用post方法

int sum=10;
v.post(new Runnable() {
                      
    public void run() {
          System.out.println("post开始执行..."+Thread.currentThread().getId());
          TextView view =(TextView)v;
          view.setText(""+10);

    }
});

使用post方法后,post依然是在主线程中执行,执行的顺序是先执行额外的线程,在额外的线程执行结束后,再执行post,因此不会影响别的线程执行。

缺点:可读性差并且维护性差。
所以我们可以选择异步任务(AsyncTask)来解决这个问题。

  private Button button2 = null;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //为button1添加动画操作
        Button button1 = (Button) findViewById(R.id.button);
        TranslateAnimation animation = new TranslateAnimation(0, 150, 0, 0);
        animation.setRepeatCount(30);//重复三十次
        animation.setDuration(2000);//完成一次的时间 2s
        button1.setAnimation(animation);
        button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                new DownloadImageTask().execute();//执行

            }
        });

    }

    private class DownloadImageTask extends AsyncTask<String, Void, Integer> {
        protected Integer doInBackground(String... urls) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int sum = 10;
            return sum;
        }

        protected void onPostExecute(Integer sum) {
            button2.setText(""+sum);
        }
    }

那么这次基本就说这么多啦!!!
参考自:尚学堂android课程

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值