Android App鼠标指针输入在Activity UI元素上无法正常工作

问题描述

解决https://stackoverflow.com/a/63790855/12021422

我正在开发可在手机,标签和电视盒上使用的Android应用。我的应用程序需要处理来自触摸,鼠标指针或遥控器的输入。

当前,“我的代码”可以很好地实现该功能,但是鼠标输入的处理中存在异常行为,仅在电视盒上发生。

问题:应用启动后,遥控器可以轻松导航到focusable元素上 但是应用程序元素不会检测到指针上的鼠标。 现在,将鼠标指针移至“音量选项”,然后单击以返回。该应用程序开始检测鼠标,但是经过一些操作后,它再次从应用程序UI中松开focus并移动了鼠标指针,并再次检测不到点击。

请观看下面的链接视频,以了解应用程序当前的运行方式。 https://jumpshare.com/v/bvyfbqZFWNJfoUsXJbSU

问题要点:当音量控制器显示在应用程序上方时,鼠标可以在音量跟踪器上进行更改,并在单击鼠标左键后出来。该应用程序会响应悬停和鼠标指针操作,并且在该应用程序上执行某些操作后,它将再次变得无响应。

应用程序应遵循的一些条件:

  • 最低SDK 19
  • ScrollView

代码

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#dad6d6"
    android:orientation="vertical">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">


            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="30sp"
                android:fontFamily="@font/poppinsregular"
                android:gravity="center"
                android:text="Mouse and Remote Input App"
                android:textColor="#000000"
                android:textSize="30sp" />


            <Button
                android:id="@+id/btn1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/buttondesign"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:fontFamily="@font/poppinsregular"
                android:text="Button 1"
                android:textColor="#ffffff"
                android:textSize="20sp"
                android:textStyle="bold" />

            <Button
                android:id="@+id/btn2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10sp"
                android:background="@drawable/buttondesign"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:fontFamily="@font/poppinsregular"
                android:text="Button 2"
                android:textColor="#ffffff"
                android:textSize="20sp"
                android:textStyle="bold" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"

                android:layout_marginTop="20sp"
                android:fontFamily="@font/poppinsregular"
                android:text="Try Switch 1"
                android:textColor="#000000"
                android:textSize="20sp" />

            <Switch
                android:id="@+id/switch1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="2sp"
                android:focusable="true"
                android:focusableInTouchMode="true"

                />


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:fontFamily="@font/poppinsregular"
                android:text="Edit Text 1"
                android:textColor="#000000"
                android:textSize="20sp" />

            <EditText
                android:id="@+id/edittext1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:autofillHints=""
                android:background="@drawable/edittext_design"
                android:ems="5"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:hint="Number"
                android:inputType="number"
                android:textAlignment="center"
                android:textColor="@android:color/black"
                android:textSize="30sp" />


        </LinearLayout>

    </ScrollView>
    </LinearLayout>

MainActivity.java

package com.example.remoteandmouseapp;


import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;


public class MainActivity extends AppCompatActivity {
    LinearLayout root_layout;

