การเปลี่ยนพื้นหลังที่วาดได้ของวิดเจ็ต searchview


123

ฉันกำลังพยายามเปลี่ยน drawable ที่อยู่ในวิดเจ็ต searchview ของแถบการดำเนินการของ Android

ปัจจุบันมีลักษณะดังนี้: ใส่คำอธิบายภาพที่นี่

แต่ฉันต้องเปลี่ยนพื้นหลังสีน้ำเงินที่วาดได้เป็นสีแดง

ฉันได้ลองทำหลาย ๆ อย่างโดยไม่ต้องใช้วิดเจ็ตการค้นหาของตัวเอง แต่ดูเหมือนจะไม่ได้ผล

ใครช่วยชี้ทางที่ถูกต้องให้ฉันเปลี่ยนสิ่งนี้ได้ไหม


1
ฉันเชื่อว่าโพสต์ SO นี้สามารถช่วยคุณในสิ่งที่คุณต้องการทำให้สำเร็จได้หากคุณยังไม่ได้ตรวจสอบ
Angelo

@Angelo แต่นี้เป็นไปไม่ได้ที่มีพื้นหลังเพราะมันไม่สามารถใช้ได้ในผ่านSearchView R.styleableคำตอบของฉันด้านล่างอธิบายถึงวิธีการทำในโค้ด
vArDo

คุณได้รับข้อความ "ป้อนชื่อฟิล์ม" อย่างไร
เซน

คุณสามารถตั้งค่าข้อความคำใบ้ในมุมมองการค้นหาดังนี้ SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete) searchView.findViewById (android.support.v7.appcompat.R.id.search_src_text); searchAutoComplete.setHint ("ข้อความคำใบ้");
Dominik

ฉันอธิบายในตอนท้ายของโพสต์นี้ พร้อมรูปภาพ/programming/47426541/how-to-change-searchbar-cancel-button-image-in-xamarin-forms/51297028#51297028
vu ledang

คำตอบ:


253

Intro

แต่น่าเสียดายที่ไม่มีทางไปยังชุดSearchViewข้อความรูปแบบข้อมูลโดยใช้รูปแบบรูปแบบและมรดกในรูปแบบ XML ที่คุณสามารถทำอะไรกับพื้นหลังของรายการใน ActionBar แบบเลื่อนลง เนื่องจากselectableItemBackground มีการระบุว่ามีสไตล์ในR.stylableขณะที่searchViewTextField(แอตทริบิวต์ธีมที่เราสนใจ) ไม่ใช่ ดังนั้นเราจึงไม่สามารถเข้าถึงได้อย่างง่ายดายจากภายในทรัพยากร XML (คุณจะได้รับNo resource found that matches the given name: attr 'android:searchViewTextField'ข้อผิดพลาด)

การตั้งค่าพื้นหลังฟิลด์ข้อความ SearchView จากโค้ด

ดังนั้นวิธีเดียวที่จะแทนที่พื้นหลังของSearchViewฟิลด์ข้อความได้อย่างถูกต้องคือการเข้าไปในภายในของมันรับการเข้าถึงเพื่อดูที่มีการตั้งค่าพื้นหลังตามsearchViewTextFieldและตั้งค่าของเราเอง

หมายเหตุ:โซลูชันด้านล่างขึ้นอยู่กับ id ( android:id/search_plate) ขององค์ประกอบภายในSearchViewเท่านั้นดังนั้นจึงเป็นเวอร์ชัน SDK ที่เป็นอิสระมากกว่าการส่งผ่านลูก (เช่นใช้searchView.getChildAt(0)เพื่อไปยังมุมมองที่ถูกต้องภายในSearchView) แต่ไม่สามารถกันกระสุนได้ โดยเฉพาะอย่างยิ่งหากผู้ผลิตบางรายตัดสินใจที่จะติดตั้งภายในSearchViewและองค์ประกอบที่มี id ที่กล่าวถึงข้างต้นจะไม่สามารถใช้งานได้

