Samsung键盘无法与SearchView一起使用的退格键不起作用。

huangapple 未分类评论53阅读模式
标题翻译

Samsung keyboard backspace not working with SearchView

问题

在我的安卓应用中使用SearchView时,三星设备上使用三星键盘的用户无法使用退格按钮。三星键盘中的退格按钮在EditText和其他任何输入视图上的效果都很好,但在SearchView上却不起作用。我尝试过在用户按下退格键的时候检测并手动删除一个字母,但这也没有起作用。这是三星键盘的问题吗?我该如何解决这个问题?

英文翻译

When using SearchView in my android app, Samsung devices users with samsung keyboard only can't use the backspace button.
Backspace button in samsung keyboard is working fine with EditText and any other input view, except SearchView.
I have tried to detect when the user press the backspace key code and remove one letter manualy, but not working also.
Is it a problem with Samsung keyboard? How can I overcome this problem?

答案1

得分: 0

我知道这是一篇旧帖子,但我刚遇到了相同的问题,所以我会贴出我的解决方案。问题是由于 SearchView 使用了扩展的 EditText,覆盖了 onKeyPreIme 方法,但没有传递 KeyEvent.KEYCODE_BACK 事件。解决方案并不完全安全,因为我必须重写了一个受限 API,但这不应该是问题。

解决方案使用了 androidx 库的版本,但可以根据旧的 appcompat 库进行编辑。

首先,我们创建一个名为 MySearchViewSearchAutoComplete 的类,该类覆盖了内部静态类 androidx.appcompat.widget.SearchView.SearchAutoComplete。该类重写了 onKeyPreIme 方法,当需要时,拦截 KeyEvent.KEYCODE_BACK 事件,将其替换为 KeyEvent.KEYCODE_DEL 事件,并直接发送到编辑框中。

以下是代码:

package com.example.widget.search;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;

@SuppressLint("RestrictedApi")
public class MySearchViewSearchAutoComplete extends androidx.appcompat.widget.SearchView.SearchAutoComplete {
    boolean _isNonTouch;
    boolean _isIgnore;

    public MySearchViewSearchAutoComplete(Context context) {
        super(context);
        init(context);
    }

    public MySearchViewSearchAutoComplete(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MySearchViewSearchAutoComplete(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {
        _isNonTouch = context.getResources().getConfiguration().touchscreen == android.content.res.Configuration.TOUCHSCREEN_NOTOUCH;
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (_isNonTouch && keyCode == KeyEvent.KEYCODE_BACK) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                _isIgnore = getSelectionStart() == 0 && getSelectionEnd() == 0;
            }
            if (!_isIgnore) {
                event = new KeyEvent(event.getDownTime(), event.getEventTime(), event.getAction(), KeyEvent.KEYCODE_DEL, event.getRepeatCount(), event.getMetaState(), event.getDeviceId(), event.getScanCode(), event.getFlags(), event.getSource());
                dispatchKeyEvent(event);
                return true;
            }
        }
        return super.onKeyPreIme(keyCode, event);
    }
}

然后,我们重写 abc_search_view 布局,使用上面扩展的类。我们只需更改 EditText 类为我们上面扩展的类。创建一个名为 abc_search_view.xml 的布局文件。以下是代码:

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

    <!-- ... 其他布局元素 ... -->

    <LinearLayout
        android:id="@+id/search_edit_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="8dip"
        android:layout_marginRight="8dip"
        android:layout_weight="1"
        android:layoutDirection="locale"
        android:orientation="horizontal">

        <!-- ... 其他布局元素 ... -->

        <view
            android:id="@+id/search_src_text"
            class="com.example.widget.search.MySearchViewSearchAutoComplete"
            android:layout_width="0dp"
            android:layout_height="36dip"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:background="@null"
            android:dropDownAnchor="@id/search_edit_frame"
            android:dropDownHeight="wrap_content"
            android:dropDownHorizontalOffset="0dip"
            android:dropDownVerticalOffset="0dip"
            android:ellipsize="end"
            android:imeOptions="actionSearch"
            android:inputType="text|textAutoComplete|textNoSuggestions"
            android:paddingLeft="@dimen/abc_dropdownitem_text_padding_left"
            android:paddingRight="@dimen/abc_dropdownitem_text_padding_right"
            android:singleLine="true" />

        <!-- ... 其他布局元素 ... -->

    </LinearLayout>

    <!-- ... 其他布局元素 ... -->

