Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ Add local search to your Android app     - Computer security perimeter recommendations (Linux)

- Linux process group, session daemon (Linux)

- C ++ free store and heap (Programming)

- Install Java JDK 8 in CentOS 7 / 6.5 / 6.4 (Linux)

- Oracle EBS R12 for Linux installation (Database)

- To install Emacs under CentOS 6.5 (Linux)

- Node.js Getting the basics: Helloworld! (Linux)

- MySQL master-slave database configuration and error handling Raiders (Database)

- Use regular expressions to check whether the input box to enter a URL (Programming)

- Visual Studio Code experience (Linux)

- IOS interview questions Summary (Programming)

- How to Install Android Studio on Ubuntu 15.04 / CentOS7 (Linux)

- ARM runtime environment built from scratch using QEMU emulator (Linux)

- Four IDS intrusion detection tool under Linux environment (Linux)

- Repair Maven project developed default Maven Plugin folder (Linux)

- shell script error dirname: invalid option - b (Database)

- Spark build standalone version cluster (Server)

- Install snort intrusion detection system on Debian (Linux)

- C ++ handling text input (Programming)

- Linux System Tutorial: Fix ImportError: No module named wxversion error (Linux)

 
         
  Add local search to your Android app
     
  Add Date : 2017-08-31      
         
         
         
  Introduction

Search is a basic functional requirement for various applications, and in our case, we have a restaurant application that allows users to easily and quickly search the list of dishes and find what they want. , I will describe my ongoing maintenance of the UI when our existing restaurant application to join the local search function process.I will detail my choice of UI program and its reasons, in addition to activities like adding a GestureOverlayView.

search for

To search for this feature, we need to do a lot of design considerations before we start writing code. What do you want to search for? We want to search the title and description for the user in order to get bigger The result set, and this is because the title does not always tell what the dish actually looks like, and you can also add some hidden metadata search for each item, and for the layout of the search activity, How do I get the result set to display? I started by displaying the result set in a list view, like the activity in the shopping cart view. Then, the menu does not seem to be attractive to click on, because the image is Small, and when I make the picture bigger, the page can be a result of a screen show less.Therefore, I decided to show the list of topics part of the menu lock in the grid view, but not in the Side display a larger detailed view, but will allow the grid view to occupy the entire screen display space, it can easily be different from the general list of dishes now in order to query the detailed view of the individual, the user should use the phone list And then it will be displayed as a dialog-like fragment floating above the interface (see Figure 2), so that the user can quickly click elsewhere to close the item, and then in the other The search needs to be fast and smooth, for users, they want to find the information they want as soon as possible, otherwise they may not find a certain, and depressed The final question is how are we going to handle user privacy? We can design a search function that provides search suggestions based on recent search behavior, or a search function that requires the input of private information from users. This may give information about other people who might You will see what you are searching for and where your personal information will flow, but in our case, because it's just a restaurant application, you do not have to worry about it because people will know what you like What to eat to worry about, but write the application is you need to carefully consider the user privacy.For our application, do not need any private information, it will not record any search items log, and no search terms history record.

The first step in implementing this functionality in our restaurant application is to add a method to our database class to build a new table that stores the search results to be displayed. You can learn more about it here Database settings for the restaurant: Use the database in your Android application. Using a SQLite query, we can easily find the data items we need with just a few lines of code. Here we search for any data item that contains a search term or its Followed by the name of another text or description of the content and we will return all the columns, because we will be in a detailed view of the information displayed.Note that if your database is large, the query may be delayed, And you'll want to show the user a progress bar or rotate the ring during the query.

/ **
* Builds a table of items matching the searchTerm in their name or description
* /
    Public Cursor searchMenuItems (String searchTerm) {
        SQLiteDatabase db = getReadableDatabase ();
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder ();
        Qb.setTables (TABLES.MENU);
        Cursor c = qb.query (db, null, "(" + MenuColumns.NAME + "LIKE & apos;%" + searchTerm + "% & apos;)" +
            "OR (" + MenuColumns.DESCRIPTION + "LIKE & apos;%" + searchTerm + "% & apos;)"
            Null, null, null, null);
        Return c;
    }}

Code sample 1: Query the database method

Next, we need to set the search option on the action bar of the main activity. For more information on setting up the action bar, read this article: Building a dynamic UI for Android devices. The search function will be handled entirely within our application ; We do not want to list the list of applications that have been installed on the device at the beginning of the search, or send an intent to let another search application process it.

Add the following string variable to the MainActivity class: We will use this variable to send the string to be searched for the intent of the search:

/ * Search string label * /
    Public final static String SEARCH_MESSAGE = "com.example.restaurant.MESSAGE";

Code sample 2: Add the class variable for the extended data to the search intent

Update the onCreateOptionsMenu method of the MainActivity:

