giriş
Ne yazık ki , ActionBar açılır listesindeki öğelerin arka planında yapabildiğinizSearchView gibi, XML'de temaları, stilleri ve kalıtımı kullanarak metin alanı stilini ayarlamanın bir yolu yoktur . Bunun nedeni styleable olarak listelenen in ise (biz ilgilenen olduğunuzu tema nitelik) değildir. Bu nedenle, XML kaynaklarından kolayca erişemiyoruz (bir hata alırsınız ).selectableItemBackground R.stylablesearchViewTextFieldNo resource found that matches the given name: attr 'android:searchViewTextField'
SearchView metin alanı arka planını koddan ayarlama
Bu nedenle, SearchViewmetin alanının arka planını uygun şekilde değiştirmenin tek yolu, iç kısımlarına girmek, arka planı temel alan görünüme erişim elde etmek searchViewTextFieldve kendimizi ayarlamaktır.
NOT: Aşağıdaki çözüm yalnızca android:id/search_plateiçindeki öğenin id ( ) 'sine bağlıdır SearchView, bu nedenle alt geçişten daha çok SDK sürümü bağımsızdır (örneğin, içerideki searchView.getChildAt(0)doğru görünüme ulaşmak için kullanma SearchView), ancak kurşun geçirmez değildir. Özellikle bazı üreticiler SearchView, yukarıda belirtilen kimliğe sahip ve öğesinin dahili bileşenlerini yeniden uygulamaya karar verirse , kod çalışmayacaktır.
SDK'da, metin alanının arka planı dokuz yamaSearchView ile bildirilir , bu yüzden biz de aynı şekilde yapacağız. Orijinal png resimlerini Android git deposunun drawable-mdpi dizininde bulabilirsiniz . İki resimle ilgileniyoruz. Metin alanı seçildiğinde durum için ( textfield_search_selected_holo_light.9.png olarak adlandırılır ) ve olmadığı yer için ( textfield_search_default_holo_light.9.png olarak adlandırılır ) bir durum içindir.
Ne yazık ki, yalnızca odaklanmış durumu özelleştirmek isteseniz bile, her iki görüntünün yerel kopyalarını oluşturmanız gerekecektir . Bunun nedeni R.drawable'datextfield_search_default_holo_light mevcut olmamasıdır . Bu nedenle @android:drawable/textfield_search_default_holo_light, yerel çizilebilirliğe atıfta bulunmak yerine, aşağıda gösterilen seçicide kullanılabilen aracılığıyla kolayca erişilebilir değildir .
NOT: Temel olarak Holo Light temasını kullanıyordum , ancak aynısını Holo Dark ile de yapabilirsiniz . Görünüşe göre, Açık ve Koyu temalar arasında seçilen durum 9 yamalarında gerçek bir fark yok . Ancak, varsayılan durum için 9 yamada bir fark vardır (bkz. Açık ve Koyu ). Yani, muhtemelen 9-yamalar yerel kopyalarını yapmak gerek yoktur seçilen devlet hem, Karanlık ve Işık temalar (her iki işlemek istiyorum varsayarak ve onlara hem göz ile aynı hale Holo Theme ). Sadece bir yerel kopya oluşturun veher iki tema için çekilebilir seçici .
Şimdi, indirdiğiniz dokuz yamayı ihtiyacınıza göre düzenlemeniz gerekecek (yani mavi rengi kırmızıya çevirmeniz). Düzenlemenizden sonra doğru şekilde tanımlanıp tanımlanmadığını kontrol etmek için 9 yama çizme aracını kullanarak dosyaya göz atabilirsiniz .
Tek piksel kalem aracıyla (oldukça kolay) GIMP kullanarak dosyaları düzenledim, ancak muhtemelen kendi aracınızı kullanacaksınız. İşte odaklanmış durum için özelleştirilmiş 9 yamam :

