工具栏搜索建议主题

时间:2015-06-12 16:38:43

标签: android android-layout android-support-library android-theme android-search

我正在尝试将搜索建议更改为“轻量级主题”。 我正在使用appcompat-v7:22.2.0库并阅读new feature来自定义搜索视图小部件(android.support.v7.widget.SearchView)。

第一部分

工具栏

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

主题

<style name="Main.Theme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/red</item>
    <item name="colorPrimaryDark">@color/red_dark</item>
    <item name="searchViewStyle">@style/Main.Theme.SearchView</item>
</style>

SearchView主题

<style name="Main.Theme.SearchView" parent="Widget.AppCompat.Light.SearchView">
    <item name="voiceIcon">@mipmap/test_icon</item>
</style>

这样我就无法影响搜索视图。要测试它我在搜索视图中更改了语音图标,并且它不会从默认值更改。

第二部分

第二次尝试是覆盖工具栏中的叠加主题:

叠加主题

<style name="Main.Theme.Overlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="searchViewStyle">@style/Main.Theme.SearchView</item>
</style>

通过这种方式,我得到了一些反馈,但我失去了材料设计&#34;,特别是我的#34; old&#34;提示图标,并带有下划线。 我的最终目标是更改搜索建议行背景:

建议行布局

<item name="suggestionRowLayout">@layout/my_custom_layout</item>

我认为我在远方做到这一点......你能帮助我吗?

3 个答案:

答案 0 :(得分:4)

这就是我使用自己的搜索建议的方式......

这是我的CountriesFragment文件,只显示建议中的所有国家/地区名称。

这里的技巧是我提供自定义View to Suggestion列表来显示。

public class CountriesFragment extends Fragment {

    private boolean mSearchCheck;
    private SimpleCursorAdapter mAdapter;
    public static final String TEXT_FRAGMENT = "TEXT_FRAGMENT";
    public static final String CITY_NAME = "cityName";
    private LayoutInflater mInflater;
    private ViewGroup mainContainer;

    private static final String[] COUNTRIES = {
            "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica",
            "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados",
            "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegowina", "Botswana", "Bouvet Island", "Brazil",
            "British Indian Ocean Territory", "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde",
            "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros",
            "Congo", "Congo, the Democratic Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia (Hrvatska)", "Cuba", "Cyprus",
            "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea",
            "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "France Metropolitan", "French Guiana",
            "French Polynesia", "French Southern Territories", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada",
            "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Heard and Mc Donald Islands", "Holy See (Vatican City State)",
            "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran (Islamic Republic of)", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
            "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, Democratic People's Republic of", "Korea, Republic of", "Kuwait", "Kyrgyzstan",
            "Lao, People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya", "Liechtenstein", "Lithuania", "Luxembourg",
            "Macau", "Macedonia, The Former Yugoslav Republic of", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique",
            "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia, Federated States of", "Moldova, Republic of", "Monaco", "Mongolia", "Montserrat", "Morocco",
            "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria",
            "Niue", "Norfolk Island", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines",
            "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russian Federation", "Rwanda", "Saint Kitts and Nevis", "Saint Lucia",
            "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Seychelles", "Sierra Leone", "Singapore",
            "Slovakia (Slovak Republic)", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "Spain", "Sri Lanka",
            "St. Helena", "St. Pierre and Miquelon", "Sudan", "Suriname", "Svalbard and Jan Mayen Islands", "Swaziland", "Sweden", "Switzerland", "Syrian Arab Republic",
            "Taiwan, Province of China", "Tajikistan", "Tanzania, United Republic of", "Thailand", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia",
            "Turkey", "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States",
            "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", "Vietnam", "Virgin Islands (British)", "Virgin Islands (U.S.)",
            "Wallis and Futuna Islands", "Western Sahara", "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
    };

