英文:
Android App Mouse Pointer Input Not working well on Activity UI Elements
问题
已解决!https://stackoverflow.com/a/63790855/12021422
我正在开发一个Android应用,该应用适用于手机、平板和电视机顶盒。我的应用将需要处理来自触摸、鼠标指针或遥控器的输入。
目前,我的代码能够很好地实现所需的功能,但在处理鼠标输入方面,只在电视机顶盒上出现异常行为。
问题:当应用启动时,遥控器可以轻松导航到“可聚焦”元素,但是指针处的鼠标不能被应用元素检测到。
现在,当鼠标指针移到音量选项并在点击后返回时,应用开始检测鼠标,但在执行某些操作后,它再次从应用界面中失去焦点
,鼠标指针的移动和点击再次变得不被检测到。
请查看以下链接中的视频,以查看应用当前的行为: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">
<!-- 其他控件被省略... -->
</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 {
// MainActivity的代码被省略...
}
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">
<!-- 其他配置被省略... -->
</manifest>
(注意:这只是代码的一部分,根据您的要求,我只提供了翻译后的部分内容。如果需要完整的翻译,请继续提供原始内容。)
英文:
Solved! https://stackoverflow.com/a/63790855/12021422
I am working on an Android App which works on Mobiles, Tabs and TV Boxes. My app will need to handle inputs from Touch, Mouse Pointer or Remote.
Currently, My Code works well to achieve the functionality but there is abnormal behaviour in handling of Mouse inputs only happens on TV Box.
Problem: When the app starts the remote can easily navigate on the focusable
elements
but the mouse at pointer does not get detected by app elements.
Now When a mouse pointer is taken to Volume Option and then comes back with a Click. The app starts detecting mouse but after some Action, it again looses focus
from App UI and motion of the mouse pointer and clicks become undetected again.
Please Watch the Video from Link below to see How the app is currently behaving.
https://jumpshare.com/v/bvyfbqZFWNJfoUsXJbSU
Problem Gist: As the Volume controller is displayed above the app the mouse can make changes on volume tracker and come out after making left-click. The app becomes responsive to hovers and mouse pointer action and when some action is made on the app it again becomes unresponsive.
Some Conditions that App should Follow:
- Minimum SDK 19
- ScrollView
Code
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, 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, 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", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 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, MotionEvent arg1) {
if ((arg1.getAction() == MotionEvent.ACTION_UP)) {
Toast toast = Toast.makeText(getApplicationContext(), "Button 2 Touched", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 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, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
} else {
}
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
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, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 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>
答案1
得分: 0
我在从我的MainActivity中移除getSupportActionBar().hide();
后解决了这个奇怪的问题。
解决方法说明:我发现当应用程序栏未从主题中移除时,应用程序上的鼠标事件开始工作。
我之前为了实现干净的用户界面而隐藏了应用程序栏,但那只是一个增强功能,所以取消隐藏应用程序栏以使其工作。
我希望这对于你遇到的相同独特情况有所帮助。
英文:
I solved this weird Issue after removing get getSupportActionBar().hide();
from my MainActivity.
Solution Description: I found that when the app bar was not removed from the theme the mouse events on the app started working.
I was hiding app bar for clean UI for my use case but that was just an enhancement so unhide the app bar to make it work.
I hope this helps if you are stuck with the same unique case.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论