Anroid Searchview ile Uygulamaya Arama İşlevselliği Eklemek

Betül Şahin
5 min readNov 16, 2021

Bu yazıda uygulamaya Searchview kullanarak arama işlevselliği ekleyeceğiz. Android geliştirici dökümanı üzerinden ilerleyeceğiz. Bunun için üç aşamadan oluşan aşağıdaki adımları takip edeceğiz.

  1. Arama Arayüzünü Ayarlamak
    Uygulamaya nasıl arama arayüzü ekleneceğini ve arama sorgularını işlemek için activity’nin nasıl yapılandırılacağını öğreneceğiz.
  2. Veri Depolamak ve Aramak
    SQLite sanal veritabanı tablosunda verilerin nasıl saklandığını ve sorgulandığını öğreneceğiz.
  3. Geriye Doğru Uyumluluk
    Arama özelliklerinin, eski cihazlarla geriye dönük olarak uyumluluğunu nasıl sağlayacağımızı öğreneceğiz.

Konuyu öğrenirken basit bir İngilizce sözlük uygulaması yazacağız. Çalışma tamamlandığında aşağıdaki gibi görünecek.

1. Arama Arayüzünü Ayarlamak

Uygulama çubuğuna, SearchView widget’ı konularak uygulamaya arama özelliği eklenmektedir. Bu yöntem Android 3.0'dan bu yana tercih edilmektedir.

App Bar’a SearchView Ekleme

Uygulama çubuğuna bir SearchView widget’ı eklemek için projede res/menu/options_menu.xml adlı bir dosya oluşturuyoruz. Bunu yapmak için sol yan bölümden res klasörüne sağ tıklayıp New->Android Resource File’ı seçiyoruz. Açılan pencerede dosya adı alanına options_menu.xml yazıp kaynak tipini menu olarak belirliyoruz. Dosyaya aşağıdaki kodu ekliyoruz.

options_menu.xml dosyasıyla arama öğesi olarak kullanılacak simge ve başlık yazısı belirledik. showAsAction özelliğini collapseActionView|ifRoom olarak belirledik.

showAsAction’a geçtiğimiz öznitelikler ne anlama geliyor ?

  • collapseActionView: SearchView tüm uygulama çubuğunu kaplar ve kullanılmadığında normal boyutuna geri küçülür.
  • ifRoom: Uygulama çubuğunda yer varsa öğenin simgesi gösterilir yer yoksa öğe taşma menüsünde görüntülenir.

SearchView’i uygulama çubuğunda göstermek için activity’nin onCreateOptionsMenu() metodunda menü dosyasını(res/menu/options_menu.xml) inflate ediyoruz.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);

return true;
}

Uygulamayı çalıştırdığınızda yandaki gibi görünecektir. Arama simgesine tıkladığınızda herhangi bir işlem yapmayacaktır. Çünkü henüz nasıl davranacağını tanımlamadık.

showAsAction’ın özniteliklerini değiştirerek diğer öznitelikler ile nasıl görüneceğini inleceyebilirsiniz.

Arama Yapılabilecek Şekilde Yapılandırma (Searchable Configuration)

Burada yapılandırmadan kastedilen SearchView’in nasıl davranacağını tanımlamak.

İlk olarak projede res/xml/searchable.xml dosyasını oluşturup aşağıdaki kodları ekliyoruz. searchable.xml dosyası en azından, Android manifest’inizdeki <application> veya <activity> öğesinin android: label özelliğiyle aynı değere sahip bir android: label özelliği içermelidir. Bununla birlikte, kullanıcıya arama kutusuna ne gireceği hakkında bir fikir vermek için android: hint özelliği eklenmesi öneriliyor.

Şimdi AndroidManifest’te bu dosyaya işaret eden bir <meta-data> öğesi bildiriyoruz.

<activity ... >
...
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable" />


</activity>

Son olarak daha önce oluşturduğumuz onCreateOptionsMenu() metodunda, setSearchableInfo () metodunu çağırarak aranabilir yapılandırmayı(searchable.xml) SearchView ile ilişkilendiriyoruz.

Kullanıcı bir sorgu gönderdiğinde SearchView, ACTION_SEARCH intenti ile bir activity başlatır. Şimdi bu intenti filtreleyebilecek ve arama sorgusunu işleyebilecek bir activity‘e ihtiyacımız var.

Aranabilir Activity Oluşturma

AndroidManifest’te Activity’i, ACTION_SEARCH intentini filtrelemek üzere bildiriyoruz.

<activity android:name=".MainActivity" ... >
...
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
...
</activity>

MainActivity’nin onCreate() metodunda ACTION_SEARCH intentini kullanarak kullanıcının girmiş olduğu arama sorgusunu alıyoruz.

Buraya kadar uygulamamıza SearchView’i nasıl ekleyeceğimizi öğrendik. Sonraki adımlarda kullanıcıdan aldığımız sorguyu nasıl saklayacağımızı ve arayacağımızı öğreneceğiz.

2. Veri Depolamak ve Aramak

Bu adımda bir SQLite sanal tablosu oluşturacağız. Tablo’da kelimeler ve tanımları tutulacak. Tabloyu bir .txt dosyasıyla dolduracağız.

Sanal Tablo Oluşturma

Sanal tablo, SQLite tablosuna benzer şekilde davranır. Ancak bir veritabanı dosyası yerine geri çağrılar(callbacks) aracılığıyla bellekteki bir nesneyi okur ve yazar. Sanal tablo oluşturmak için DictionaryDatabase isminde bir sınıf oluşturuyoruz.

