i'm making select statement and it works fine
the problem is selecting more than thousands of records ate one and this cause the program too slow.
is there a possibility to select fifty by fifty and when select the first fifty record show them then add the next fifty record to them.
how can i do that .
thanks in advance ...
Use LIMIT/OFFSET Clauses is selection statement
I haven't worked on that but can give some idea reagarding that. You can use AsynTask here. In the doingInbackground() you can get the records and then you can call publishProgress() when 50 records are fetched and update the UI.
UPDATE:
You can use the LIMIT/OFFSET clause that Kiran said to get the limit of the record fetched and can update the UI using AsyncTask.
Here is the code you need to back your AutoCompleteTextView with a cursor adapter.
#Override
protected void onResume() {
super.onResume();
text = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
final AdapterHelper h = new AdapterHelper(this);
Cursor c = h.getAllResults();
startManagingCursor(c);
String[] from = new String[] { "val" };
int[] to = new int[] { android.R.id.text1 };
CursorAdapter adapter = new MyCursorAdapter(this,
android.R.layout.simple_dropdown_item_1line, c,
from, to);
adapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
if (constraint == null) {
return h.getAllResults();
}
String s = '%' + constraint.toString() + '%';
return h.getAllResults(s);
}
});
text.setAdapter(adapter);
}
class MyCursorAdapter extends SimpleCursorAdapter {
public MyCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
}
public CharSequence convertToString(Cursor cursor) {
return cursor.getString(cursor.getColumnIndex("val"));
}
}
The database that I am using has 3k rows of data in it and the Autocomplete works fine.
The things to note are that you need make sure that the your adapter puts the correct value in the text box once a user selects it. Do this with the convertToString method (at the end of the snippet above). You get to this method by extending SimpleCursorAdapter and overriding the method as shown.
Then you need to provide a FilterQueryProvider to your adapter. This allows your query to be run with the where clause of your typed text. If you have a huge dataset, then setting the threshold large enough (either programatically, or in xml) will prevent the filter query running until it will return a suitably sized resultset.
Hope this is useful.
Anthony Nolan
Related
I am reading data from an SQLite database using a cursor and using an adapter to display it in a listView. This works fine but I now want to reduce the amount of data that I show in the listView. At the moment it displays the following:
John Smith, 25, Moday, Consultation, Dr. Harley
Jane Doe, 41, Wednesday, Surgery, Dr. Pope
What I want it to display is:
John Smith, 25, Mo, Con, Harley
Jane Doe, 41, We, Sur, Pope
Basically I want to parse 3 of the strings. The problem is the cursor adapter takes the columns of the database as a string array in its constructor so I don't know where to perform the parsing operation on it. I've tried a number of different options and am getting unrecognised column id errors and other runtime errors. Can anyone point me in the right direction?
The method where the adapter is created:
private void fillList() {
Cursor c = db.getApts();
startManagingCursor(c);
String[] from = new String[] {ModuleDB.KEY_AptCode,
ModuleDB.KEY_AptName,
ModuleDB.KEY_AptAge,
ModuleDB.KEY_AptDay,
ModuleDB.KEY_AptType,
ModuleDB.KEY_AptDoc};
int[] to = new int[] {R.id.Aptcode_entry,
R.id.AptName_entry,
R.id.AptAge_entry,
R.id.Aptday_entry,
R.id.Apttype_entry,
R.id.Aptdoc_entry};
SimpleCursorAdapter aptAdapter =
new SimpleCursorAdapter(this, R.layout.apt_entry, c, from, to);
setListAdapter(aptAdapter);
}
1.) Let your activity implement - ViewBinder
2.) Match your column and use substring
public class YourActivity extends Activity
implements SimpleCursorAdapter.ViewBinder {
adapter.setViewBinder(this); //Put this line after your list creation and setlistAdapter
#Override
public boolean setViewValue(View view, Cursor cursor, int column) {
//Showing for day, similarly for others
int dayColumn = cursor.getColumnIndex(your day column name in quotes);
if (column == dayColumn ) {
String dayString = cursor.getString(dayColumn );
((TextView)view).setText(bodyString.subString(0, 3));
return true; // Return true to show you've handled this column
}
return false;
}
}
Also - #Simon is Right - Using a Custom Adapter that extends a Cursor Adapter is always better because you get a lot more freedom to modify it later if your requirements evolve further. Off the top of my head here is an example of how you can use custom adapter and build a nice list- http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
Not sure what adapter you use, but assuming all the data is shown as single row then I'd extend that one and override toString() method of it.
Don't think you can override toString() on a simple adapter but perhaps this will help?
SimpleCursorAdapter aptAdapter= new SimpleCursorAdapter(this, R.layout.apt_entry, c, from, to);
CursorToStringConverter stringConverter = new CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor cursor) {
return "Hello listview"; // whatever string you want to build using cursor.getString() etc
}
};
aptAdapter.setCursorToStringConverter(stringConverter);
[EDIT] Just checked the docs and SimpleCursorAdapter does not have a toString() method, nor do any of it's super classes.
I am trying to change only one (maybe more) ListView row based on specific condition. I have read many answers on similar questions and tons of other tutorials but I am not able to make anything.
Exactly what I want to achieve is to have row background (easier version) or row picture (I think harder version) set different than others when row from SQLite is set at specific value.
I have got Activity that extends ListActivity and I am setting the ListView adapter like this:
private void refreshList() {
mySQLiteAdapter = new MyDBAdapter(this);
mySQLiteAdapter.open();
String[] columns = { MyDBAdapter.KEY_TITLE, MyDBAdapter.KEY_GENRE,
MyDBAdapter.KEY_PRICE, MyDBAdapter.KEY_ID };
Cursor contentRead = mySQLiteAdapter.getAllEntries(false, columns,
null, null, null, null, MyDBAdapter.KEY_TITLE, null);
SimpleCursorAdapter adapterCursor = new SimpleCursorAdapter(this,
R.layout.row, contentRead, columns, new int[] {
R.id.text1, R.id.detail });
this.setListAdapter(adapterCursor);
mySQLiteAdapter.close();
}
This function is called in onCreate method and in onResume. I want to set different color/image of row where value from column MyDBAdapter.KEY_PRICE is equal to 5. The R.layout.row is my xml file with row design.
Maybe someone can help me with this? Or at least show tutorial describing it?
Simply extend SimpleCursorAdapter and override bindView():
public class MyAdapter extends SimpleCursorAdapter {
public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
if(cursor.getLong(cursor.getColumnIndex(MyDBAdapter.KEY_PRICE)) == 5)
view.setBackgroundColor(0xff00ff00);
else // this will be the default background color: transparent
view.setBackgroundColor(0x00000000);
}
}
You can try to create your custom adapter that extends on SimpleCursorAdapter and inside that, on the method bindView, you can look if the condition you look for is accomplished and make what you want on that method.
http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html#bindView(android.view.View, android.content.Context, android.database.Cursor)
Hope to help :)
I'm using SimpleCursorAdaptor and a ListView to display the values in my SQLite database rows. One of the values in my row is a date (column 'date'). Rather than display this date I need to run this through a method that will return another string based on what the date is. This is the value I want displayed in my list rather than the actual value taken straight from the Database.
In short I wish to display all values from my database table row except for one, where I need to change it before displaying it.
Here is my code:
public class BinCollectionDayListActivity extends ListActivity{
//
private static final String fields[] = { "name", "date", BaseColumns._ID };
//
public void onCreate(Bundle savedInstanceState) {
//
super.onCreate(savedInstanceState);
//
DatabaseHelper helper = new DatabaseHelper(this);
SQLiteDatabase database = helper.getWritableDatabase();
Cursor data = database.query("names", fields, null, null, null, null, null);
CursorAdapter dataSource = new SimpleCursorAdapter(this, R.layout.binrow, data, fields, new int[] { R.id.name, R.id.date });
dataSource.getCursor().requery();
//
ListView view = getListView();
view.setHeaderDividersEnabled(true);
setListAdapter(dataSource);
//
helper.close();
database.close();
}
}
As you can tell I am pretty new to Android development and would love to know what the best approach would be to achieving the desired result.
Thanks in advance,
Tony
Two options that I've used before:
Array Adapter (Preferred):
Create an ArrayAdapter and populate the Cursor data into your ArrayAdapter.
http://anujarosha.wordpress.com/2011/11/17/how-to-create-a-listview-using-arrayadapter-in-android/
ViewBinder: On your Cursor, you can setup/specify a ViewBinder where you can check the data that's about to be mapped, perform some logic on it, and spit out a different result if desired. This is probably exactly what you're looking for, but do consider the ArrayAdapter as it tends to give you better control and it's a pain to switch these things later on.
Changing values from Cursor using SimpleCursorAdapter
I am using a AutoCompleteTextView in my code and loading the list from database using SimpleCursorAdapter.
AutoCompleteTextView cocktailIngredientView = (AutoCompleteTextView) findViewById(R.id.item);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, mCursor,
new String[] { "field" },
new int[] { android.R.id.text1 });
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
cocktailIngredientView.setAdapter(adapter);
cocktailIngredientView.setThreshold(0);
It populates the list correctly but I have two issues:
I want this list to be sorted
Whatever I enter, it displays the complete list. I want it to filter based on matching patterns in the list. e.g. if the list contains values Page, Tools...then if I enter T in the box, the drop-down should show only Tools. The idea is to display options which contain the entered pattern anywhere in the string text.
How can this be done?
You have to tell the adapter what items to display. I tried implementing something similar to this by using a FilterQueryProvider that queries the database for the items that I want to display in the dropdown.
FilterQueryProvider filter = new FilterQueryProvider() {
#Override
public Cursor runQuery(CharSequence constraint) {
// Make a DB query that filters based on the constraint
return //whatever query results;
}
};
myAdapter.setFilterQueryProvider(filter);
As for the situation when you select an item on the list, you have to override the CursorToStringConverter of the SimpleCursorAdapter. Something like:
SimpleCursorAdapter.CursorToStringConverter conv = new SimpleCursorAdapter.CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor cursor) {
int numCol = cursor.getColumnIndexOrThrow("whateverFieldYouNeed");
String term = cursor.getString(numCol);
return term;
}
};
myAdapter.setCursorToStringConverter(conv);
Instead of the CursorToStringConverter you could also use
mAdapter.setStringConversionColumn(mCursor.getColumnIndexOrThrow("whateverFieldYouNeed"));
I have a list of countries in a database. I have created a select country activity that consists of a edit box for filtering and a list which displays the flag and country name.
When the activity starts the list shows the entire list of countries sorted alphabetically - works fine. When the customer starts typing into the search box I want the list to be filtered based on their typing. My database query was previously working in an AutoCompleteView (I just want to switch to a separate text box and list) so I know my full query and my constraint query are working. What I did was add a TextWatcher to the EditText view and every time the text is changed I invoke the list's SimpleCursorAdapter runQueryOnBackgroundThread with the edit boxes text as the constraint. The trouble is the list is never updated. I have set breakpoints in the debugger and the TextWatcher does make the call to runQueryOnBackgroundThread and my FilterQueryProvider is called with the expected constraint. The database query goes fine and the cursor is returned.
The cursor adapter has a filter query provider set (and a view binder to display the flag):
SimpleCursorAdapter adapter = new SimpleCursorAdapter (this,
R.layout.country_list_row, countryCursor, from, to);
adapter.setFilterQueryProvider (new CountryFilterProvider ());
adapter.setViewBinder (new FlagViewBinder ());
The FitlerQueryProvider:
private final class CountryFilterProvider implements FilterQueryProvider {
#Override
public Cursor runQuery (CharSequence constraint) {
Cursor countryCursor = myDbHelper.getCountryList (constraint);
startManagingCursor (countryCursor);
return countryCursor;
}
}
And the EditText has a TextWatcher:
myCountrySearchText = (EditText)findViewById (R.id.entry);
myCountrySearchText.setHint (R.string.country_hint);
myCountrySearchText.addTextChangedListener (new TextWatcher() {
#Override
public void afterTextChanged (Editable s) {
SimpleCursorAdapter filterAdapter = (SimpleCursorAdapter)myCountryList.getAdapter ();
filterAdapter.runQueryOnBackgroundThread (s.toString ());
}
#Override
public void onTextChanged (CharSequence s, int start, int before, int count) {
// no work to do
}
#Override
public void beforeTextChanged (CharSequence s, int start, int count, int after) {
// no work to do
}
});
The query for the database looks like this:
public Cursor getCountryList (CharSequence constraint) {
if (constraint == null || constraint.length () == 0) {
// Return the full list of countries
return myDataBase.query (DATABASE_COUNTRY_TABLE,
new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE }, null, null, null,
null, KEY_COUNTRYNAME);
} else {
// Return a list of countries who's name contains the passed in constraint
return myDataBase.query (DATABASE_COUNTRY_TABLE,
new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE },
"Country like '%" + constraint.toString () + "%'", null, null, null,
"CASE WHEN Country like '" + constraint.toString () +
"%' THEN 0 ELSE 1 END, Country");
}
}
It just seems like there is a missing link somewhere. Any help would be appreciated.
Thanks,
Ian
I saw that you managed to solve your problem in another way, but thought I should add the answer for other people stumbling upon this question.
runQueryOnBackgroundThread() is only responsible for running a query for a constraint and returning a Cursor. To be able to filter the adapter based on the cursor you need to do something like
filterAdapter.getFilter().filter(s.toString());
A CursorAdapter always implements Filterable by default, and anything that implements filterable can be filtered using getFilter().filter(constraint)
The way that the CursorAdapters built in filter works is that if you either override runQueryOnBackgroundThread() or if you use setFilterQueryProvider() then it runs that code in a background thread, gets a new cursor and sets it as the cursor of the CursorAdapter.
It seems like you're doing a lot of work for something that is already built into Android. Take a look at the Android Search Dialog at http://developer.android.com/guide/topics/search/search-dialog.html, and it should be very easy for you.