Toolbar+SearchView+textSelection = неправильное положение панели выбора текста

Фон

Я пытаюсь настроить тему моего приложения, чтобы иметь больше внешнего вида в материальном дизайне, и поэтому у меня есть панель инструментов, которая устанавливается в качестве панели действий действия.

У меня есть SearchView, который позволяет искать элементы списка ниже.

Эта проблема

Дело в том, что вы можете выбрать текст в SearchView (чтобы скопировать, вырезать и т. д.), но когда это происходит, панель инструментов получает панель инструментов выбора текста поверх нее, делая ее и сам текст скрытыми:

Перед выделением текста:

введите здесь описание изображения

После выделения текста:

введите здесь описание изображения

Что я пробовал

Я попытался отключить выделение текста, используя этот код:

  final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text);
  if(searchTextView!=null&&VERSION.SDK_INT>=VERSION_CODES.HONEYCOMB)
    searchTextView.setTextIsSelectable(false);

Но это ничего не сделало. Я также пытался найти, как прослушивать даже выбор текста (чтобы я мог установить панель инструментов как marginTop или что-то в этом роде), но не нашел.

Единственное, что мне удалось, — это использовать этот код, который сообщает мне, когда появляется панель инструментов выбора текста (но не когда она исчезает):

  searchTextView.setOnCreateContextMenuListener(new OnCreateContextMenuListener()
  {
  @Override
  public void onCreateContextMenu(final ContextMenu menu,final View v,final ContextMenuInfo menuInfo)
    {
    Log.d("AppLog","onCreateContextMenu");
    }
  });

Это не помогает. Я даже не могу закрыть меню. Я думаю, что это даже не может помочь, так как некоторые устройства могут отображать что-то другое вместо панели инструментов (например, на устройствах LG, где у них есть небольшое всплывающее окно).

Код

Макет в основном представляет собой вертикальный LinearLayout, где первым элементом является панель инструментов:

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <android.support.v7.widget.Toolbar
    android:id="@+id/activity_app_list__toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:colorControlNormal="?attr/colorControlNormal"
    android:minHeight="?attr/actionBarSize"
    android:theme="?attr/actionBarTheme"
    tools:ignore="UnusedAttribute"/>
  ...

Используемая тема скрывает обычную панель действий:

  <style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
  ...

XML меню панели действий довольно простой и имеет 3 элемента действий, где первый из них — это searchView:

<item
    android:id="@+id/menuItem_search"
    android:icon="?attr/app_search_menu_icon"
    android:title="@string/search"
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always|collapseActionView"/>

Обработка SearchView осуществляется с помощью специального класса, который я создал, который поддерживает даже старые версии Android. Это основная функция, которая обрабатывает searchView :

  @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
  public void init(final MenuItem searchMenuItem,final int hintResId,final OnQueryTextListener onQueryTextListener,final OnActionExpandListener onActionExpandListener)
    {
    this._searchMenuItem=searchMenuItem;
    if(_searchView==null)
      {
      _searchView=(SearchView)MenuItemCompat.getActionView(searchMenuItem);
      if(_searchView==null)
        {
        MenuItemCompat.setShowAsAction(searchMenuItem,MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW|MenuItem.SHOW_AS_ACTION_ALWAYS);
        MenuItemCompat.setActionView(searchMenuItem,_searchView=new SearchView(_context));
        }
      _searchView.setQueryHint(_context.getString(hintResId));
      if(VERSION.SDK_INT<VERSION_CODES.HONEYCOMB)
        {
        final EditText searchTextView=(EditText)_searchView.findViewById(R.id.search_src_text);
        if(searchTextView!=null)
          {
          searchTextView.setScroller(new Scroller(_context));
          searchTextView.setMaxLines(1);
          searchTextView.setVerticalScrollBarEnabled(true);
          searchTextView.setMovementMethod(new ScrollingMovementMethod());
          final int searchTextColorResId=App.getResIdFromAttribute(_context,android.R.attr.textColorPrimary);
          if(searchTextColorResId!=0)
            searchTextView.setTextColor(_context.getResources().getColor(searchTextColorResId));
          else
            {
            // TODO workaround for some v2.3 devices that can't get the correct color. remove this when stopping the support for v2.3
            TextView searchBadge=(TextView)_searchView.findViewById(R.id.search_badge);
            if(searchBadge!=null)
              searchTextView.setTextColor(searchBadge.getTextColors());
            }
          }
        }
      _searchView.setOnQueryTextListener(onQueryTextListener);
      MenuItemCompat.setOnActionExpandListener(searchMenuItem,onActionExpandListener);
      }
    }