    Switch switch1;
    EditText edittext1;
    Button btn1,btn2;


    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }


    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportActionBar().hide();
        getwindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getwindow().getDecorView().setsystemUIVisibility(View.SYstem_UI_FLAG_HIDE_NAVIGATION);
        getwindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        switch1 = (Switch) findViewById(R.id.switch1);

        edittext1 = (EditText) findViewById(R.id.edittext1);


        root_layout = findViewById(R.id.root_layout);


        edittext1.setText("4");


        btn1 = (Button) findViewById(R.id.btn1);
        btn2 = (Button) findViewById(R.id.btn2);

        btn1.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                //textInfo.setText("");
                Toast toast = Toast.makeText(getApplicationContext(),"Button 1 Clicked",Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER,0);
                toast.show();

            }
        });

        btn1.setonTouchListener(new Button.OnTouchListener() {

            @Override
            public boolean onTouch(View v,MotionEvent arg1) {
                if ((arg1.getAction() == MotionEvent.ACTION_UP)) {
                    Toast toast = Toast.makeText(getApplicationContext(),"Button 1 Touched",Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER,0);
                    toast.show();

                }
                return true;
            }
        });

        btn1.setonHoverListener(new View.OnHoverListener() {
            @Override
            public boolean onHover(View v,MotionEvent event) {

                if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
                    btn1.setBackgroundResource(R.drawable.onfoucsbuttondesign);

                }
                if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
                    btn1.setBackgroundResource(R.drawable.buttondesign);

                }

                return true;
            }
        });
        btn1.setonFocuschangelistener(new View.OnFocuschangelistener() {

            @Override
            public void onFocusChange(View v,boolean hasFocus) {

                if (hasFocus) {
                    btn1.setBackgroundResource(R.drawable.onfoucsbuttondesign);
                } else {
                    btn1.setBackgroundResource(R.drawable.buttondesign);
                }
            }
        });


        btn2.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                //textInfo.setText("");
                Toast toast = Toast.makeText(getApplicationContext(),"Button 2 Clicked",0);
                toast.show();

            }
        });

        btn2.setonHoverListener(new View.OnHoverListener() {
            @Override
            public boolean onHover(View v,MotionEvent event) {

                if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
                    btn2.setBackgroundResource(R.drawable.onfoucsbuttondesign);

                }
                if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
                    btn2.setBackgroundResource(R.drawable.buttondesign);
                }

                return true;
            }
        });

        btn2.setonTouchListener(new Button.OnTouchListener() {

            @Override
            public boolean onTouch(View v,"Button 2 Touched",0);
                    toast.show();

                }
                return true;
            }
        });


        btn2.setonFocuschangelistener(new View.OnFocuschangelistener() {

            @Override
            public void onFocusChange(View v,boolean hasFocus) {

                if (hasFocus) {
                    btn2.setBackgroundResource(R.drawable.onfoucsbuttondesign);
                } else {
                    btn2.setBackgroundResource(R.drawable.buttondesign);

                }
            }
        });

        edittext1.addTextChangedListener(new TextWatcher() {

            public void afterTextChanged(Editable s) {
                if (!s.toString().equals("")) {

                    Toast toast = Toast.makeText(getApplicationContext(),"Edit Text Changed to: " + s,0);
                    toast.show();
                } else {

                }
            }

            public void beforeTextChanged(CharSequence s,int start,int count,int after) {
            }

            public void onTextChanged(CharSequence s,int before,int count) {

                // status.setText(""+s);
            }
        });

        edittext1.setonTouchListener(new Button.OnTouchListener() {
            @Override
            public boolean onTouch(View v,MotionEvent arg1) {
                if ((arg1.getAction() == MotionEvent.ACTION_UP)) {

                    edittext1.requestFocus();
                    edittext1.setCursorVisible(true);
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.showSoftInput(edittext1,InputMethodManager.SHOW_IMPLICIT);
                    edittext1.setSelection(edittext1.getText().length());
                }
                return true;
            }
        });


        switch1.setonCheckedchangelistener(new CompoundButton.OnCheckedchangelistener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
                Log.v("Switch State=","" + isChecked);
                Toast toast = Toast.makeText(getApplicationContext(),"Switch Boolean: " + isChecked,0);
                toast.show();
            }
        });


        switch1.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                toggleSwitchOnTap();
            }
        });

        switch1.setonTouchListener(new Button.OnTouchListener() {
            @Override
            public boolean onTouch(View v,MotionEvent arg1) {
                if ((arg1.getAction() == MotionEvent.ACTION_UP)) {
                    toggleSwitchOnTap();
                }
                return true;
            }
        });


    }

    public void toggleSwitchOnTap() {
        if (switch1.isChecked()) {
            switch1.setChecked(false);
        } else {
            switch1.setChecked(true);
        }
    }


}


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.remoteandmouseapp">
    <uses-feature android:name="android.hardware.touchscreen"
        android:required="false" />
    <uses-feature android:name="android.hardware.faketouch"
        android:required="false"
        />
    <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="Testname"
        android:roundIcon="@mipmap/ic_launcher"
        android:hardwareAccelerated="true"
        android:largeHeap="true"
        android:theme="@style/AppTheme"
        >
        <activity android:name=".MainActivity"
            android:label="testname"
            android:configChanges="keyboard|keyboardHidden|navigation"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>



</manifest>

解决方法

从我的MainActivity中删除了getSupportActionBar().hide();后,我解决了这个奇怪的问题。

解决方案说明:我发现当未从主题中删除应用栏时,该应用上的鼠标事件开始起作用。

我为用例隐藏了干净的UI的应用程序栏,但这只是一项增强,因此请取消隐藏应用程序栏以使其正常工作。 如果您坚持使用相同的独特案例,希望对您有所帮助。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...