Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-11604] Android: Support search widget in action bar

GitHub Issuen/a
TypeNew Feature
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2013-01-17T17:18:12.000+0000
Affected Version/sRelease 3.0.0
Fix Version/sRelease 3.0.2, Release 3.1.0, 2013 Sprint 02 API, 2013 Sprint 02
ComponentsAndroid
Labelsapi, module_actionbar, qe-port, qe-testadded, triage
ReporterArthur Evans
AssigneeHieu Pham
Created2012-10-29T21:33:50.000+0000
Updated2014-04-30T22:58:49.000+0000

Description

To enable native-style search functionality, we should support the Android search widget (SearchView), which can be embedded in the action bar, as an alternative to the Ti SearchBar component. This could be implemented either using a lot of magic (so that if a search bar is inserted into the action bar and a table view, it appears in the action bar and acts on the table view), or it could be implemented as a separate object that can only be used in the action bar, and the user could link it up to a (hidden) search bar inserted into a table view. The latter approach is cleaner, but requires a little more work on the part of the user. Testing code:
var searchView = Ti.UI.Android.createSearchView();
var win = Ti.UI.createWindow({
    backgroundColor: 'blue',
    fullscreen: false,
    activity: {
        onCreateOptionsMenu: function(e) {
            var menu = e.menu;
            var menuItem = menu.add({
                actionView : searchView,
                icon: Ti.Android.R.drawable.ic_menu_search,
                showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM | Ti.Android.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
            });
            menuItem.addEventListener("click", function(e) {
                Ti.API.info("I was clicked");
            });
        }
    }
});


// create table view data object
var data = [];

data[0] = Ti.UI.createTableViewRow({hasChild:true,title:'Row 1'});
data[1] = Ti.UI.createTableViewRow({hasDetail:true,title:'Row 2'});
data[2] = Ti.UI.createTableViewRow({hasCheck:true,title:'Row 3'});
data[3] = Ti.UI.createTableViewRow({title:'Row 4'});

// create table view
var tableview = Titanium.UI.createTableView({
	data:data,
	search:searchView,
        searchAsChild: false
});


// create table view event listener
tableview.addEventListener('click', function(e)
{
	// event data
	var index = e.index;
	var section = e.section;
	var row = e.row;
	var rowdata = e.rowData;
	Titanium.UI.createAlertDialog({title:'Table View',message:'row ' + row + ' index ' + index + ' section ' + section  + ' row data ' + rowdata}).show();
});

var hide = Titanium.UI.createButtonBar({
	labels:['Hide', 'Show'],
	backgroundColor:'#336699',
	height:25,
	width:120
});


// add table view to the window
win.add(tableview);

hide.addEventListener('click', function(e)
{
	Ti.API.info("search hidden = "+tableview.searchHidden);
	if (e.index === 0)
	{
		tableview.searchHidden = true;
	}
	else if (e.index === 1)
	{
		tableview.scrollToTop(0,{animated:true});
	}
});

win.open();
1. Run the above code with target API 11 - add this line in manifest section in tiapp.xml:
  <uses-sdk android:targetSdkVersion="11"/>
2. Click on the search icon (top right corner) and make sure you can search for the tableview content