</LinearLayout>

至此,应该就可以了。

英文翻译

I know this is old post, but I just had the same issue,so I will post my solution. The issue is caused by SearchView using an extended EditText that overrides onKeyPreIme, and does not pass KeyEvent.KEYCODE_BACK events.<br>
The solution I used, is not entirely safe, as I have to overide a RestrictedAPI, but it shouldn't be an issue.<br>
The solution uses the androidx library version, but can be edited for the older appcompat library.<p>
First we create a class MySearchViewSearchAutoComplete that overrides the internal static androidx.appcompat.widget.SearchView.SearchAutoComplete class. This class overrides onKeyPreIme, and when needed, intercepts KeyEvent.KEYCODE_BACK events, swaps them for KeyEvent.KEYCODE_DEL events, and dispatches them directly to the EditBox. </p>
Here is the code;

package com.example.widget.search;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;

@SuppressLint(&quot;RestrictedApi&quot;)
public class MySearchViewSearchAutoComplete extends androidx.appcompat.widget.SearchView.SearchAutoComplete
{
	boolean _isNonTouch;
	boolean _isIgnore;

	public MySearchViewSearchAutoComplete(Context context)
	{
		super(context);
		init(context);
	}

	public MySearchViewSearchAutoComplete(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		init(context);
	}

	public MySearchViewSearchAutoComplete(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
		init(context);
	}

	private void init(Context context)
	{
		_isNonTouch = context.getResources().getConfiguration().touchscreen == android.content.res.Configuration.TOUCHSCREEN_NOTOUCH;
	}

	@Override
	public boolean onKeyPreIme(int keyCode, KeyEvent event)
	{
		if (_isNonTouch &amp;&amp; keyCode == KeyEvent.KEYCODE_BACK)
		{
			if (event.getAction() == KeyEvent.ACTION_DOWN) // on ActionUp it may already be empty, but we should treat it as not empty
			{
				_isIgnore = getSelectionStart() == 0 &amp;&amp; getSelectionEnd() == 0;
			}
			if (!_isIgnore)
			{
				event = new KeyEvent(event.getDownTime(), event.getEventTime(), event.getAction(), KeyEvent.KEYCODE_DEL, event.getRepeatCount(), event.getMetaState(), event.getDeviceId(), event.getScanCode(), event.getFlags(), event.getSource());
				dispatchKeyEvent(event);
				return true;
			}
		}
		return super.onKeyPreIme(keyCode, event);
	}
}