/ **
    * Initialize the action menu on action bar
    * /
    Public boolean onCreateOptionsMenu (Menu menu) {
        GetMenuInflater (). Inflate (R.menu.action_bar, menu);
 
        // set up the search
        MenuItem searchItem = menu.findItem (R.id.action_search);
        SearchView mSearchView = (SearchView) searchItem.getActionView ();
        SearchItem.setShowAsActionFlags (MenuItem.SHOW_AS_ACTION_IF_ROOM
                | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
        // set up the query listener
        MSearchView.setOnQueryTextListener (new OnQueryTextListener () {
            @Override
            Public boolean onQueryTextSubmit (String query) {
              // start the search intent
              Intent searchIntent = new Intent (MainActivity.this, SearchResultsActivity.class);
              SearchIntent.putExtra (SEARCH_MESSAGE, query);
                StartActivity (searchIntent);
                Return false;
            }}
            @Override
            Public boolean onQueryTextChange (String query) {
                // do nothing in our case
                Return true;
            }}
        });
        
        Return super.onCreateOptionsMenu (menu);
    }}

Code Example 3: Action bar initialization code

And the SearchResultsActivity class:

Public class SearchResultsActivity extends Activity {
 
  TextView mQueryText;
  GridView searchListResults;
  SearchAdapter adapter;
  Vector < com.example.restaurant.MenuFactory.MenuItem> searchList;
 
  @Override
  Public void onCreate (Bundle savedInstanceState) {
    Super.onCreate (savedInstanceState);
 
    SetContentView (R.layout.search_query_grid_results);
    MQueryText = (TextView) findViewById (R.id.txt_query);
 
    // setup the grid view
    SearchListResults = (GridView) findViewById (R.id.search_results);
    SearchList = new Vector < com.example.restaurant.MenuFactory.MenuItem> ();
    // get and process search query here
    Final Intent queryIntent = getIntent ();
    DoSearchQuery (queryIntent);
    Adapter = new SearchAdapter (this, searchList);
    SearchListResults.setAdapter (adapter);
 
    // Listener for grid view
    SearchListResults.setOnItemClickListener (new AdapterView.OnItemClickListener () {
      @Override
      Public void onItemClick (AdapterView < ?> Parent, View v, int position, long id) {
        FragmentTransaction ft = getFragmentManager (). BeginTransaction ();
        Fragment prev = getFragmentManager (). FindFragmentByTag ( "dialog");
        If (prev! = Null) {
          Ft.remove (prev);
        }}
        Ft.addToBackStack (null);
        DialogFragment newFragment = SearchResultsDialogFragment.newInstance (searchList.elementAt (position));
        NewFragment.show (ft, "dialog");
 
      }}
    });
  }}

Code Listing 4: Main search result class (below)

When we build this list, we will also handle what we should do without any matches. If there is no match, we will search the search for a message dialog to let them know, and close the search activity , They will not see a blank interface.

/ **
  * Builds the found item list.
  * /
  Private void doSearchQuery (final Intent queryIntent) {
    // Get the query text
    String message = queryIntent.getStringExtra (MainActivity.SEARCH_MESSAGE);
    // Set the UI field
    MQueryText.setText (message);
 
    RestaurantDatabase dB = new RestaurantDatabase (this);
    MenuFactory mMF = MenuFactory.getInstance ();
    Cursor c = dB.searchMenuItems (message);
    Set < String> categories = new HashSet < String> ();
    While (c.moveToNext ()) {
      String category = c.getString (c.getColumnIndexOrThrow (RestaurantDatabase.MenuColumns.CATEGORY));
      Categories.add (category);
 
      // build a new menu item and add it to the list
      MenuItem item = mMF.new MenuItem ();
      Item.setCategory (category);
      Item.setName (c.getString (c.getColumnIndexOrThrow (RestaurantDatabase.MenuColumns.NAME)));
      Item.setDescription (c.getString (c.getColumnIndexOrThrow (RestaurantDatabase.MenuColumns.DESCRIPTION)));
      Item.setNutrition (c.getString (c.getColumnIndexOrThrow (RestaurantDatabase.MenuColumns.NUTRITION)));
      Item.setPrice (c.getString (c.getColumnIndexOrThrow (RestaurantDatabase.MenuColumns.PRICE)));
      Item.setImageName (c.getString (c.getColumnIndexOrThrow (RestaurantDatabase.MenuColumns.IMAGENAME)));
      SearchList.add (item);
    }}
    C.close ();
 
    // Handle the case of not finding anything
    If (searchList.size () == 0) {
      Intent intent = new Intent (SearchResultsActivity.this, OrderViewDialogue.class);
      Intent.putExtra (OrderViewActivity.DIALOGUE_MESSAGE, "Sorry, no matching items found.");
      StartActivity (intent);
      SearchResultsActivity.this.finish ();
    }}
  }}

