问题描述
已解决! 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>