Android: animate searchview

2019-02-24 22:41发布

问题:

I'm trying to implement an animated searchview (with a simple extend/collapse animation) but all the answers in this forum are not working.

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

what i've done

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    //Get the ID for the search bar LinearLayout
    int searchBarId = searchView.getContext().getResources().getIdentifier("android:id/search_bar", null, null);
    //Get the search bar Linearlayout
    LinearLayout searchBar = (LinearLayout) 
            searchView.findViewById(searchBarId);
    //Give the Linearlayout a transition animation.
    searchBar.setLayoutTransition(new LayoutTransition());
    return true;
}

all the error:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.daveslab.wideview, PID: 2459
              java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.LinearLayout.setLayoutTransition(android.animation.LayoutTransition)' on a null object reference
                  at com.daveslab.wideview.MainActivity.onCreateOptionsMenu(MainActivity.java:69)
                  at android.app.Activity.onCreatePanelMenu(Activity.java:2846)
                  at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:360)
                  at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:88)
                  at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onCreatePanelMenu(AppCompatDelegateImplBase.java:331)
                  at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:88)
                  at android.support.v7.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:454)
                  at android.support.v7.app.ToolbarActionBar$1.run(ToolbarActionBar.java:61)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:148)
                  at android.app.ActivityThread.main(ActivityThread.java:5417)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

errors in values.xml(all the icons are in the project with the correct name):

Error:(1605, 21) No resource found that matches the given name: attr 'searchBackIcon'.

Error:(1602, 21) No resource found that matches the given name: attr 'searchBackground'. Error:(1604, 21) No resource found that matches the given name: attr 'searchCloseIcon'. Error:(1606, 21) No resource found that matches the given name: attr 'searchSuggestionBackground'. Error:(1603, 21) No resource found that matches the given name: attr 'searchVoiceIcon'. Error:(1605, 21) No resource found that matches the given name: attr 'searchBackIcon'. Error:(1602, 21) No resource found that matches the given name: attr 'searchBackground'. Error:(1604, 21) No resource found that matches the given name: attr 'searchCloseIcon'. Error:(1606, 21) No resource found that matches the given name: attr 'searchSuggestionBackground'. Error:(1603, 21) No resource found that matches the given name: attr 'searchVoiceIcon'. Error:Execution failed for task ':app:processDebugResources'. com.android.ide.common.process.ProcessException: Failed to execute aapt.

回答1:

There is an easier approach (in fact, just two more lines of code) and it's bug-free. What you have to do is populating your SearchView in the onCreateOptionsMenu() method like you would have done before, but avoiding the lines of code where you set the transition, as they are not needed anymore.

Next, override onOptionsItemSelected() like this:

@Override
public boolean onOptionsItemSelected(final MenuItem item) {
    switch(item.getItemId()) {
        case R.id.action_search:
            TransitionManager.beginDelayedTransition((ViewGroup) getActivity().findViewById(R.id.toolbar));
            MenuItemCompat.expandActionView(item);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

This code prepares a transition and listens for changes in the toolbar layout. When the SearchView appears, the animation starts. It uses the same API as KitKat but it is available starting with ICS. In your build.gradle:

compile 'com.android.support:transition:24.2.1'

You can also customize the transition if you don't like the default one.



回答2:

This might be helpful for you.But accept the answer if it solves your problem.So,It will help others too.

SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
//Get the ID for the search bar LinearLayout
int searchBarId = searchView.getContext().getResources().getIdentifier("android:id/search_bar", null, null);
//Get the search bar Linearlayout
 LinearLayout searchBar = (LinearLayout)       
 searchView.findViewById(searchBarId);
 //Give the Linearlayout a transition animation.
 searchBar.setLayoutTransition(new LayoutTransition());

Styles.xml

  <style name="MaterialSearchViewStyle">
    <item name="searchBackground">@color/white_ish</item>
    <item name="searchVoiceIcon">@drawable/ic_action_voice_search</item>
    <item name="searchCloseIcon">@drawable/ic_action_navigation_close</item>
    <item name="searchBackIcon">@drawable/ic_action_navigation_arrow_back</item>
    <item name="searchSuggestionBackground">@color/search_layover_bg</item>
    <item name="android:textColor">@color/black</item>
    <item name="android:textColorHint">@color/gray_50</item>
    <item name="android:hint">@string/search_hint</item>
    <item name="android:inputType">textCapWords</item>
</style>

Use that style in your xml

<item
android:id="@+id/action_search"
android:orderInCategory="100"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
android:icon="@drawable/ic_search_white_48px"
app:showAsAction="always"
 style="@style/MaterialSearchViewStyle"/>


回答3:

I am bit late to answer but above answers not worked for me.

     SearchView searchView;
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.application_menu, menu);
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) menu.findItem(R.id.app_bar_search).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        LinearLayout searchBar = (LinearLayout) searchView.findViewById(R.id.search_bar);
        searchBar.setLayoutTransition(new LayoutTransition());
 return super.onCreateOptionsMenu(menu);
        }

And my application_menu.xml

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

    <item
        android:id="@+id/app_bar_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="Search"
        app:showAsAction="ifRoom"
         />

</menu>