Go to ListView specific position by SearchView Android

    As you can see in most of app, there are a SearchView in ActionBar or Toolbar, and layout usally include a ListView in it. By searching, it will filter ListView and give us the satisfactory values. AutoCompleteTextView is a other approach for this feature. Moreover, by this searching action, we can go to a specific position which it's value "look like" search query.
    In this small tip, I will present the way to do this trick, provide how to use SearchView in ActionBar with it's event! Hope this is helpful in your code.

Create SearchView layout in ActionBar

    Every layout in ActionBar will maked through "Menu" (was define xml files in res/menu folder). Create a menu with SearchView like this:

Main activity programmatically code

    Now, we'll build code for running activity. First, initializing ActionBar features by onCreateOptionsMenu method:
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        // Inflate menu to add items to action bar if it is present.
        inflater.inflate(R.menu.menu_main, menu);
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        searchView.setOnQueryTextListener(onQueryTextListener()); // text changed listener
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        return true;
    }
    In this example, I read a text file in assets folder and saving data into an ArrayList (each line is a person name and stored by each ArrayList element) and after that, this Strings List will be shown by ListView. Source code for reading Asset resource file:
private void readTxtFileToList() {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(getAssets().open("friends_list.txt"), "UTF-8"));

            // do reading, usually loop until end of file reading
            String line = reader.readLine();
            while (line != null) {
                line = reader.readLine();
                friendsList.add(line); // add line to array list
            }
        } catch (IOException e) {
            //log the exception
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    In onCreateOptionsMenu method above, we added OnQueryTextListener for SearchView to detect user typing text, app will find if ArrayList has this string or not and smooth scroll to this ListView position by:
listView.smoothScrollToPositionFromTop(position, 0, 200);
Code for onQueryTextListener method:
 private SearchView.OnQueryTextListener onQueryTextListener() {
        return new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                int position = 0;
                while (position < friendsList.size() - 1) {
                    if (friendsList.get(position).toUpperCase().contains(s.toUpperCase())) {
                        listView.smoothScrollToPositionFromTop(position, 0, 200);
                        break;
                    } else {
                        position++;
                    }
                }

                return false;
            }
        };
    }

Customizing SearchView Hint

   By default, when SearchView forcused, it's hint text is "Search...":


   To change this text, first, creating a xml file in res/xml folder:     Open your AndroidManifest.xml and add intent-filter, meta-data in <activity>  scope like this:
    Finally, we have this new "hint layout":


    Okey, you can changed any features of ActionBar/SearchView by customzing your theme in styles.xml, in this example, I don't.

Final Code


    Full code for running activity, most important file:
package info.devexchanges.specificpositonlistview;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import listview.devexchanges.info.specificpositionlistview.R;

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private ArrayList<String> friendsList;
    private ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        friendsList = new ArrayList<>();
        listView = (ListView) findViewById(R.id.list_view);

        readTxtFileToList();
        setListViewHeader();
        setListViewAdapter();
        touchLayoutToHideKeyboard(listView);
    }

    private void setListViewHeader() {
        LayoutInflater inflater = getLayoutInflater();
        View header = inflater.inflate(R.layout.layout_header, listView, false);
        listView.addHeaderView(header, null, false);
    }

    private void setListViewAdapter() {
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, friendsList);
        listView.setAdapter(adapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        // Inflate menu to add items to action bar if it is present.
        inflater.inflate(R.menu.menu_main, menu);
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        searchView.setOnQueryTextListener(onQueryTextListener());
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        return true;
    }

    private SearchView.OnQueryTextListener onQueryTextListener() {
        return new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                int position = 0;
                while (position < friendsList.size() - 1) {
                    if (friendsList.get(position).toUpperCase().contains(s.toUpperCase())) {
                        listView.smoothScrollToPositionFromTop(position, 0, 200);
                        break;
                    } else {
                        position++;
                    }
                }

                return false;
            }
        };
    }

    private void readTxtFileToList() {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(getAssets().open("friends_list.txt"), "UTF-8"));

            // do reading, usually loop until end of file reading
            String line = reader.readLine();
            while (line != null) {
                line = reader.readLine();
                friendsList.add(line); // add line to array list
            }
        } catch (IOException e) {
            //log the exception
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void hideSoftKeyboard(Activity activity) {
        InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
    }

    public void touchLayoutToHideKeyboard(View view) {
        //Set up touch listener for non-text box views to hide keyboard.
        if (!(view instanceof EditText)) {
            view.setOnTouchListener(new View.OnTouchListener() {

                public boolean onTouch(View v, MotionEvent event) {
                    hideSoftKeyboard(MainActivity.this);
                    return false;
                }
            });
        }
    }
}
    And it's layout was very simple:     After running, this screen look like:


    Strings resource:     Layout for ListView header, include it to ListView by setListViewHeader method:

Running application

    I installed this app in Asus Zenfone 4 and here is screen recording demo video:




Share


Previous post
« Prev Post
Next post
Next Post »