ใน SDK พื้นหลังของช่องข้อความในSearchViewจะถูกประกาศผ่านเก้าแพตช์ดังนั้นเราจะทำในลักษณะเดียวกัน คุณสามารถค้นหาเดิมPNGภาพในdrawable-mdpiไดเรกทอรีของAndroid คอมไพล์พื้นที่เก็บข้อมูล เราสนใจภาพสองภาพ หนึ่งสำหรับสถานะเมื่อมีการเลือกฟิลด์ข้อความ (ชื่อtextfield_search_selected_holo_light.9.png ) และอีกรายการหนึ่งสำหรับตำแหน่งที่ไม่ใช่ (ชื่อtextfield_search_default_holo_light.9.png )

น่าเสียดายที่คุณจะต้องสร้างสำเนาของภาพทั้งสองในเครื่องแม้ว่าคุณจะต้องการปรับแต่งเฉพาะสถานะที่โฟกัสก็ตาม นี้เป็นเพราะtextfield_search_default_holo_lightไม่ได้อยู่ในR.drawable ดังนั้นจึงไม่สามารถเข้าถึงได้โดยง่าย@android:drawable/textfield_search_default_holo_lightซึ่งสามารถใช้ในตัวเลือกที่แสดงด้านล่างแทนการอ้างอิงในท้องถิ่นที่วาดได้

หมายเหตุ:ฉันใช้ธีม Holo Lightเป็นพื้นฐาน แต่คุณสามารถทำเช่นเดียวกันกับHolo Darkได้ ดูเหมือนว่าจะไม่มีความแตกต่างอย่างแท้จริงในแพตช์ 9 สถานะที่เลือกระหว่างธีมLightและDark อย่างไรก็ตามมีความแตกต่างใน 9 แพตช์สำหรับสถานะเริ่มต้น (ดูLight vs Dark ) ดังนั้นอาจไม่จำเป็นต้องทำสำเนา 9 แพทช์ในเครื่องสำหรับสถานะที่เลือกสำหรับทั้งธีมมืดและสว่าง (สมมติว่าคุณต้องการจัดการทั้งสองอย่างและทำให้ทั้งคู่ดูเหมือนกันในธีม Holo ) เพียงทำสำเนาในเครื่องหนึ่งชุดและใช้ในตัวเลือกที่วาดได้สำหรับทั้งสองธีม

ตอนนี้คุณจะต้องแก้ไขเก้าแพทช์ที่ดาวน์โหลดมาตามความต้องการของคุณ (เช่นเปลี่ยนสีน้ำเงินเป็นสีแดง) คุณสามารถดูไฟล์โดยใช้เครื่องมือวาด 9 แพทช์เพื่อตรวจสอบว่าได้กำหนดไว้อย่างถูกต้องหรือไม่หลังจากการแก้ไขของคุณ

ฉันได้แก้ไขไฟล์โดยใช้GIMPด้วยเครื่องมือดินสอหนึ่งพิกเซล (ค่อนข้างง่าย) แต่คุณอาจใช้เครื่องมือของคุณเอง นี่คือ 9-patch ที่กำหนดเองสำหรับสถานะโฟกัส :

ใส่คำอธิบายภาพที่นี่

หมายเหตุ:เพื่อความเรียบง่ายฉันใช้เฉพาะภาพสำหรับความหนาแน่นmdpi คุณจะต้องสร้าง9 แพตช์สำหรับความหนาแน่นของหน้าจอหลาย ๆ หน้าจอหากคุณต้องการผลลัพธ์ที่ดีที่สุดบนอุปกรณ์ใด ๆ รูปภาพสำหรับHolo SearchViewสามารถพบได้ในmdpi , hdpiและxhdpi drawable

ตอนนี้เราจะต้องสร้างตัวเลือกที่วาดได้เพื่อให้แสดงภาพที่เหมาะสมตามสถานะการดู สร้างไฟล์ที่res/drawable/texfield_searchview_holo_light.xmlมีเนื้อหาต่อไปนี้:

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

เราจะใช้ drawable สร้างขึ้นไปยังพื้นหลังที่ตั้งไว้สำหรับLinearLayoutมุมมองที่เก็บข้อมูลข้อความภายในSearchView- android:id/search_plateรหัสของมันคือ ต่อไปนี้เป็นวิธีดำเนินการอย่างรวดเร็วในโค้ดเมื่อสร้างเมนูตัวเลือก:

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

}

