Pregunta

Estoy tratando de agregar soporte para el SearchView en el Android 3.0+ ActionBar, pero no puedo obtener el OnCloseListener para el trabajo.

Aquí está mi código:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    searchView = (SearchView) menu.findItem(R.id.search_textbox).getActionView();
    searchView.setOnQueryTextListener(new OnQueryTextListener() {
        @Override
        public boolean onQueryTextChange(String newText) {
            searchLibrary(newText);
            return false;
        }
        @Override
        public boolean onQueryTextSubmit(String query) { return false; }
    });
    searchView.setOnCloseListener(new OnCloseListener() {
        @Override
        public boolean onClose() {
            System.out.println("Testing. 1, 2, 3...");
            return false;
        }
    });
    return true;
}

La búsqueda funciona muy bien y todo es trabajo, excepto para el OnCloseListener.Nada de lo que se imprime a Logcat.Aquí está el Logcat para cuando estoy presionando el botón "Cerrar":

02-17 13:01:52.914: I/TextType(446): TextType = 0x0
02-17 13:01:57.344: I/TextType(446): TextType = 0x0
02-17 13:02:02.944: I/TextType(446): TextType = 0x0

He mirado a través de la documentación y muestras, pero nada parecía cambiar.Yo estoy corriendo en una Asus Transformer Prime y un Galaxy Nexus, tanto en Ice Cream Sandwich.Alguna idea?

Actualización:

Sí - System.out.println() ¿ trabajo.Aquí está la prueba:

   @Override
 public boolean onQueryTextChange(String newText) {
    System.out.println(newText + "hello");
    searchLibrary(newText);
    return false;
 }

Los resultados en este Logcat:

02-17 13:04:20.094: I/System.out(21152): hello
02-17 13:04:24.914: I/System.out(21152): thello
02-17 13:04:25.394: I/System.out(21152): tehello
02-17 13:04:25.784: I/System.out(21152): teshello
02-17 13:04:26.064: I/System.out(21152): testhello
¿Fue útil?

Solución

También me encuentro con este problema, y yo no tenemos más remedio que renunciar a la "oncloselistener".En su lugar, usted puede conseguir su menuItem, entonces setOnActionExpandListener.A continuación, reemplazar unimplents métodos.

@Override
public boolean onMenuItemActionExpand(MenuItem item) {
    // TODO Auto-generated method stub
    Log.d("*******","onMenuItemActionExpand");
    return true;
}

@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
    //do what you want to when close the sesarchview
    //remember to return true;
    Log.d("*******","onMenuItemActionCollapse");
    return true;
}

Otros consejos

Para Android API 14+ (ICS y mayor) use este código:

// When using the support library, the setOnActionExpandListener() method is
// static and accepts the MenuItem object as an argument
MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() {
    @Override
    public boolean onMenuItemActionCollapse(MenuItem item) {
        // Do something when collapsed
        return true;  // Return true to collapse action view
    }

    @Override
    public boolean onMenuItemActionExpand(MenuItem item) {
        // Do something when expanded
        return true;  // Return true to expand action view
    }
});

Para más información: http://developer.android.com/guide/topics/ui/actionbar.html#actionview

Árbitro: onationCollapse/onactionExpand

Para este problema se me ocurrió algo como esto,

private SearchView mSearchView;

@TargetApi(14)
@Override
public boolean onCreateOptionsMenu(Menu menu)
{

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.conversation_index_activity_menu, menu);

    mSearchView = (SearchView) menu.findItem(R.id.itemSearch).getActionView();

    MenuItem menuItem = menu.findItem(R.id.itemSearch);

    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    {
        menuItem.setOnActionExpandListener(new OnActionExpandListener()
        {

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item)
            {
                // Do something when collapsed
                Log.i(TAG, "onMenuItemActionCollapse " + item.getItemId());
                return true; // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item)
            {
                // TODO Auto-generated method stub
                Log.i(TAG, "onMenuItemActionExpand " + item.getItemId());
                return true;
            }
        });
    } else
    {
        // do something for phones running an SDK before froyo
        mSearchView.setOnCloseListener(new OnCloseListener()
        {

            @Override
            public boolean onClose()
            {
                Log.i(TAG, "mSearchView on close ");
                // TODO Auto-generated method stub
                return false;
            }
        });
    }


    return super.onCreateOptionsMenu(menu);

}