Code Sample 4 continued

This part of the class is the mesh view adapter, where we can only do relatively small changes to achieve the reuse from the main menu code itself.We can also adapt the layout file, so keep the UI in the visual consistency with You do not need to start from scratch, as long as the code to facilitate the recycling of this benefit. You may have realized before, I also reuse the OrderViewDialogue, this thing I would like to write a cart for the class, but here can work.

/**
* SearchAdapter to handle the grid view of found items. Each grid item contains
* a view_grid_item which includes a image, name, and price.
*/
class SearchAdapter extends BaseAdapter {
private Vector< com.example.restaurant.MenuFactory.MenuItem> mFoundList;
private LayoutInflater inflater;

public SearchAdapter(Context c, Vector< com.example.restaurant.MenuFactory.MenuItem> list) {
mFoundList= list;
inflater = LayoutInflater.from(c);
}

public int getCount() {
return mFoundList.size();
}

public Object getItem(int position) {
return mFoundList.get(position);
}

public long getItemId(int position) {
return 0;
}

// create a new ItemView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {

View v = convertView;
ImageView picture;
TextView name;
TextView price;

if(v == null) {
v = inflater.inflate(R.layout.view_grid_item, parent, false);
v.setTag(R.id.picture, v.findViewById(R.id.picture));
v.setTag(R.id.grid_name, v.findViewById(R.id.grid_name));
v.setTag(R.id.grid_price, v.findViewById(R.id.grid_price));
}
picture= (ImageView) v.getTag(R.id.picture);
name= (TextView) v.getTag(R.id.grid_name);
price= (TextView) v.getTag(R.id.grid_price);

final MenuItem foundItem = (MenuItem) mFoundList.get(position);

InputStream inputStream = null;
AssetManager assetManager = null;
try {
assetManager = getAssets();
inputStream = assetManager.open(foundItem.imageName);
picture.setImageBitmap(BitmapFactory.decodeStream(inputStream));
} catch (Exception e) {
Log.d("ActionBarLog", e.getMessage());
} finally {
}
name.setText(foundItem.name);
price.setText(foundItem.price);

return v;
}
}
}

Code Sample 4 continued

Another problem that needs to be considered in layout is the horizontal and vertical mode of the screen. The bottom is the search_query_grid_results.xml file in the res / layout-land directory. You can see that numColumns is set to 4, except that the value is 2 , Res / layout-port file with this file is the same.

< ? Xml version = "1.0" encoding = "utf-8"?>
< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
    Android: layout_width = "match_parent"
    Android: layout_height = "match_parent"
    Android: paddingLeft = "5dp"
  Android: paddingRight = "5dp"
  Android: paddingBottom = "5dp"
  Android: paddingTop = "5dp"
    Android: orientation = "vertical">
    < LinearLayout
        Android: layout_width = "match_parent"
        Android: layout_height = "wrap_content"
        Android: orientation = "horizontal">
        < TextView
            Android: layout_width = "wrap_content"
            Android: layout_height = "wrap_content"
            Style = "@ style / FragmentTitle"
            Android: text = "Results For:" />
        < TextView android: id = "@ + id / txt_query"
            Android: layout_width = "wrap_content"
            Android: layout_height = "wrap_content"
            Style = "@ style / OrderTitle" />
    < / LinearLayout>
    < GridView
      Android: id = "@ + id / search_results"
      Android: layout_width = "fill_parent"
      Android: layout_height = "0dp"
      Android: paddingTop = "10dp"
      Android: numColumns = "4"
      Android: verticalSpacing = "10dp"
      Android: horizontalSpacing = "10dp"
      Android: layout_weight = "1"
      Android: stretchMode = "columnWidth"
      Android: gravity = "center" />
< / LinearLayout>

Code Example 5: Search the horizontal layout of the view xml

Gesture Overlay