ผลสุดท้าย

นี่คือภาพหน้าจอของผลลัพธ์สุดท้าย:

ใส่คำอธิบายภาพที่นี่

ฉันมาถึงจุดนี้ได้อย่างไร

ฉันคิดว่ามันคุ้มค่าที่จะพิจารณาว่าฉันมาถึงจุดนี้ได้อย่างไรเพื่อให้สามารถใช้แนวทางนี้ในการปรับแต่งมุมมองอื่น ๆ

กำลังตรวจสอบเค้าโครงมุมมอง

ฉันได้ตรวจสอบSearchViewลักษณะของเค้าโครงแล้ว ในSearchView contructorเราสามารถค้นหาเส้นที่ขยายโครงร่าง:

inflater.inflate(R.layout.search_view, this, true);

ตอนนี้เรารู้ว่ารูปแบบที่อยู่ในแฟ้มชื่อSearchView res/layout/search_view.xmlเมื่อมองเข้าไปในsearch_view.xmlเราจะพบLinearLayoutองค์ประกอบภายใน(พร้อม id search_plate) ที่มี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">

ตอนนี้เราได้ตั้งค่าพื้นหลังตามsearchViewTextFieldแอตทริบิวต์ของธีมปัจจุบันแล้ว

การตรวจสอบแอตทริบิวต์ (สามารถตั้งค่าได้ง่ายหรือไม่?)

หากต้องการตรวจสอบว่าsearchViewTextFieldแอตทริบิวต์มีการตั้งค่าที่เราตรวจสอบความละเอียด / ค่า / themes.xml มีกลุ่มของแอตทริบิวต์ที่เกี่ยวข้องกับSearchViewค่าเริ่มต้น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>

@drawable/textfield_searchview_holo_darkเราจะเห็นว่าสำหรับรูปแบบเริ่มต้นมีค่าเป็น สำหรับTheme.Lightค่าจะถูกตั้งค่าในไฟล์นั้นด้วย

ตอนนี้มันจะดีมากถ้าแอตทริบิวต์นี้สามารถเข้าถึงได้ผ่านรูปแบบRแต่น่าเสียดายที่มันไม่ใช่ สำหรับการเปรียบเทียบให้ดูที่อื่น ๆรูปแบบแอตทริบิวต์ที่มีอยู่ทั้งในthemes.xmlและR.attrเช่นtextAppearanceหรือselectableItemBackground หากsearchViewTextFieldมีอยู่ในR.attr(และR.stylable) เราสามารถใช้ตัวเลือกที่วาดได้ของเราเมื่อกำหนดธีมสำหรับแอปพลิเคชันทั้งหมดของเราใน XML ตัวอย่างเช่น:

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

ควรแก้ไขอย่างไร

ตอนนี้เรารู้แล้วว่าเราต้องเข้าถึงsearch_plateรหัส อย่างไรก็ตามเรายังไม่รู้ว่าควรมีลักษณะอย่างไร ในระยะสั้นเราค้นหาภาพวาดใช้เป็นค่าในรูปแบบเริ่มต้น: textfield_searchview_holo_dark.xmlและtextfield_searchview_holo_light.xml เมื่อดูเนื้อหาเราจะเห็นว่าสิ่งที่วาดได้นั้นselectorอ้างอิงสิ่งที่วาดได้อีกสองรายการ (ซึ่งเกิดขึ้นเป็น 9 แพตช์ในภายหลัง) ตามสถานะการดู คุณสามารถค้นหารายการวาด 9 แพตช์แบบรวมได้จาก (เกือบ) ทุกเวอร์ชันของ Android บนandroiddrawables.com

การปรับแต่ง

เรารู้จักเส้นสีน้ำเงินในหนึ่งใน 9 แพตช์ดังนั้นเราจึงสร้างสำเนาในเครื่องและเปลี่ยนสีตามต้องการ


โค้ด java ของคุณจะไม่ทำงาน SearchView ของเขาอยู่ใน ActionBar และไม่พบด้วยเมธอด findViewById แต่ที่เหลือถูกต้อง!
VinceFR