    public static CountriesFragment newInstance(String text) {
        CountriesFragment mFragment = new CountriesFragment();
        Bundle mBundle = new Bundle();
        mBundle.putString(TEXT_FRAGMENT, text);
        mFragment.setArguments(mBundle);
        return mFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        loadHints();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_countries, container, false);
        mInflater = inflater;
        mainContainer = (ViewGroup) rootView.findViewById(R.id.container);
        //rootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.menu, menu);

        SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
        searchView.setQueryHint(this.getString(R.string.search));

        ((EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text))
                .setHintTextColor(getResources().getColor(R.color.nliveo_white));


        searchView.setSuggestionsAdapter(mAdapter);
        searchView.setOnQueryTextListener(onQuerySearchView);
        searchView.setOnSuggestionListener(onQuerySuggestion);

        menu.findItem(R.id.menu_add).setVisible(true);
        menu.findItem(R.id.menu_search).setVisible(true);

        mSearchCheck = false;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case R.id.menu_add:
                addCountry();
                break;

            case R.id.menu_search:
                mSearchCheck = true;
                break;
        }
        return true;
    }

    private void addCountry() {
        final ViewGroup newView = (ViewGroup) mInflater.inflate(R.layout.country_row, mainContainer, false);
        final TextView countryName = (TextView) newView.findViewById(android.R.id.text1);
        countryName.setText(COUNTRIES[(int) (Math.random() * COUNTRIES.length)]);


        final Animation fadeIn = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in);
        final Animation fadeOut = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_out);
        fadeIn.setFillAfter(false);
        fadeOut.setFillAfter(false);

        final ImageButton closeButton = (ImageButton) newView.findViewById(R.id.delete_button);
        closeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                newView.startAnimation(fadeOut);
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mainContainer.removeView(newView);
                    }
                }, fadeOut.getDuration());
            }
        });

        mainContainer.addView(newView, 0);
        newView.startAnimation(fadeIn);
    }

    private SearchView.OnQueryTextListener onQuerySearchView = new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            mSearchCheck = false;
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {
            if (mSearchCheck) {
                // implement your search here
                giveSuggestions(query);
            }
            return false;
        }
    };

    private void giveSuggestions(String query) {
        final MatrixCursor cursor = new MatrixCursor(new String[]{BaseColumns._ID, CITY_NAME});
        for (int i = 0; i < COUNTRIES.length; i++) {
            if (COUNTRIES[i].toLowerCase().contains(query.toLowerCase()))
                cursor.addRow(new Object[]{i, COUNTRIES[i]});
        }
        mAdapter.changeCursor(cursor);
    }

    private SearchView.OnSuggestionListener onQuerySuggestion = new SearchView.OnSuggestionListener() {
        @Override
        public boolean onSuggestionSelect(int position) {
            return false;
        }

        @Override
        public boolean onSuggestionClick(int position) {
            return false;
        }
    };

    private void loadHints() {
        final String[] from = new String[]{CITY_NAME};
        final int[] to = new int[]{android.R.id.text1};
        mAdapter = new SimpleCursorAdapter(getActivity(),
                R.layout.hint_row,
                null,
                from,
                to,
                CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    }
}

这是hint_row.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:background="@color/nliveo_green_colorPrimaryDark"
    android:textColor="@color/nliveo_white"
    android:paddingLeft="15dp"
    android:paddingRight="15dp"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:elevation="3dp"
    android:alpha="0.7" />

具有SearchView的简单菜单文件。 menu.xml

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

    <item
        android:id="@+id/menu_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:icon="@mipmap/ic_search_white_24dp"
        app:showAsAction="ifRoom|collapseActionView"
        android:title="@string/search"/>
    <item
        android:id="@+id/menu_add"
        android:icon="@mipmap/ic_add_white_24dp"
        app:showAsAction="ifRoom"
        android:title="@string/add"/>

</menu>

我得到了这些美好的建议......

Custom Hints

答案 1 :(得分:3)

建议是由系统创建的动态列表,不是活动。所以你不能将光主题应用于它。

相反,您可以使用样式自定义建议,使其感觉像是一个轻松的主题。

使用此hint_row.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="@style/suggestionsTheme"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:gravity="center_vertical"
    android:text="demo"
    android:paddingLeft="15dp"
    android:paddingRight="15dp" />