Me encontré con el mismo problema en Android 4.1.1. Parece que es un error conocido: https://code.google.com/p/android/issues/detail?id=25758

De todos modos, como una solución, utilicé el oyente de cambio de estado (cuando SearchView se separa de la barra de acción, también se cierra obviamente).

view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {

    @Override
    public void onViewDetachedFromWindow(View arg0) {
        // search was detached/closed
    }

    @Override
    public void onViewAttachedToWindow(View arg0) {
        // search was opened
    }
});

El código anterior funcionó bien en mi caso.


Publico la misma respuesta aquí: https://stackoverflow.com/a/24573266/2162924

Terminé usando un poco de hack, que funciona bien para mi propósito, no estoy seguro de que funcione con todos los propósitos. De todos modos, estoy haciendo un cheque para ver si la consulta de búsqueda está vacía. Esto no está realmente relacionado con el SearchView's OnCloseListener Sin embargo, ¡eso todavía no funciona!

searchView.setOnQueryTextListener(new OnQueryTextListener() {
            @Override
            public boolean onQueryTextChange(String newText) {
                if (newText.length() > 0) {
                    // Search
                } else {
                    // Do something when there's no input
                }
                return false;
            }
            @Override
            public boolean onQueryTextSubmit(String query) { return false; }
        });

Bueno, esto resolvió mi problema:

Elemento de menú con showAsAction="always"

<item
    android:id="@+id/action_search"
    android:icon="@drawable/ic_action_search"
    android:title="Search"
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always"/>

y en actividad

searchView.setOnCloseListener(new OnCloseListener() {

        @Override
        public boolean onClose() {

            Log.i("SearchView:", "onClose");
            searchView.onActionViewCollapsed();
            return false;
        }
    });

He encontrado el mismo problema con OnCloseListener que no invocó para SearchView. Comprender por el problema de errores planteado en 25758, y algunas publicaciones que he leído, para invocar a OnCloSeListener, debes establecer:

searchView.setIconifiedByDefault(true);

Pero para mi caso quería que se abriera la vista de búsqueda y no se haya iconificado todo el tiempo. Me las arreglo para resolver esto agregando una línea más a continuación:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.search_bar, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setOnQueryTextListener(queryTextListener);
    searchView.setIconifiedByDefault(true);
    searchView.setIconified(false);
    return true;
}

SearchView.SeticOnified (FALSE) hará que la SearchView se abra, a pesar de establecer el valor predeterminado en Iconified a True en la línea anterior. De esta manera, logré tener una vista de búsqueda que se abre todo el tiempo y que invoque el OnCloSelistener.

Para hacer el OnCloseListener trabajar, asegúrese de que showAsAction se establece en always En el elemento del menú de búsqueda.

<menu 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"
      tools:context=".SearchActivity">

    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:icon="@drawable/ic_search_toolbar"
        app:showAsAction="always"
        app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>

Para MenuItemCompat Problema Agregué ViewTreeObServer para rastrear el estado de visibilidad. Puedes consultar mi respuesta aquí:https://stackoverflow.com/a/28762632/1633609

Crea el elemento de menú con el app:showAsAction establecido para siempre.

<item   
 android:id="@+id/action_search"  
 android:title="..."  
 android:icon="..."  
 app:actionViewClass="android.support.v7.widget.SearchView"  
 app:showAsAction="always"/>

Al crear el SearchView en el onCreateOptionsMenu método hacer algo similar