@VinceFR ขอบคุณที่ชี้ให้เห็น ยังไม่สังเกตเห็นเลย (ฉันโฟกัสไปที่SearchViewตัวเองแล้ว) จะเป็นไรไหมถ้าฉันรวมคำตอบของคุณ (แทนที่ onCreateOptionsMenu) ลงในของฉัน
vArDo

@VinceFR ฉันได้ย้ายรหัสของฉันจากonCreate()วิธีonCreateOptionsMenu()การเป็นวิธีการตามที่คุณแนะนำ โหวตคำตอบของคุณ
vArDo

ขอบคุณมาก: D มีวิธีใดบ้างที่ฉันสามารถเปลี่ยนไอคอน Mag และไอคอนปิดในลักษณะเดียวกันได้หรือไม่?
Harsha MV

เราจะเปลี่ยนไอคอนแว่นขยายได้อย่างไร? ฉันลองทุกอย่างแล้ว แต่ไม่สามารถเปลี่ยนแปลงได้ ... ขอบคุณ ... แล้วจะทำอย่างไรในแถบการดำเนินการ sherlock
Jovan

32

วิธีแก้ปัญหาข้างต้นอาจใช้ไม่ได้หากคุณใช้ไลบรารี appcompat คุณอาจต้องแก้ไขโค้ดเพื่อให้ใช้งานได้กับไลบรารี appcompat

นี่คือโซลูชันการทำงานสำหรับไลบรารี appcompat

  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {

    getMenuInflater().inflate(R.menu.main_menu, menu); 

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchAutoComplete.setHintTextColor(Color.WHITE);
    searchAutoComplete.setTextColor(Color.WHITE);

    View searchplate = (View)searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
    searchplate.setBackgroundResource(R.drawable.texfield_searchview_holo_light);

    ImageView searchCloseIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
    searchCloseIcon.setImageResource(R.drawable.abc_ic_clear_normal);

    ImageView voiceIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_voice_btn);
    voiceIcon.setImageResource(R.drawable.abc_ic_voice_search);

    ImageView searchIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
    searchIcon.setImageResource(R.drawable.abc_ic_search);


    return super.onCreateOptionsMenu(menu);
}

1
สิ่งนี้ใช้ไม่ได้กับ search_mag_icon มันให้ "สไตล์มีคีย์ที่มีรายการที่ไม่ถูกต้อง: 0x01010479"
Lavanya

1
แผ่นค้นหาใช้ไม่ได้สำหรับฉัน (มันทำอะไรบางอย่าง แต่ฉันไม่เห็นการเปลี่ยนแปลงใด ๆ ในบรรทัดล่างสุด) แต่แนวคิดทั่วไปสำหรับ AppCompat นั้นมีประโยชน์มาก
guy_m

14

onCreateOptionsMenuวิธีการของคุณต้อง:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.option, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        ViewGroup v = (ViewGroup) searchView.findViewById(linlayId);
        v.setBackgroundResource(R.drawable.searchviewredversion);
        return super.onCreateOptionsMenu(menu);
    }

ที่รายการค้นหาของคุณไม่menu_searchแน่นอน

และนี่คือsearchviewredversion(อันนี้คือรุ่น xhdpi): http://img836.imageshack.us/img836/5964/searchviewredversion.png

ใส่คำอธิบายภาพที่นี่


มีวิธีใดบ้างในการเปลี่ยนไอคอนค้นหาและปุ่มปิดในลักษณะเดียวกัน
Harsha MV

ฉันไม่รู้เกี่ยวกับ SherlockActionBar 4.2 แต่ใช่คุณสามารถเปลี่ยนไอคอนค้นหาและปุ่มปิดได้ในลักษณะเดียวกัน!
VinceFR

ActionbarSherlock มีธีมของตัวเองและกำหนด SearchView ของตัวเอง ซึ่งหมายความว่าคุณสามารถเพิ่มรายการในธีมของคุณที่ชื่อว่า searchViewTextField และใช้คำจำกัดความที่วาดได้และแพตช์ 9 รายการด้านบน
NKijak