Функция вызывается в конце «onCreateOptionsMenu» любого действия/фрагмента, который должен иметь searchView, например:

    _searchHolder.init(menu.findItem(R.id.menuItem_search),R.string.search_for_apps,onQueryTextListener,onActionExpandListener);

Вопрос

Как я могу решить эту проблему? Очевидно, это произошло из-за того, что панель инструментов — это просто представление, поэтому панель выбора текста отображается поверх нее, но есть ли способ исправить это?

Как избежать того, чтобы дополнительная панель инструментов становилась поверх той, которую я использовал?

Есть ли способ поддерживать все устройства в этом отношении?

Глядя на приложения Google, кажется, что они обычно используют не официальный searchView, а свой собственный. Только на ютубе вроде официальный, а там вроде как тоже официальный экшнбар используют (плюс у него странные цвета при выделении текста).


person android developer    schedule 14.05.2015    source источник


Ответы (2)


Я обнаружил, что во многих приложениях (Google messenger, Контакты и т. д.) выделение текста отключено в режиме поиска. Вы можете сделать это, установив тему панели инструментов как.

<style name="toolbarTheme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <item name="android:autoCompleteTextViewStyle">@style/SearchViewStyle</item>
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textColorPrimary">@android:color/white</item>
        <item name="android:editTextColor">@android:color/white</item>        
</style>

<style name="SearchViewStyle" parent="@android:style/Widget.Holo.Light.AutoCompleteTextView">
        <item name="android:longClickable">false</item>
</style>

Или, если вы хотите, чтобы это было похоже на youtube, добавьте эту строку в свою тему.

<item name="windowActionModeOverlay">false</item>
person Max    schedule 15.05.2015
comment
Что касается первого решения, оно должно быть голографическим? Кроме того, некоторые приложения Google могут обрабатывать выделение текста. Что касается второго решения, на самом деле я установил для windowActionModeOverlay значение true, потому что я хочу, чтобы actionMode находился поверх панели действий (потому что я разрешаю множественный выбор в приложении), но я не знал, что выделение текста будет быть проблемой. Может быть, когда появится actionMode, который я создаю, моя панель инструментов также исчезнет, ​​и наоборот? Это может сработать, нет? - person android developer; 15.05.2015
comment
Второе решение, кажется, работает для меня. При создании и уничтожении actionMode я просто соответствующим образом устанавливаю видимость панели инструментов. Спасибо. Тем не менее, для первого решения, не могли бы вы ответить на вопрос? - person android developer; 15.05.2015
comment
@androiddeveloper оба решения предназначены для Theme.AppCompat из appcompat-v7:21+ - person Max; 16.05.2015
comment
так это должно быть голо? - person android developer; 16.05.2015

Благодаря ответу Макса, я попытался просмотреть файлы стилей AppCompat, щелкая ссылки одну за другой, я нашел Widget.AppCompat.AutoCompleteTextView. Переопределите его в своей теме панели инструментов с помощью:

<item name="android:autoCompleteTextViewStyle">@style/AppTheme.SearchViewStyle</item>

<style name="AppTheme.SearchViewStyle" parent="Widget.AppCompat.AutoCompleteTextView">
    <item name="android:longClickable">false</item>
</style>

Он отключает longClick в SearchView. Это работает на устройствах от API 14 (предыдущие версии не пробовал) до API 22.1.1, по крайней мере.

person Davideas    schedule 19.05.2015