SearchView'ün OnCloseListener'ı çalışmıyor


101

SearchViewAndroid 3.0+ ActionBar'da için destek eklemeye çalışıyorum , ancak OnCloseListenerişe koyamıyorum .

İşte kodum:

@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;
}

Arama harika çalışıyor ve OnCloseListener. Logcat'e hiçbir şey yazdırılmıyor. İşte "Kapat" düğmesine bastığımda kullanacağım Logcat:

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

Belgeleri ve örnekleri inceledim , ancak hiçbir şey onu değiştirmedi. Her ikisi de Ice Cream Sandwich üzerinde bir Asus Transformer Prime ve bir Galaxy Nexus üzerinde çalıştırıyorum. Herhangi bir fikir?

Güncelleme:

Evet - System.out.println() does işi. İşte kanıtı:

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

Bu Logcat'teki sonuçlar:

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

Hmm, Android 3.2 ile benim için iyi çalışıyor, ancak 4.0+ için DEĞİL
PJL

10
Yükseltilmiş hata, 25758
PJL

3
Bu sorunu sadece benim yaşamamdan dolayı memnunum. Aşağıdakinden başka herhangi bir hack olan var mı?
bencallis

2
Eğer showAsActionayarlanmışsa iki şey öğrendim always. Arama kutusunun kendine ait bir kapatma düğmesi vardır, ancak eğer ayarlanmışsa ifRoom | collapseActionViewişlem çubuğunda genişler.
Beraki

Yanıtlar:


153

Ben de bu problemle karşılaşıyorum ve "oncloselistener" dan vazgeçmekten başka seçeneğim yok. Bunun yerine, menuItem'inizi alabilirsiniz setOnActionExpandListener. Daha sonra, istenmeyen yöntemleri geçersiz kılın.

@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;
}

Sanırım sadece Honeycomb + olan
ActionBar'ın Arama Görünümü'nden bahsediyoruz

onCloseListener'ı kullanmakla uğraşmayın, sadece bunu menü öğenizle kullanın.
Robert

12
Önceki API seviyeleri için MenuItemCompat.OnActionExpandListener'ı kullanabileceğinizi düşünüyorum: developer.android.com/reference/android/support/v4/view/…
Ripityom

2
Tam cevap:if (Build.VERSION.SdkInt > BuildVersionCodes.NMr1) item.SetOnActionExpandListener(this); else MenuItemCompat.SetOnActionExpandListener(item, this);
FindOutIslamNow

61

Android API 14+ (ICS ve üstü) için şu kodu kullanın:

// 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
    }
});

Daha fazla bilgi için: http://developer.android.com/guide/topics/ui/actionbar.html#ActionView

Ref: onActionCollapse / onActionExpand


31

Bu problem için böyle bir şey buldum,

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);

}

1
Her zaman setIconofiedByDefault (false) kullanarak genişletmişseniz ne olur? İşe yaramıyor ... :(
Joan Casadellà

19

Android 4.1.1'de aynı problemle karşılaştım. Bilinen bir hata gibi görünüyor: https://code.google.com/p/android/issues/detail?id=25758

Her neyse, geçici bir çözüm olarak durum değişikliği dinleyicisini kullandım (SearchView eylem çubuğundan ayrıldığında, açık bir şekilde kapanır).

view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {

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

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

Yukarıdaki kod benim durumumda iyi çalıştı.


Aynı cevabı buraya gönderiyorum : https://stackoverflow.com/a/24573266/2162924


Evet, bu hata bu soruyu gönderdikten hemen sonra oluşturuldu. Orijinal soruya ilişkin yorumları görün.
Michell Bak

Oh tamam, şimdi bakın. Ancak her neyse, durum değişikliği dinleyicisi ile ilgili bu geçici çözüm başkaları için de yararlı olabilir.
Dario

OnCloseListener'ın düşündüğünüz gibi çalışmaması hayal kırıklığına uğratırken, bu aslında güzel, temiz bir çözüm. Tebrikler!
welshk91

10

Sonunda amacım için iyi çalışan bir bilgisayar korsanlığı kullandım - tüm amaçlarla çalışacağından emin değilim. Her neyse, arama sorgusunun boş olup olmadığını kontrol ediyorum. Bu, SearchView'ler ile gerçekten ilgili değil OnCloseListener- bu hala çalışmıyor!

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; }
        });

8

Bu benim sorunumu çözdü:

Olan menü öğesi 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"/>

ve faaliyette