1
อย่าลืมเปลี่ยนชื่อไฟล์เป็น searchviewredversion.9.png เพื่อระบุการส่งออกเนื้อหาเป็น 9-patch
1owk3y

13

โซลูชันข้างต้นใช้ไม่ได้กับ ActionBarSherlock 4.2 ดังนั้นจึงไม่สามารถใช้งานร่วมกับ Android 2.x ได้ นี่คือรหัสการทำงานที่ตั้งค่าพื้นหลัง SearchView และข้อความคำใบ้บน ActionBarSherlock 4.2:

public static void styleSearchView(SearchView searchView, Context context) {
    View searchPlate = searchView.findViewById(R.id.abs__search_plate);
    searchPlate.setBackgroundResource(R.drawable.your_custom_drawable);
    AutoCompleteTextView searchText = (AutoCompleteTextView) searchView.findViewById(R.id.abs__search_src_text);
    searchText.setHintTextColor(context.getResources().getColor(R.color.your_custom_color));
}

ฉันควรใส่รหัสนี้ไว้ที่ไหน ฉันกำลังพยายามทำสิ่งนี้ในแถบการดำเนินการเวอร์ชัน 4.2 คำถามของฉันstackoverflow.com/questions/13992424/…
Harsha MV

สวัสดีเรียกจากเมธอด onCreateOptionsMenu ค้นหา searchView และส่งต่อไปยังวิธีนี้
David Vávra

ขอบคุณ. ความคิดใด ๆ ที่จะลบสัญลักษณ์ Mag แบบอินไลน์ดังที่แสดงไว้ที่นี่i.imgur.com/YvBz2.png
Harsha MV

3
ด้วย ABS คุณจะขยาย Theme.Sherlock หรือ Theme.Sherlock.Light ไม่ใช่ธีม Android ซึ่งหมายความว่าสิ่งที่คุณต้องทำคือเพิ่มรายการที่ชื่อ searchViewTextField ลงในข้อกำหนดธีมแอปของคุณ ทำทั้งหมดใน XML ไม่ต้องใช้รหัส
NKijak

5

ฉันเหนื่อยที่จะทำสิ่งนี้เช่นกันและฉันใช้ v7 แอปพลิเคชันล้มเหลวเมื่อฉันพยายามคว้าsearchPlateผ่านgetIdentifier()ดังนั้นฉันจึงทำแบบนี้:

View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);

4

ปรับปรุง

หากคุณใช้ AndroidX คุณสามารถทำได้เช่นนี้

    View searchPlate = svSearch. findViewById(androidx.appcompat.R.id.search_plate);
    if (searchPlate != null) {
        AutoCompleteTextView searchText = searchPlate.findViewById(androidx.appcompat.R.id.search_src_text);
        if (searchText != null){
            searchText.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.edittext_text_size));
            searchText.setMaxLines(1);
            searchText.setSingleLine(true);
            searchText.setTextColor(getResources().getColor(R.color.etTextColor));
            searchText.setHintTextColor(getResources().getColor(R.color.etHintColor));
            searchText.setBackground(null);
        }
    }

3

ฉันก็ประสบปัญหาเดียวกันฉันใช้ appcompat v7 ไลบรารีและกำหนดสไตล์ที่กำหนดเองสำหรับมัน ในโฟลเดอร์ที่วาดได้ให้ใส่ไฟล์ bottom_border.xml ซึ่งมีลักษณะดังนี้:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
  <shape >
      <solid android:color="@color/blue_color" />
  </shape>
</item>
<item android:bottom="0.8dp"
  android:left="0.8dp"
  android:right="0.8dp">
  <shape >
      <solid android:color="@color/background_color" />
  </shape>
</item>

<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="2.0dp">
  <shape >
      <solid android:color="@color/main_accent" />
  </shape>
 </item>
</layer-list>

ในโฟลเดอร์ค่า styles_myactionbartheme.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="AppnewTheme" parent="Theme.AppCompat.Light">
    <item name="android:windowBackground">@color/background</item>
    <item name="android:actionBarStyle">@style/ActionBar</item>
    <item name="android:actionBarWidgetTheme">@style/ActionBarWidget</item>