inflater.inflate(R.menu.menu_search, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView search = (SearchView) item.getActionView();
search.setQueryHint(getString(R.string.search_brand_item));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
  @Override
  public boolean onQueryTextSubmit(String query) {
    // add your code
    return false;
  }

  @Override
  public boolean onQueryTextChange(String newText) {
    // add your code 
    return false;
  }
});
search.setOnCloseListener(new SearchView.OnCloseListener() {
  @Override
  public boolean onClose() {
    // add your code here
    return false;
  }
});
search.setIconifiedByDefault(true); // make sure to set this to true

los search.setIconifiedByDefault(true) necesita ser configurado en true para llamar al onClose() método en el SearchView.OnCloseListener() creado arriba.

La razón por la que el OnCloseListener no se llama es porque hay un error en el código de Android: el oyente solo se llama si también llama setIconifiedByDefault(true).

Parece un hilo viejo ya, pero pensé que tengo el mismo problema API 18 en el primer comienzo. Después de buscar en Google, encontré este hilo, otra hora leyó que el Javadoc probó y erró por algo que no pretendo entender completamente en Javadoc, el siguiente trabajo para mí ahora:

searchView.setIconifiedByDefault(true);

   // OnQueryTextListener
   @Override
   public boolean onQueryTextSubmit(String query) {
      Log.d(tag, "onQueryTextSubmit: " + query);
      return true;
   }

   @Override
   public boolean onQueryTextChange(String query) {
      Log.d(tag, "onQueryTextChange: " + query);
      return true;
   }

   // OnCloseListener
   @Override
   public boolean onClose() {
      Log.w(tag, "onClose: ");
      return false;
   }

Jugué un poco con True/False, que de alguna manera marca la diferencia, y ahora funciona para mí. Con suerte, podría ahorrar tiempo a alguien.

Es una solución pero ha funcionado para mí

  searchView.setOnQueryTextListener(new android.widget.SearchView.OnQueryTextListener() {

                String lastText;

                @Override
                public boolean onQueryTextChange(final String newText) {
                    if (lastText != null && lastText.length() > 1 && newText.isEmpty()) {
                        // close ctn clicked

                        return true;
                    }
}
    searchView.setOnCloseListener {
        d("click", "close clicked")
        return@setOnCloseListener false
    }

Si hace clic en SearchView Cerrar ->

D/Haga clic: Cerrar Haga clic

Encontré este problema mientras intentaba detectar la muestra/despido de SearchView. Terminé usando un oyente diferente y funcionó para lo que necesito:

        setOnQueryTextFocusChangeListener { _, hasFocus ->
            if (hasFocus) {
                // SearchView is being shown
            } else {
                // SearchView was dismissed
            }
        }

No hay consola en Android para registrar. En su lugar, use el marco de registro de Android:

Log.d("Test Tag", "Testing.  1, 2, 3...");

Ver también esta pregunta: ¿Por qué no funciona "System.out.println" en Android?

Hay dos patrones comunes para SearchView.setOnCloseListener(). Esto es realmente cierto para todos los oyentes, pero estoy abordando su pregunta específicamente. La primera forma es crear una función de oyente y adjuntarla a una variable miembro, y la segunda es hacer que la clase implementa la interfaz y hacer que el controlador sea una función miembro.

Crear un objeto de oyente se ve así:

private SearchView mSearchView;
private final SearchView.OnCloseListener mOnCloseListener = 
    new SearchView.OnCloseListener() {
        public boolean onClose() {
            doStuff();
            return myBooleanResult;
        }
    };
mSearchView.setOnCloseListener(mOnCloseListener);

Implementar el oyente a nivel de clase se ve así:

public class MyClass implements OnCloseListener {
    private SearchView mSearchView;

    public MyClass(...) {
        mSearchView.setOnCloseListener(this);
    }

    @Override
    public boolean onClose() {
        doStuff();
        return false;
    }
}

No he visto ningún ejemplo que cree el OnCloseListener ad-hoc, como lo hiciste en tu pregunta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top