并应用此风格

<style name="suggestionsTheme" parent="TextAppearance.AppCompat.Light.SearchResult.Subtitle" >
        <item name="android:background">@android:color/white</item>
        <item name="android:textColor">@android:color/black</item>

现在我得到了这个

Light suggestions

您可以根据需要提供更多风格

答案 2 :(得分:0)

我知道我来晚了,但是我认为这对仍在寻找此问题的人会有所帮助。如果使用Toolbar,则建议的解决方案有效。首先,您需要以像belov这样的样式覆盖Toolbar的主题:

<style name="AppTheme.Toolbar" parent="Base.ThemeOverlay.AppCompat.Dark.ActionBar">
        <item name="searchViewStyle">@style/CustomSearchStyle</item>
    </style>

    <style name="CustomSearchStyle" parent="Base.Widget.AppCompat.SearchView.ActionBar">
        <item name="suggestionRowLayout">@layout/custom_search_layout</item>
    </style>

我使用了Dark主题,但是我认为使用Light这个解决方案也是可行的。如您所见,我已经覆盖了工具栏主题的searchViewStylesuggestionRowLayout的{​​{1}},在其中放置了自己的布局:

SearchView

我从原始主题中提取了此布局,并对其进行了一些更改以获取所需的内容。

注意: 不幸的是,我找不到改变最近的标准图标的方法,所以我把它留了下来,因为它对我来说并不重要。

因此,要更改建议项的背景颜色,只需将其添加到根<?xml version="1.0" encoding="utf-8"?> <!-- /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="58dip" android:background="@color/white" style="@style/RtlOverlay.Widget.AppCompat.Search.DropDown"> <!-- Icons come first in the layout, since their placement doesn't depend on the placement of the text views. --> <ImageView android:id="@android:id/icon1" android:layout_width="48dip" android:layout_height="48dip" android:scaleType="centerInside" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" android:tint="@color/black" android:visibility="invisible" style="@style/RtlOverlay.Widget.AppCompat.Search.DropDown.Icon1" /> <ImageView android:id="@+id/edit_query" android:layout_width="48dip" android:layout_height="48dip" android:scaleType="centerInside" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" android:background="?attr/selectableItemBackground" android:visibility="gone" style="@style/RtlOverlay.Widget.AppCompat.Search.DropDown.Query" /> <ImageView android:id="@android:id/icon2" android:layout_width="48dip" android:layout_height="48dip" android:scaleType="centerInside" android:layout_alignWithParentIfMissing="true" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" android:visibility="gone" style="@style/RtlOverlay.Widget.AppCompat.Search.DropDown.Icon2" /> <!-- The subtitle comes before the title, since the height of the title depends on whether the subtitle is visible or gone. --> <TextView android:id="@android:id/text2" style="?android:attr/dropDownItemStyle" android:singleLine="true" android:layout_width="match_parent" android:textColor="@color/black" android:textSize="16sp" tools:text="id/text2" android:layout_height="29dip" android:paddingBottom="4dip" android:gravity="top" android:layout_alignWithParentIfMissing="true" android:layout_alignParentBottom="true" android:visibility="gone" /> <!-- The title is placed above the subtitle, if there is one. If there is no subtitle, it fills the parent. --> <TextView android:id="@android:id/text1" style="?android:attr/dropDownItemStyle" android:singleLine="true" android:textColor="@color/black" tools:text="id/text1" android:textStyle="bold" android:textSize="18sp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_above="@android:id/text2" /> </RelativeLayout> -在我的情况下,我将其更改为白色。您可以自己设定颜色。 我检查了建议,仅使用ID为RelativeLayout的{​​{1}}和ID为ImageView的{​​{1}},因此我对这两个添加了更改。由于在@android:id/icon1主题中默认的最近图标是白色,因此我添加了TextView@android:id/text1可以根据需要进行配置。

我们最近需要做的就是将主题应用于Dark

android:tint="@color/black"

这是我所得到的结果:

enter image description here