NOT: Basit olması için, yalnızca mdpi yoğunluğu için resimler kullandım . Herhangi bir cihazda en iyi sonucu almak istiyorsanız, birden fazla ekran yoğunluğu için 9 yama oluşturmanız gerekir . İçin Görüntüler Holo SearchView bulunabilir mdpi , hdpi ve xhdpi çekilebilir.
Şimdi, görüntü durumuna göre uygun görüntünün görüntülenmesi için çekilebilir seçici oluşturmamız gerekecek. res/drawable/texfield_searchview_holo_light.xmlAşağıdaki içeriğe sahip dosya oluşturun :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:drawable="@drawable/textfield_search_selected_holo_light" />
<item android:drawable="@drawable/textfield_search_default_holo_light" />
</selector>
LinearLayoutMetin alanını içinde tutan görünüm için arka planı ayarlamak için yukarıda oluşturulmuş çekmeceyi kullanacağız SearchView- kimliği android:id/search_plate. Öyleyse, seçenekler menüsünü oluştururken bunu kodda hızlı bir şekilde nasıl yapacağınız aşağıda açıklanmıştır:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Getting SearchView from XML layout by id defined there - my_search_view in this case
SearchView searchView = (SearchView) menu.findItem(R.id.my_search_view).getActionView();
// Getting id for 'search_plate' - the id is part of generate R file,
// so we have to get id on runtime.
int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
// Getting the 'search_plate' LinearLayout.
View searchPlate = searchView.findViewById(searchPlateId);
// Setting background of 'search_plate' to earlier defined drawable.
searchPlate.setBackgroundResource(R.drawable.textfield_searchview_holo_light);
return super.onCreateOptionsMenu(menu);
}
}
Nihai etki
İşte nihai sonucun ekran görüntüsü:

Buna nasıl ulaştım
Buna nasıl ulaştığımı ölçmeye değer olduğunu düşünüyorum, böylece bu yaklaşım diğer görünümleri özelleştirirken kullanılabilir.
Görünüm düzenine bakılıyor
SearchViewDüzenin nasıl göründüğünü kontrol ettim . In SearchView contructor biri açılırsa düzeni bir çizgi bulabilirsiniz:
inflater.inflate(R.layout.search_view, this, true);
Artık SearchViewlayout un isimli dosyada olduğunu biliyoruz res/layout/search_view.xml. Search_view.xml'ye bakarak , içinde bulunan (bizim arama görünümü metin alanına benzeyen ) bir iç LinearLayoutöğe (id ile search_plate) bulabiliriz android.widget.SearchView$SearchAutoComplete:
<LinearLayout
android:id="@+id/search_plate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:orientation="horizontal"
android:background="?android:attr/searchViewTextField">
Şimdi, arka plan mevcut temanın searchViewTextFieldniteliğine göre ayarlandığına göre .
Özniteliğin incelenmesi (kolayca ayarlanabilir mi?)
Özelliğin nasıl searchViewTextFieldayarlandığını kontrol etmek için res / values / themes.xml'yi araştırıyoruz . SearchViewVarsayılan olarak ilgili bir grup öznitelik vardır Theme:
<style name="Theme">
<!-- (...other attributes present here...) -->
<!-- SearchView attributes -->
<item name="searchDropdownBackground">@android:drawable/spinner_dropdown_background</item>
<item name="searchViewTextField">@drawable/textfield_searchview_holo_dark</item>
<item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_dark</item>
<item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
<item name="searchViewSearchIcon">@android:drawable/ic_search</item>
<item name="searchViewGoIcon">@android:drawable/ic_go</item>
<item name="searchViewVoiceIcon">@android:drawable/ic_voice_search</item>
<item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_dark</item>
<item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>
Varsayılan tema için değerin olduğunu görüyoruz @drawable/textfield_searchview_holo_dark. İçin Theme.Lightdeğer de bu dosyada yer almaktadır .
Şimdi, bu niteliğe R.styleable aracılığıyla erişilebilseydi harika olurdu , ama maalesef öyle değil. Karşılaştırma için, diğer bakınız tema içinde hem de özelliklerini themes.xml ve R.attr gibi textAppearance veya selectableItemBackground . (Ve ) ' searchViewTextFieldde mevcut olsaydı , XML'deki uygulamamızın tamamı için tema tanımlarken basitçe çekilebilir seçicimizi kullanabilirdik. Örneğin:R.attrR.stylable
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Light">
<item name="android:searchViewTextField">@drawable/textfield_searchview_holo_light</item>
</style>
</resources>
Neler değiştirilmeli?
Artık search_platekod aracılığıyla erişmemiz gerekeceğini biliyoruz . Ancak yine de nasıl görünmesi gerektiğini bilmiyoruz. Kısacası, varsayılan temalarda değerler olarak kullanılan çekilebilir öğeleri arıyoruz: textfield_searchview_holo_dark.xml ve textfield_searchview_holo_light.xml . İçeriğe baktığımızda, selectorgörüntü durumuna bağlı olarak diğer iki çekilebilir öğeye (daha sonra 9 yamalı olacak) referans veren çekilebilirin olduğunu görüyoruz . Android'in tüm sürümlerinden (neredeyse) toplu 9 yama çekmecelerini androiddrawables.com'da bulabilirsiniz.
Özelleştirme
Mavi çizgiyi 9 yamadan birinde tanıyoruz , bu yüzden onun yerel kopyasını oluşturuyoruz ve arzu edildiği gibi renkleri değiştiriyoruz.