Comments

  1. Arthur Evans 2012-12-07

    BTW, I have the basics of this working as a module. Pretty simple, but available if it's of any use.
  2. Hieu Pham 2013-01-04

    PR #3659
  3. Ping Wang 2013-01-17

    Expanded test case to test events:
       var searchView = Ti.UI.Android.createSearchView({
       	hintText: "hint",
       	submitEnabled: true
       });
       
       searchView.addEventListener("blur", function(){
       	Ti.API.info("******************* searchView: blur");
       });
       
       searchView.addEventListener("focus", function(){
       	Ti.API.info("******************* searchView: focus");
       });
       
       searchView.addEventListener("change", function(){
       	Ti.API.info("******************* searchView: change");
       });
       
       searchView.addEventListener("cancel", function(){
       	Ti.API.info("******************* searchView: cancel");
       });
       
       searchView.addEventListener("submit", function(){
       	Ti.API.info("******************* searchView: submit");
       });
       
       var win = Ti.UI.createWindow({
           backgroundColor: 'blue',
           fullscreen: false,
           activity: {
               onCreateOptionsMenu: function(e) {
                   var menu = e.menu;
                   var menuItem = menu.add({
                       actionView : searchView,
                       icon: Ti.Android.R.drawable.ic_menu_search,
                       showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM | Ti.Android.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
                   });
                   menuItem.addEventListener("click", function(e) {
                       Ti.API.info("I was clicked");
                   });
               }
           }
       });
        
        
       // create table view data object
       var data = [];
        
       data[0] = Ti.UI.createTableViewRow({hasChild:true,title:'Row 1'});
       data[1] = Ti.UI.createTableViewRow({hasDetail:true,title:'Row 2'});
       data[2] = Ti.UI.createTableViewRow({hasCheck:true,title:'Row 3'});
       data[3] = Ti.UI.createTableViewRow({title:'Row 4'});
        
       // create table view
       var tableview = Titanium.UI.createTableView({
           data:data,
           search:searchView,
           searchAsChild: false
       });
        
        
       // create table view event listener
       tableview.addEventListener('click', function(e)
       {
           // event data
           var index = e.index;
           var section = e.section;
           var row = e.row;
           var rowdata = e.rowData;
           Titanium.UI.createAlertDialog({title:'Table View',message:'row ' + row + ' index ' + index + ' section ' + section  + ' row data ' + rowdata}).show();
       });
        
       var hide = Titanium.UI.createButtonBar({
           labels:['Hide', 'Show'],
           backgroundColor:'#336699',
           height:25,
           width:120
       });
        
        
       // add table view to the window
       win.add(tableview);
        
       hide.addEventListener('click', function(e)
       {
           Ti.API.info("search hidden = "+tableview.searchHidden);
           if (e.index === 0)
           {
               tableview.searchHidden = true;
           }
           else if (e.index === 1)
           {
               tableview.scrollToTop(0,{animated:true});
           }
       });
        
       win.open();
       
  4. Shyam Bhadauria 2013-01-28

    Search widget is working and returning the searched row from the tableview. Environment used for verification - Titanium SDK: 3.1.0.v20130126182604 Titanium SDK: 3.0.2.v20130126230207 Titanium  Studio:3.0.1.201212181159 Device: Samung GALAXY Tab 620 Android 3.2
  5. Lee Driscoll 2013-10-23

    Please consider re-opening this ticket. This functionality needs to be tested on a window within a TabGroup as I am certain this does not work. jobSearchList.js
       var jobSearch = Alloy.createController("jobSearch").getView();
       
       $.jobSearchList.searchAsChild = false;
       $.jobSearchList.search = jobSearch;
       
       $.jobSearchListWindow.addEventListener('open', function(e){
           
           if( OS_ANDROID ){
               var activity = $.jobSearchListWindow.activity;
                   
               activity.actionBar.setDisplayHomeAsUp(true);
               activity.actionBar.onHomeIconItemSelected = function() {
                   $.jobSearchListWindow.close(Alloy.Globals.Transitions.FADE);
               };
           
               // Menu Item Specific Code
               activity.onCreateOptionsMenu = function(e) {
                   // Search Field
                   var searchField = e.menu.add({
                       actionView: jobSearch
                   });
                   
                   searchField.expandActionView();       
               };
               
               activity.invalidateOptionsMenu();
           }
           
       });
       
    index.js
       $.mainTabGroup.addEventListener('open', function(e) {
       
           if( OS_ANDROID ){
               var activity = $.mainTabGroup.activity,
                   jobSearchListWindow = Alloy.createController("jobSearchList").getView();
       
               // Menu Item Specific Code
               activity.onCreateOptionsMenu = function(e) {
                   var menu = e.menu;
           
                   // Search Button
                   var searchButton = menu.add({
                       title : "Search Jobs",
                       icon  : Ti.Android.R.drawable.ic_menu_search,
                       showAsAction: Ti.Android.SHOW_AS_ACTION_ALWAYS
                   });
                   searchButton.addEventListener('click', function(e){
                       $.mainTabGroup.activeTab.open(jobSearchListWindow);
                   });
               };
       
               activity.invalidateOptionsMenu();
           }
       });
       
    jobSearchList.xml
       <Alloy>
       	<Window id="jobSearchListWindow" fullscreen="false" navBarHidden="false" layout="vertical">
               <TableView id="jobSearchList" top="10">
                   <TableViewRow title="Apple" />
                   <TableViewRow title="Banana" />
                   <TableViewRow title="Orange" />
                   <TableViewRow title="Raspberry" />
               </TableView>
           </Window>
       </Alloy>
       
  6. Mark Mokryn 2014-04-08

JSON Source