searchView.setOnCloseListener(new OnCloseListener() {

        @Override
        public boolean onClose() {

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

1
Özniteliğe alwaysdeğer ayarlamak showAsActionsorunu çözer. Önemli olan, içinde alwaysdeğer is notbulunduğunda showAsAction, genişletilmiş SearchView, yalnızca sorgu SearchViewboş olmayan Dize ise kapatma düğmesini (çarpı işareti) sunar . SearchView.onCloseClickedKolları kapatma düğmesi olayları o geri arama söyler OnCloseListenero değilse sorgu, boş olması durumunda denir - bu ilk Temizmis - ama sonra, takas sorgu kapatma düğmesi kaybolana sonra biz teslim edemiyoruz onCloseiçin geri aramaOnCloseListener
bpawlowski

1
Sadece bir ipucu: bu yöntem, kullanıcı arama görünümünü kapattığında çağrılır (oldukça açık, ancak fark etmem birkaç kez aldı). Kullanıcı X'i ilk tıkladığında metni siliyor ve ben bu güncellemeyi almadım, X'e ikinci tıklamada SearchView'ü kapatıyor ve onClose çalıştırılıyor. Umarım yardımcı olur!
Federico Alvarez

4

Çalışmayı yapmak için arama menü öğesinde ayarlandığından OnCloseListeneremin olun .showAsActionalways

<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>

2

SearchView için çağırmayan onCloseListener ile aynı sorunla karşılaştım. Yetiştirilen hata sayısından anlayın 25758 ve okudum bazı kayıtlar, onCloseListener çağırmak için, sette gerekir:

searchView.setIconifiedByDefault(true);

Ancak benim durumum için arama görünümünün her zaman açılmasını ve simge haline getirilmemesini istedim. Aşağıya bir satır daha ekleyerek bu sorunu çözmeyi başardım:

@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), varsayılanı önceki satırda simge haline getirilmiş olarak ayarlamasına rağmen searchView'in açılmasına neden olur. Bu şekilde, hem her zaman açılan hem de onCloseListener'ı çağıran bir SearchView'e sahip olmayı başardım.


2

app:showAsActionHer zaman olacak şekilde ayarlanmış menü öğesini oluşturun .

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

Oluştururken SearchViewiçinde onCreateOptionsMenuyönteme benzer bir şey

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

search.setIconifiedByDefault(true)İhtiyaçlar için ayarlanacak truearamaya onClose()üzerine yöntemini SearchView.OnCloseListener()yukarıda yarattı.



0

Çağrılmamasının nedeni OnCloseListenerAndroid kodunda bir hata olmasıdır - dinleyici yalnızca siz de ararsanız aranır setIconifiedByDefault(true).


7
Az önce setIconifiedByDefault (true) eklemeyi denedim ama çağrılmadı
Giuseppe

@Joseph Earl: Burada benzer bir sorun yaşıyorum: stackoverflow.com/questions/43702055/… . Nasıl düzeltileceğine dair herhangi bir fikir veya fikrin var mı?
AJW

0

Zaten eski bir iş parçacığı gibi görünüyor, ancak ilk başta aynı API 18 problemini yaşadığımı düşündüm. Etrafta dolaştıktan sonra, bu konuyu bulduktan sonra, bir saat daha javadoc'un javadoc'ta tam olarak anlamadığım bir şey için denediğini ve hata yaptığını okuyun, şu anda benim için aşağıdaki çalışma:

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;
   }

Biraz doğru / yanlış ile oynadım, bu bir şekilde fark yaratıyor ve şimdi benim için çalışıyor. Umarım birisine zaman kazandırır.


0

Bu geçici bir çözüm ama benim için çalıştı

  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;
                    }
}

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

searchView'i kapat'a tıklarsanız ->

D / tıklama: tıklanan kapat


1
Bir kod bloğu ve bazı şifreli kelimeler içeren yanıtlar özellikle net değildir. Bunun neden sorunu çözdüğünü düşündüğünüzü açıklamak için doğal bir dil kullanın ve ardından çözümün uygulanmasını gösterin.

0

SearchView'ün gösterildiğini / reddedildiğini tespit etmeye çalışırken bu sorunla karşılaştım. Farklı bir dinleyici kullandım ve ihtiyacım olan şey için çalıştı:

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

0

SearchView kapat düğmesini kullandım ve üzerinde bir setOnClickListener ayarladım

searchView.findViewById<ImageView>(R.id.search_close_btn).setOnClickListener {
    searchView.setQuery("", false)
    searchView.clearFocus()
}

-2

Android'de giriş yapabileceğiniz bir konsol yok. Bunun yerine, android günlük çerçevesini kullanın:

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

Şu soruya da bakın: "System.out.println" Android'de neden çalışmıyor?


2
Doğru değil, gayet iyi çalışıyor. Lütfen güncellenmiş soruma bakın - kanıtlamak için onQueryTextChange yöntemine bir satır ekledim. Ayrıca Log.d () eklemeyi denedi, ancak bu da hiçbir şey göstermedi.
Michell Bak

Ah benim hatam! System.out.println'i Log.i'ye yazdırmaya karar verdikleri bir yere benziyor. İyi şanslar
Chris Knight

-3

İçin iki ortak model vardır SearchView.setOnCloseListener(). Bu gerçekten tüm dinleyiciler için geçerli, ancak sorunuzu özellikle ele alıyorum. İlk yol, bir dinleyici işlevi oluşturmak ve bunu bir üye değişkene eklemek, ikincisi ise sınıfın arabirimi uygulamasını sağlamak ve işleyicinin bir üye işlev olmasını sağlamaktır.

Dinleyici nesnesi oluşturmak şuna benzer:

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

Dinleyiciyi sınıf düzeyinde uygulamak şuna benzer:

public class MyClass implements OnCloseListener {
    private SearchView mSearchView;

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

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

OnCloseListenerSorunuzda yaptığınız gibi geçici olanı yaratan herhangi bir örnek görmedim .


Hey Sparky, bu konuda yorum yaptığın için teşekkürler. Bunun bir şeyi nasıl değiştireceğini gerçekten anlamıyorum. Yuvalanmış bir dinleyici, onu yapmanın geçerli bir yoludur ve buradaki yorumlara göre görebileceğiniz gibi Honeycomb üzerinde çalışır. Bunun dışında ICS'de yuvalanmış dinleyicilerle ilgili herhangi bir sorun yaşamadım - yine Honeycomb üzerinde çalışıyor.
Michell Bak

Yuvalanmış dinleyiciler ile anonim iç sınıfları kastediyorum.
Michell Bak

Bunun önemli olmaması gerektiğine katılıyorum. Ben sadece kod tabanında neler olduğu hakkında yorum yapıyorum. OnClose'un yeniden tanımlandığı koşullara bakacağım ve bakacağım.
Sparky

Java'yı anladığınızdan emin değilim - buna anonim bir iç sınıf denir.
Joseph Earl
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.