</style> 
<!-- Actionbar Theme -->
<style name="ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
    <item name="android:background">@color/main_accent</item>
    <!-- <item name="android:icon">@drawable/abc_ic_ab_back_holo_light</item> -->
</style> 
<style name="ActionBarWidget" parent="Theme.AppCompat.Light">
    <!-- SearchView customization-->
     <!-- Changing the small search icon when the view is expanded -->
    <!-- <item name="searchViewSearchIcon">@drawable/ic_action_search</item> -->
     <!-- Changing the cross icon to erase typed text -->
  <!--   <item name="searchViewCloseIcon">@drawable/ic_action_remove</item> -->
     <!-- Styling the background of the text field, i.e. blue bracket -->
    <item name="searchViewTextField">@drawable/bottom_border</item>
     <!-- Styling the text view that displays the typed text query -->
    <item name="searchViewAutoCompleteTextView">@style/AutoCompleteTextView</item>        
</style>

  <style name="AutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
    <item name="android:textColor">@color/text_color</item>
  <!--   <item name="android:textCursorDrawable">@null</item> -->
    <!-- <item name="android:textColorHighlight">@color/search_view_selected_text</item> -->
</style>
</resources>

ฉันกำหนดไฟล์ custommenu.xml สำหรับแสดงเมนู:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:com.example.actionbartheme="http://schemas.android.com/apk/res-auto" >  

<item android:id="@+id/search"
      android:title="@string/search_title"
      android:icon="@drawable/search_buttonn" 
     com.example.actionbartheme:showAsAction="ifRoom|collapseActionView"   
                 com.example.actionbartheme:actionViewClass="android.support.v7.widget.SearchView"/>

กิจกรรมของคุณควรขยาย ActionBarActivity แทน Activity

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    // Inflate the menu; this adds items to the action bar if it is present.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.custommenu, menu);
}

ในไฟล์รายการ:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppnewTheme" >

ดูข้อมูลเพิ่มเติมได้ที่
นี่http://www.jayway.com/2014/06/02/android-theming-the-actionbar/


ลองดู: stackoverflow.com/questions/8211929/…สำหรับตัวอย่าง LayerList อื่น
Jared Burrows

2

ขั้นแรกให้สร้างไฟล์ XML ชื่อ search_widget_background.xml เพื่อใช้เป็น drawable เช่นภายใต้ไดเร็กทอรี drawable

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="@color/red" />

</shape>

วาดได้นี้จะใช้เป็นพื้นหลังสำหรับวิดเจ็ตการค้นหาของเรา ฉันตั้งค่าสีเป็นสีแดงเพราะนั่นคือสิ่งที่คุณขอ แต่คุณสามารถตั้งค่าเป็นสีใดก็ได้ที่กำหนดโดยแท็ก @color คุณยังสามารถแก้ไขเพิ่มเติมได้โดยใช้แอตทริบิวต์ที่กำหนดไว้สำหรับแท็กรูปร่าง (ทำมุมโค้งมนทำพื้นหลังวงรี ฯลฯ )

ขั้นตอนต่อไปคือการตั้งค่าพื้นหลังของวิดเจ็ตการค้นหาของเราเป็นอันนี้ สามารถทำได้ดังต่อไปนี้:

    public boolean onCreateOptionsMenu(Menu menu) {

        SearchView searchView = (SearchView)menu.findItem(R.id.my_search_view).getActionView();
        Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
        searchView.setBackground(d);
...
    }

@shkschneider IMHO มันจะใช้ไม่ได้เพราะต้องตั้งพื้นหลังในองค์ประกอบภายในSearchView(ชื่อsearch_plate) ไม่ใช่ในSearchViewตัวมันเอง ดูคำตอบของฉันสำหรับรายละเอียดเพิ่มเติม อย่างไรก็ตามฉันต้องยอมรับว่าฉันไม่ได้พยายามใช้คำตอบของ @ (baba tenor)
vArDo

ไม่ได้สังเกตว่า SearchView อยู่ใน ActionBar ตอนนี้น่าจะใช้ได้แล้ว
Erol

