IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 使用Android事件实现连续两次按下“返回键“退出,长按图片收藏,移动帽子 -> 正文阅读

[移动开发]使用Android事件实现连续两次按下“返回键“退出,长按图片收藏,移动帽子

1 概述

物理按键事件:按下,抬起和长按。
触摸事件:按下,抬起,滑动和双击。

1.1 基于监听的事件处理(setOnTouchListener())

做法是绑定特定的事件监听器

1.2 基于回调的事件处理(onTouchEvent())

做法是重写回调方法。View类事件处理的回调方法如下:

方法

说明

onKeyDown()

按下按键

okKeyLongPress()

长按

onKeyShortCut()

按下键盘快捷键

onKeyUp()

松开按键

onTouchEvent()

触摸

表9-1 View类事件处理的回调方法
对于某些事件,无法采用基于回调的事件处理方式处理,只能采用基于监听的事件处理方式。

2 使用物理按键事件实现连续两次按下"返回键"退出

物理按键

KeyEvent

电源键

KEYCODE_POWER

返回键

KEYCODE_BACK

菜单键

KEYCODE_MENU

Home键

KEYCODE_HOME

查找键

KEYCODE_SEARCH

音量键

KEYCODE_VOLUME_UP

KEYCODE_VOLUME_DOWN

方向键

KEYCODE_DPAD_CENTER

KEYCODE_DPAD_UP

KEYCODE_DPAD_DOWN

KEYCODE_DPAD_LEFT

KEYCODE_DPAD_RIGHT

表9-2 Android设备可用物理按键
KeyDown:
MainActivity.java

public class MainActivity extends AppCompatActivity {
    private long exitTime = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            exit();
            Log.d("MainActivity","return false");
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }
    public void exit() {
        // 计算按键时间差是否大于两秒
        if ((System.currentTimeMillis() - exitTime) > 2000) {
            Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
            exitTime = System.currentTimeMillis();
        } else {
            // 连续按键两次退出
            finish();
            System.exit(0);
        }
    }
}

https://github.com/hanyuhang-hz/android-demos

3 使用触摸屏事件实现长按图片收藏,移动帽子

触摸屏事件:
单击事件:setOnClickListener()
长按事件:setOnLongClickListener()
触摸事件:setOnTouchListener()

LongClick:
MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView imageView = (ImageView) findViewById(R.id.imageView);
        imageView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                registerForContextMenu(v); // 将长按事件注册菜单中
                openContextMenu(v); // 打开菜单
                // 表示用户消耗此事件,现象为收藏菜单显示后一直存在
                return true;
                // 表示系统消耗此事件,现象为收藏菜单显示后立刻消失
                // return false;
            }
        });
    }
    // 创建菜单
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add("收藏");
    }
}

https://github.com/hanyuhang-hz/android-demos

MoveHat
MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);
        final HatView hat = new HatView(MainActivity.this); // 创建并实例化HatView类
        hat.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                hat.bitmapX = event.getX()-10; // 设置帽子显示位置的X坐标
                hat.bitmapY = event.getY()-50; // 设置帽子显示位置的Y坐标
                hat.invalidate(); // 重绘hat组件
                return true;
            }
        });
        relativeLayout.addView(hat);
    }
}

当触摸事件onTouch发生后,会产生一个MotionEvent事件对象,可以通过该对象获取当前的x和y坐标。
HatView.java

public class HatView extends View {
    public float bitmapX; // 帽子显示位置的X坐标
    public float bitmapY; // 帽子显示位置的Y坐标

    public HatView(Context context) {
        super(context);
        bitmapX = 30;
        bitmapY = 0;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.hat);
        Log.d("HatView", "bitmapX: " + bitmapX + " bitmapY: " + bitmapY);
        // 绘制帽子
        canvas.drawBitmap(bitmap, bitmapX, bitmapY, paint);
        if (bitmap.isRecycled()) {
            bitmap.recycle(); // 强制回收图片
        }
    }
}

https://github.com/hanyuhang-hz/android-demos

4 区分触摸事件和单击事件

在Android中,一次用户操作可以被不同的View按次序分别处理,我们将响应了用户的一次UI操作称之为消耗了该事件。对于一个View组件,Android如何区分触摸事件和单击事件呢?
TouchAndClick
MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button= (Button) findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("MainActivity","onClick 单击事件");
            }
        });
        button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction()==MotionEvent.ACTION_DOWN){
                    Log.i("MainActivity","onTouch 按下");
                }else if (event.getAction()==MotionEvent.ACTION_UP){
                    Log.i("MainActivity","onTouch 抬起");
                }
                return false;  // 表示未消耗掉这个事件
                //return true; // 表示消耗掉这个事件
            }
        });
    }
}

未消耗掉这个事件时,单击事件可以获取到,触摸事件优先级高于单击事件:

?消耗掉这个事件时,单击事件不能获取到:

?https://github.com/hanyuhang-hz/android-demos

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-12 00:07:14  更:2022-01-12 00:07:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:40:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码