美文网首页
Android 中的监听和按键处理

Android 中的监听和按键处理

作者: BlueSocks | 来源:发表于2022-11-02 22:06 被阅读0次

    监听

    我们来练习下各种监听。我们在 TextView 上添加了触摸监听,在 Button 上添加了长按监听,在 Spinner 下拉框选项发生变化的时候添加了监听,在 ListView 选中选项时增加了监听。

    xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#F08080"
            android:padding="10dp"
            android:text="触屏监听" />
    
        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:elevation="1dp"
            android:text="长按监听" />
    
        <Spinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#EED2EE"
            android:padding="20dp" />
    
        <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#D1EEEE" />
    </LinearLayout>
    

    Activity

    public class MainActivity extends AppCompatActivity {
        private TextView textview;
        private Button button;
        private Spinner spinner;
        private ListView listview;
    
        private String[] cities;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            setData();//准备要在列表中要显示的数据
            setViews();//获得控件,并在列表中显示数据
            setListeners();//为控件设置监听器
        }
    
        private void setData() {
            cities = new String[]{"北京", "天津", "河北",
                    "黑龙江", "吉林", "辽宁", "内蒙古",
                    "新疆", "西藏", "江苏", "上海"
            };
        }
    
        private void setViews() {
            textview = findViewById(R.id.textView);
            button = findViewById(R.id.button);
            spinner = findViewById(R.id.spinner);
            listview = findViewById(R.id.listview);
    
            //列表和下拉菜单显示城市列表
            //一段神秘的代码...
            ArrayAdapter<String> adapter = null;
            adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, cities);
            listview.setAdapter(adapter);
    
            adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, cities);
            adapter.setDropDownViewResource(android.R.layout.simple_expandable_list_item_1);
            spinner.setAdapter(adapter);
        }
    
        private void setListeners() {
            textview.setOnTouchListener((view, motionEvent) -> {
                switch (motionEvent.getAction()) {
                    //按下
                    case MotionEvent.ACTION_DOWN:
                        Toast.makeText(MainActivity.this, "按下", Toast.LENGTH_SHORT).show();
                        break;
                    //抬起
                    case MotionEvent.ACTION_UP:
                        Toast.makeText(MainActivity.this, "抬起", Toast.LENGTH_SHORT).show();
                        break;
                    //移动
                    case MotionEvent.ACTION_MOVE:
                        //Toast.makeText(MainActivity.this, "移动", Toast.LENGTH_SHORT).show();
                        break;
                }
                return true;
            });
    
            button.setOnLongClickListener(view -> {
                Toast.makeText(MainActivity.this, "长按了按钮", Toast.LENGTH_SHORT).show();
                //返回布尔值true
                return true;
            });
    
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                    Toast.makeText(MainActivity.this, "下标" + i + "城市" + cities[i], Toast.LENGTH_SHORT).show();
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {
                }
            });
    
            listview.setOnItemClickListener((adapterView, view, i, l) -> Toast.makeText(MainActivity.this, "下标" + i + "城市" + cities[i], Toast.LENGTH_SHORT).show());
        }
    }
    

    按键处理

    onKeyDown()

    按键处理表现为使用 Android 设备时操作的物理按钮的响应的处理。

    重写 onKey??() 方法可以处理按钮的事件,该系列方法的参数 int keyCode 表示按下的哪个键,可以匹配 keyEvent 类中的常量进行对比。

    我们可以捕获 Back 键。原理是:当按下 BACK 键时,会被onKeyDown捕获,判断是 BACK 键,则执行相应方法。

    新建一个测试项目,在 MainActivity 中增加如下代码:

    @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            //日志
            Log.d("ONKEYDOWN", "keyCode:" + keyCode);
            //判断其按下的是否为返回键(Back)
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                Toast.makeText(this, "连按2下退出应用程序", Toast.LENGTH_SHORT).show();
            }
            //按照默认方式处理
            return super.onKeyDown(keyCode, event);
        }
    

    可以看到按下返回键时,退出了程序,同时输出日志

    ONKEYDOWN: keyCode:4
    

    由于最后执行了return super.onKeyDown(keyCode, event);,所以按照默认方式退出了
    如果改为return false; 或 return true; 都不会退出程序。

    例子:连按2次退出应用程序的代码

    public class MainActivity extends AppCompatActivity {
        private long lastBackDownTime;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            //日志
            Log.d("ONKEYDOWN", "keyCode:" + keyCode);
            //判断其按下的是否为返回键(Back)
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                //获取当前按下Back键的时间
                long currentBackDownTime = System.currentTimeMillis();
                //与上一次按下Back键的时间对比
                //如果时间差不超过1000ms,判定为连续按下,则退出
                //否则再次提示
                if (currentBackDownTime - lastBackDownTime < 1000) {
                    finish();
                } else {
                    Toast.makeText(this, "连按2下退出应用程序", Toast.LENGTH_SHORT).show();
                    //如果没有退出,则记录本次按下Back键时间,作为下次时间参考
                    lastBackDownTime = currentBackDownTime;
                }
    
                return true;
            }
            //按照默认方式处理
            return super.onKeyDown(keyCode, event);
        }
    }
    

    运行程序,当连续按两次返回键会退出程序,如果只按一次不会。

    onBackPressed()

    onBackPressed()这个方法就是专门用来监听 back 键事件的。所以可以用以下代码完成 按两次返回键退出程序 的功能。

    @Override
        public void onBackPressed() {
            long currentBackDownTime = System.currentTimeMillis();
            if (currentBackDownTime - lastBackDownTime < 1000) {
                finish();
            } else {
                Toast.makeText(this, "连按2下退出应用程序", Toast.LENGTH_SHORT).show();
                lastBackDownTime = currentBackDownTime;
            }
            super.onBackPressed();
        }
    

    Fragment中监听Back返回键

    监听手机上的 Back 键可以在 Activity 中重写onBackPressed方法。

    如果只有1个 Activity 管理多个 Fragment,每个 Fragment 点击 Back 键处理不同事件,可以在 Activity 中重写 onBackPressed 方法,然后区分不同 Fragment 即可。

    因为我的 Fragment 用 tag 进行了区分,区分当前 tag 即可,代码如下:

    @Override
    public void onBackPressed() {
        if(currentTag.equals("xx")) {
            doSomething();
        } else {
            // handle by activity
            super.onBackPressed();
        }
    }
    

    来自:https://juejin.cn/post/7021022292540915720

    相关文章

      网友评论

          本文标题:Android 中的监听和按键处理

          本文链接:https://www.haomeiwen.com/subject/oklstdtx.html