@babatenor สิ่งนี้ใช้ไม่ได้เนื่องจากพื้นหลังของSearchViewตัวมันเองจะอยู่ด้านล่างพื้นหลังสำหรับองค์ประกอบที่อยู่ภายในSearchViewเสมอ มีLinearLayoutมุมมองภายในSearchViewที่มี id search_plateซึ่งชุดนี้มีองค์ประกอบขีดเส้นใต้สีน้ำเงินเป็นพื้นหลัง ดูคำตอบของฉันสำหรับรายละเอียด ดังนั้นด้วยวิธีการแก้ปัญหาของคุณผลลัพธ์คือพื้นหลังสีน้ำเงินสำหรับวิดเจ็ตทั้งหมดที่ยังคงขีดเส้นใต้สีน้ำเงิน ฉันได้ทดสอบกับJelly Beanแล้ว แต่ฉันไม่คิดว่าเวอร์ชันเป้าหมาย SDK มีความสำคัญที่นี่
vArDo

ขอบคุณ vArDo ฉันรู้โครงสร้างเลเยอร์ของ SearchView แต่ฉันแค่คิดว่ามันจะใช้งานได้ (อย่างน้อยก็ดูมีเหตุผลสำหรับฉัน)
Erol

1
@babatenor จะดีมากถ้ามันใช้งานได้ดังนั้นการแฮ็กเกอร์ทั้งหมดนี้จึงไม่จำเป็น :)
vArDo

1
public boolean onCreateOptionsMenu(Menu menu) {
........

        // Set the search plate color
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        View view = searchView.findViewById(linlayId);
        Drawable drawColor = getResources().getDrawable(R.drawable.searchcolor);
        view.setBackground( drawColor );
........
    }

และนี่คือไฟล์ searchchablecolor.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
      <shape >
          <solid android:color="#ffffff" />
      </shape>
  </item>

  <!-- main color -->
  <item android:bottom="1.5dp"
      android:left="1.5dp"
      android:right="1.5dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>

  <!-- draw another block to cut-off the left and right bars -->
  <item android:bottom="18.0dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>
</layer-list>

0

ฉันได้อธิบายไว้ในตอนท้ายของโพสต์นี้พร้อมรูปภาพซึ่งใช้สำหรับแบบฟอร์ม xamarin แต่ฉันคิดว่าคุณเข้าใจได้เพราะมันขึ้นอยู่กับซอร์สโค้ดของ searchview ของ android

วิธีเปลี่ยนภาพปุ่มยกเลิกแถบค้นหาในรูปแบบ xamarin


0

หากคุณกำลังขยาย Searchview เช่นนี้ "getMenuInflater (). inflate (R.menu.search_menu, menu);" จากนั้นคุณสามารถปรับแต่งมุมมองการค้นหานี้ผ่าน style.xml ดังต่อไปนี้

<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
      <item name="searchViewStyle">@style/SearchView.ActionBar</item>
</style>

<style name="SearchView.ActionBar" parent="Widget.AppCompat.SearchView.ActionBar">
      <item name="queryBackground">@drawable/drw_search_view_bg</item>
      <item name="searchHintIcon">@null</item>
      <item name="submitBackground">@null</item>
      <item name="closeIcon">@drawable/vd_cancel</item>
      <item name="searchIcon">@drawable/vd_search</item>
</style>

0

ฉันกำลังขุดคุ้ยเรื่องนั้นมากและในที่สุดฉันก็พบวิธีแก้ปัญหานี้และมันก็เหมาะกับฉัน!
คุณสามารถใช้สิ่งนี้

หากคุณใช้ appcompat ลองสิ่งนี้:

ImageView searchIconView = (ImageView) searchView.findViewById(android.support.v7.appcompat.R.id.search_button);
searchIconView.setImageResource(R.drawable.yourIcon);

หากคุณใช้ androidx ลองสิ่งนี้:

ImageView searchIconView = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button);
    searchIconView.setImageResource(R.drawable.yourIcon);

มันจะเปลี่ยนไอคอน serchview เริ่มต้น

หวังว่าจะช่วยได้!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.