public class DictionaryDatabase {
...
}

DictionaryDatabase sınıfında SQLiteOpenHelper’dan türeyen DatabaseOpenHelper isminde bir iç sınıf(inner class) oluşturuyoruz. DatabaseOpenHelper sınıfını tabloyu oluşturmak(create table) ve gerektiğinde yükseltmek(upgrade) için kullanacağız.

Sanal Tabloyu Doldurma

Artık tablomuza veri kaydedebiliriz. Bunun için yukarıda bahsettiğim gibi res/raw/definitions.txt dosyasından yararlanacağız. Dosyayı ve kodların tümünü yazının sonunda bulabilirsiniz. Aşağıdaki kod dosyayı nasıl parse edip satır satır sanal tabloya ekleyeceğimizi gösteriyor. Tüm bunlar, kullanıcı arayüzünün kilitlenmesini önlemek için başka bir iş parçacığında yapılıyor. Aşağıdaki kodu DatabaseOpenHelper inner sınıfına ekliyoruz.

Tabloyu doldurmak için yazmış olduğumuz loadDictionary() metodunu DatabaseOpenHelper sınıfının onCreate() metodunda çağırıyoruz.

@Override
public void onCreate(SQLiteDatabase db) {
database = db;
database.execSQL(FTS_TABLE_CREATE);
loadDictionary();
}

Veri Sorgulama

Tablodan veri sorgulamak için SearchView’den aldığımız arama terimini kullanıyoruz. Kullanıcının arama kutusuna girdiği sorguyu arayan bir SQL ifadesi oluşturmak için DictionaryDatabase sınıfına aşağıdaki metodları ekliyoruz.

getWordMatches() metodu tabloda sorguyu arıyor. Herhangi bir sonuç bulduğunda geriye Cursor döndürüyor.

Content Provider Oluşturmak

Bunun için aşağıdaki DictionaryProvider sınıfını yazıyoruz. Bu sınıfı dictionary veritabanına erişim sağlamak için kullanacağız.

Ardından bu sınıfı AndroidManifest’te tanıtıyoruz.

...<provider android:name=".DictionaryProvider"                  android:authorities="com.betulsahin.searchviewkullanimi.DictionaryProvider" />

</application>
</manifest>

Artık MainActivity’e ListView koyup sözcükleri gösterebiliriz !

İlk olarak activity_main.xml dosyasını aşağıdaki gibi düzenliyoruz.

Ardından layout/result.xml dosyasını ekliyoruz.

Ve MainActivity onCreate() metodunda ilgili layoutları çağırıyoruz.

mTextView = (TextView) findViewById(R.id.text);
mListView = (ListView) findViewById(R.id.list);

Sözlükte arama yapmak ve verilen sorgu için sonuçları görüntülemek için aşağıdaki showResults() metodunu yazıyoruz. Bu metodu handleIntent() metodunda çağırıyoruz.

Son olarak ListView’de herhangi bir sözcüğe tıklandığında başka bir sayfada açılması için showResults() metoduna aşağıdaki kodları ekliyoruz. Sözcüklere tıklandığında WordActivity’e gidecek ve sözcük detayları görüntülenecek.

// Define the on-click listener for the list items
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Build the Intent used to open WordActivity with a specific word Uri
Intent wordIntent = new Intent(getApplicationContext(), WordActivity.class);
Uri data = Uri.withAppendedPath(DictionaryProvider.CONTENT_URI,
String.valueOf(id));
wordIntent.setData(data);
startActivity(wordIntent);
}
});

WordActivity sınıfının kodlarını yazının sonunda paylaştığım repoda bulabilirsiniz.

3. Geriye Doğru Uyumluluk

SearchView ve action bar yalnızca Android 3.0 ve sonraki sürümlerde kullanılabilir. Eski platformları desteklemek için search dialog’a geri dönülebiliyor.

Minimum ve Hedef API düzeylerini ayarlama

Android developer dökümanında, search dialog’u ayarlamak için, AndroidManifest’te aşağıdaki bildirimin yapılması söylenmiş. Bu bildirim yapıldığında, uygulamanın Android 3.0 veya sonraki sürümlerde eylem çubuğunu otomatik olarak kullanacağı ve eski cihazlarda geleneksel menü sistemini kullanacağı açıklanmış.

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />

<application>
...

Eski Cihazlar için Search Dialog’un(Arama İletişim Kutusu) Desteklenmesi

Eski cihazlarda search dialog’u çağırmak için, kullanıcı menüden arama menüsü öğesini seçtiğinde onSearchRequested() metodunu çağırıyoruz.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
default:
return false;
}
}

Çalışma Zamanında Android Derleme Sürümünün Kontrol Edilmesi

Çalışma zamanında, eski cihazlarda desteklenmeyen bir SearchView kullanımının meydana gelmediğinden emin olmak için cihaz sürümünü aşağıdaki gibi kontrol edebilirsiniz.

@Override
public boolean onCreateOptionsMenu(Menu menu) {

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

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}

Uygulamamıza arama öğesi eklemeyi, verileri depolamak ve gerektiğinde sorgulayıp çekmek için sanal tablo kullanmayı öğrendik. Son olarak uygulamamızı eski sürümlerde desteklemek için gerekli düzenlemeleri yaptık.

Umarım faydalı olur.

Referans Kaynaklar:

Adding Search Functionality — developer.android.com (Orjinal döküman)

SearchableDictionary — android.googlesource.com (Tüm kodlar)

Kaynak Kodlar: Anroid-Searchview-Kullanimi (Kelime önerisi getirme hariç kodlar)

--

--