Add Autocomplete SearchView in Open Event Android App

The Open Event Android App has a map for showing all locations of sessions. All the locations have a marker in the map. It is difficult to find a particular location on the map because to know the name of location user has to click on the marker. Adding autocomplete SearchView will improve user experience by providing an ability to search the location by name and by suggesting name according to the search query. In this post I explain how to add autocomplete SearchView in the fragment or activity. Add search icon in actionbar The first step to do is to create a menu xml file and add a search menu item in it. Then inflate this menu xml file in Fragment in onCreateOptionsMenu() method. 1. Create menu.xml file In this file add search menu element. Inside menu element add search menu item. Define id, title, and icon of search menu item. Add android.support.v7.widget.SearchView” as actionViewClass which will be used as action view when the user clicks on the icon. <?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" xmlns:tools="http://schemas.android.com/tools"> <item android:id="@+id/action_search" android:icon="@drawable/ic_search_white_24dp" android:title="@string/search" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="ifRoom | collapseActionView"/> </menu> 2. Inflate menu.xml file in Fragment In the fragment’s onCreateOptionsMenu() method inflate menu.xml file using MenuInflater’s inflate() method. Then find search menu item using menu’s findItem() method by passing id of search menu item as parameter. public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.menu_map, menu); MenuItem item = menu.findItem(R.id.action_search); } Add and initialize SearchView   Now after adding search icon we need to add SearchView and SearchAutoComplete fields in the fragment. private SearchView searchView; private SearchView.SearchAutoComplete mSearchAutoComplete; Initialize SearchView in onCreateOptionMenu() method by passing search menu item in the getActionView() method of MenuItemCompat. Here SearchAutoComplete is a child object of SearchView so initialize it using findViewById method of SearchView by passing the id as parameter. searchView = (SearchView) MenuItemCompat.getActionView(item); mSearchAutoComplete = (SearchView.SearchAutoComplete) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text); Define properties of SearchAutoCompleteView By default background of drop down menu in SearchAutoComplete is black. You can change background using setDropDownBackgroundResource() method. Here i’m making it white by providing white drawable resource. mSearchAutoComplete.setDropDownBackgroundResource(R.drawable.background_white); mSearchAutoComplete.setDropDownAnchor(R.id.action_search); mSearchAutoComplete.setThreshold(0) The setDropDownAnchor() method sets the view to which the auto-complete drop down list should anchor. The setThreshold() method specifies the minimum number of characters the user has to type in the edit box before the drop down list is shown. Create array adapter Now it’s time to make the ArrayAdapter object which will provide the data set (strings) which will be used to run search queries. ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, searchItems); Here searchItems is List of strings. Now set this adapter to the mSearchAutoComplete object using setAdapter() method. mSearchAutoComplete.setAdapter(adapter); Now we are all set to run the app on device or emulator. Here’s demo how it will look Conclusion The SearchView with an ability to give suggestions serves the great user experience in the application. Additional resources: SearchView : https://developer.android.com/reference/android/support/v7/widget/SearchView.html AutoCompleteTextView Tutorial : https://www.tutorialspoint.com/android/android_auto_complete.htm Open Event Android PR : https://github.com/fossasia/open-event-android/pull/1749

Continue ReadingAdd Autocomplete SearchView in Open Event Android App

Implementing Search Feature In SUSI Web Chat

SUSI WebChat now has a search feature. Users now have an option to filter or find messages. The user can enter a keyword or phrase in the search field and all the matched messages are highlighted with the given keyword and the user can then navigate through the results. Lets visit SUSI WebChat and try it out. Clicking on the search icon on the top right corner of the chat app screen, we’ll see a search field expand to the left from the search icon. Type any word or phrase and you see that all the matches are highlighted in yellow and the currently focused message is highlighted in orange We can use the up and down arrows to navigate between previous and recent messages containing the search string. We can also choose to search case sensitively using the drop down provided by clicking on the vertical dots icon to the right of the search component. Click on the `X` icon or the search icon to exit from the search mode. We again see that the search field contracts to the right, back to its initial state as a search icon. How does the search feature work? We first make our search component with a search field, navigation arrow icon buttons and exit icon button. We then listen to input changes in our search field using onChange function, and on input change, we collect the search string and iterate through all the existing messages checking if the message contains the search string or not, and if present, we mark that message before passing it to MessageListItem to render the message. let match = msgText.indexOf(matchString); if (match !== -1) { msgCopy.mark = { matchText: matchString, isCaseSensitive: isCaseSensitive }; } We alse need to pass the message ID of the currently focused message to MessageListItem as we need to identify that message to highlight it in orange instead of yellow differentiating between all matches and the current match. function getMessageListItem(messages, markID) { if(markID){ return messages.map((message) => { return ( <MessageListItem key={message.id} message={message} markID={markID}        /> ); }); } } We also store the indices of the messages marked in the MessageSection Component state which is later used to iterate through the highlighted results. searchTextChanged = (event) => { let matchString = event.target.value; let messages = this.state.messages; let markingData = searchMsgs(messages, matchString, this.state.searchState.caseSensitive); if(matchString){ let searchState = { markedMsgs: markingData.allmsgs, markedIDs: markingData.markedIDs, markedIndices: markingData.markedIndices, scrollLimit: markingData.markedIDs.length, scrollIndex: 0, scrollID: markingData.markedIDs[0], caseSensitive: this.state.searchState.caseSensitive, open: false, searchText: matchString }; this.setState({ searchState: searchState }); } } After marking the matched messages with the search string, we pass the messages array into MessageListItem Component where the messages are processed and rendered. Here, we check if the message being received from MessageSection is marked or not and if marked, we then highlight the message. To highlight all occurrences of the search string in the message text, I used a module called react-text-highlight. import TextHighlight from 'react-text-highlight'; if(this.props.message.id === markMsgID){ markedText.push( <TextHighlight key={key} highlight={matchString} text={part} markTag='em' caseSensitive={isCaseSensitive} /> ); }…

Continue ReadingImplementing Search Feature In SUSI Web Chat