To exit the search view, we prefer to use the swept gesture to make it to the left or right slide, similar to the rest of the menu view page scroll effect. GestureDetector in such a list view on the run up very well, but with the grid View together will not be effective, so we can only turn to use a GestureOverlayView you see more need to use GestureBuilder application to build a gesture library, the application can then SDK example (for example. Android \ sdk \ Samples \ android-19 \ legacy \ GestureBuilder.) Build and run the application on your snake pendulum and use it to name and create gestures. Add all the gestures you need (in our case , Then swipe the 'gestures' file from your device into the res / raw directory. The application will tell you where to save the gesture file to. In my case, all All we need to do is connect our device via USB and the gesture file is in the root directory.

Once your file is in place, modify the SearchResultsActivity class with the following code:

GestureLibrary gestureLibrary;
GestureOverlayView gestureOverlayView;

Code Example 6: Variable declaration for GestureOverlayView

In the onCreate method, initialize the view, load the library file, and set the listener to do what the user does when a matching gesture is done. Make sure to match the name that you created in the library. Animation We're ready to call the overridePendingTransition When the implementation of it. Enter the animation we specify a value of 0, that is, no animation. You can create an empty animated XML file, and reference it, but there will be a considerable probability of the number of times, the system will be confused, the output of the animation will be executed very quickly.

GestureOverlayView = (GestureOverlayView) findViewById (R.id.gestures);
    // initialize the gesture library and set up the gesture listener
    GestureLibrary = GestureLibraries.fromRawResource (this, R.raw.gestures);
    GestureLibrary.load ();
    GestureOverlayView.addOnGesturePerformedListener (new OnGesturePerformedListener () {
      @Override
      Public void onGesturePerformed (GestureOverlayView view, Gesture gesture) {
        ArrayList < Prediction> prediction = gestureLibrary.recognize (gesture);
        If (prediction.size ()> 0) {
          String action = prediction.get (0) .name;
          // our gesture library contains "left swipe" and "right swipe" gestures
          If ( "left swipe" .equals (action)) {
            // slide out to the left
            SearchResultsActivity.this.finish ();
            OverridePendingTransition (0, R.anim.move_left);
          } Else if ( "right swipe" .equals (action)) {
            // slide out to the right
            SearchResultsActivity.this.finish ();
            OverridePendingTransition (0, R.anim.move_right);
          }}
        }}
 
      }});
    // gesture is transparent (no longer a yellow line)
    GestureOverlayView.setGestureVisible (false);

Code Example 7: Initialize GestureOverlayView in the onCreate method

Here is the animation file move_left.xml: (except that toxDelta is positive and move_right.xml is the same as move_left.xml)

< ? Xml version = "1.0" encoding = "utf-8"?>
< Translate xmlns: android = "http://schemas.android.com/apk/res/android"
    Android: duration = "500"
    Android: fromXDelta = "0"
    Android: toXDelta = "- 100%"
    Android: interpolator = "@ android: anim / decelerate_interpolator"
/>

Code Example 8: Move the animation code to the left

 Note that when used in a GestureOverlayView, your grid view can not have a 0dp layout_height value, because it will really just 0dp, rather than as we would like to expand in a linear layout. In order to our In this case, we set the layout_height to fill_parent. We do not want our gestures to be visible, and I do not want to have a delay waiting for the visible gradient to disappear, so you'll need to set fadeOffset and fadeDuration to 0 .

< Android.gesture.GestureOverlayView
    Android: id = "@ + id / gestures"
    Android: layout_width = "fill_parent"
    Android: layout_height = "fill_parent"
    Android: fadeOffset = "0"
    Android: fadeDuration = "0"
    Android: eventsInterceptionEnabled = "true">
  < GridView
      Android: id = "@ + id / search_results"
      Android: layout_width = "fill_parent"
      Android: layout_height = "fill_parent"
      Android: paddingTop = "10dp"
      Android: numColumns = "4"
      Android: verticalSpacing = "10dp"
      Android: horizontalSpacing = "10dp"
      Android: layout_weight = "1"
      Android: stretchMode = "columnWidth"
      Android: gravity = "center" />
< /android.gesture.GestureOverlayView>

Code Example 9: Get the updated GridView block for the GestureOverlayView for layout xml

to sum up

Now that you've learned that local search can be added to Android applications, and learn how some key UIs make selection decisions, I also point out some of the challenges that can arise and how to avoid them. You should now be able to integrate the search into your own applications, while giving more consideration to the user experience.
     
         
         
         
  More:      
 
- An Example of GoldenGate Extract Process Hang Problem Solving (Database)
- Linux performance monitoring (Linux)
- MySQL DATE_FORMAT () function (Database)
- Hadoop 2.7.1 installation configuration based on availability QJM (Server)
- How to install Kernel 4.0.2 on CentOS 7 (Linux)
- MySQL 5.7 can not log in problem (Database)
- Linux, see picture not resolve the problem (Linux)
- Oracle users to automatically increase the partition table (Database)
- Java input and output common class Scanner (Programming)
- View and modify Linux machine name (Linux)
- Linux IPTables anti-DDOS attack Shell Scripting (Linux)
- C data types is how it is supported by most computer systems (Programming)
- 24 Docker recommendations (Linux)
- Necessity in Java packages (Programming)
- Installation CD audio file extraction tool Flacon (Linux)
- Ubuntu install Tonido private cloud services (Server)
- Configuring Sublime Text Python runtime environment 2 (Linux)
- RAID configuration and management under linux (Server)
- Java thread pool: ExecutorService, Executors (Programming)
- How to make Linux a non-root user uses less than 1024 ports (Linux)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.