Then we override the abc_search_view layout to use this above class. We use the original source code, only changing the EditText class to our above-extended class. Create a layout file called abc_search_view.xml Here is the code;

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;&lt;!--
    /*
     * Copyright (C) 2014 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    --&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/search_bar&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;horizontal&quot;&gt;

    &lt;!-- This is actually used for the badge icon *or* the badge label (or neither) --&gt;
    &lt;TextView
        android:id=&quot;@+id/search_badge&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_marginBottom=&quot;2dip&quot;
        android:drawablePadding=&quot;0dip&quot;
        android:gravity=&quot;center_vertical&quot;
        android:textAppearance=&quot;?android:attr/textAppearanceMedium&quot;
        android:textColor=&quot;?android:attr/textColorPrimary&quot;
        android:visibility=&quot;gone&quot; /&gt;

    &lt;ImageView
        android:id=&quot;@+id/search_button&quot;
        style=&quot;?attr/actionButtonStyle&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_gravity=&quot;center_vertical&quot;
        android:contentDescription=&quot;@string/abc_searchview_description_search&quot;
        android:focusable=&quot;true&quot; /&gt;

    &lt;LinearLayout
        android:id=&quot;@+id/search_edit_frame&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_marginLeft=&quot;8dip&quot;
        android:layout_marginRight=&quot;8dip&quot;
        android:layout_weight=&quot;1&quot;
        android:layoutDirection=&quot;locale&quot;
        android:orientation=&quot;horizontal&quot;&gt;

        &lt;ImageView
            android:id=&quot;@+id/search_mag_icon&quot;
            style=&quot;@style/RtlOverlay.Widget.AppCompat.SearchView.MagIcon&quot;
            android:layout_width=&quot;@dimen/abc_dropdownitem_icon_width&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:layout_gravity=&quot;center_vertical&quot;
            android:scaleType=&quot;centerInside&quot;
            android:visibility=&quot;gone&quot; /&gt;

        &lt;!-- Inner layout contains the app icon, button(s) and EditText --&gt;
        &lt;LinearLayout
            android:id=&quot;@+id/search_plate&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;match_parent&quot;
            android:layout_gravity=&quot;center_vertical&quot;
            android:layout_weight=&quot;1&quot;
            android:orientation=&quot;horizontal&quot;&gt;

            &lt;view
                android:id=&quot;@+id/search_src_text&quot;
                class=&quot;com.example.widget.search.MySearchViewSearchAutoComplete&quot;
                android:layout_width=&quot;0dp&quot;
                android:layout_height=&quot;36dip&quot;
                android:layout_gravity=&quot;center_vertical&quot;
                android:layout_weight=&quot;1&quot;
                android:background=&quot;@null&quot;
                android:dropDownAnchor=&quot;@id/search_edit_frame&quot;
                android:dropDownHeight=&quot;wrap_content&quot;
                android:dropDownHorizontalOffset=&quot;0dip&quot;
                android:dropDownVerticalOffset=&quot;0dip&quot;
                android:ellipsize=&quot;end&quot;
                android:imeOptions=&quot;actionSearch&quot;
                android:inputType=&quot;text|textAutoComplete|textNoSuggestions&quot;
                android:paddingLeft=&quot;@dimen/abc_dropdownitem_text_padding_left&quot;
                android:paddingRight=&quot;@dimen/abc_dropdownitem_text_padding_right&quot;
                android:singleLine=&quot;true&quot; /&gt;

            &lt;ImageView
                android:id=&quot;@+id/search_close_btn&quot;
                android:layout_width=&quot;wrap_content&quot;
                android:layout_height=&quot;match_parent&quot;
                android:layout_gravity=&quot;center_vertical&quot;
                android:background=&quot;?attr/selectableItemBackgroundBorderless&quot;
                android:contentDescription=&quot;@string/abc_searchview_description_clear&quot;
                android:focusable=&quot;true&quot;
                android:paddingLeft=&quot;8dip&quot;
                android:paddingRight=&quot;8dip&quot; /&gt;

        &lt;/LinearLayout&gt;

        &lt;LinearLayout
            android:id=&quot;@+id/submit_area&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;match_parent&quot;
            android:orientation=&quot;horizontal&quot;&gt;

            &lt;ImageView
                android:id=&quot;@+id/search_go_btn&quot;
                android:layout_width=&quot;wrap_content&quot;
                android:layout_height=&quot;match_parent&quot;
                android:layout_gravity=&quot;center_vertical&quot;
                android:background=&quot;?attr/selectableItemBackgroundBorderless&quot;
                android:contentDescription=&quot;@string/abc_searchview_description_submit&quot;
                android:focusable=&quot;true&quot;
                android:paddingLeft=&quot;16dip&quot;
                android:paddingRight=&quot;16dip&quot;
                android:visibility=&quot;gone&quot; /&gt;

            &lt;ImageView
                android:id=&quot;@+id/search_voice_btn&quot;
                android:layout_width=&quot;wrap_content&quot;
                android:layout_height=&quot;match_parent&quot;
                android:layout_gravity=&quot;center_vertical&quot;
                android:background=&quot;?attr/selectableItemBackgroundBorderless&quot;
                android:contentDescription=&quot;@string/abc_searchview_description_voice&quot;
                android:focusable=&quot;true&quot;
                android:paddingLeft=&quot;16dip&quot;
                android:paddingRight=&quot;16dip&quot;
                android:visibility=&quot;gone&quot; /&gt;
        &lt;/LinearLayout&gt;
    &lt;/LinearLayout&gt;
&lt;/LinearLayout&gt;

And that's it, it should work.

huangapple
  • 本文由 发表于 2020年5月30日 23:19:05
  • 转载请务必保留本文链接:https://java.coder-hub.com/62104527.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定