I have a ListActivity where I make this
Cursor cursor = getContentResolver().query(Phone.CONTENT_URI,
new String[] { Phone._ID, Phone.DISPLAY_NAME }, null, null,
null);
startManagingCursor(cursor);
String[] columns = new String[] { Phone.DISPLAY_NAME };
int[] to = new int[] { R.id.name_row };
ListAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.contact_list_row, cursor, columns, to);
this.setListAdapter(mAdapter);
which binds my contacts names no my listadapter. Every row is a checkedtext view, so know I want to create a method to retrieve my checked items, but I can't get it to work. Can some one point me in the right direction?
I'm not 100% sure about checkboxes but I've done this for buttons and other elements and, having had a quick look around, I think this method is the same.
Insert android:onClick="methodName" in the checkbox element layout XML.
in your code have something similar to this function:
//Called from XML
public void methodName(View view) {
int cursorPosition= getListView().getPositionForView(view);
Bundle itemData = (Bundle) mAdapter.getItem(cursorPosition);
// do something with data
}
So I found my way. The problem was that I was using checked_positions.get(i) instead of checked_positions.valueAt(i).
ListView lv = getListView();
SparseBooleanArray checked_positions = lv.getCheckedItemPositions();
for (int i = 0; i < checked_positions.size(); i++) {
Log.d(TAG, "Checked " + i + " Value " + checked_positions.valueAt(i));
if (checked_positions.valueAt(i)) {
Cursor ctv = (Cursor) lv.getItemAtPosition(checked_positions.keyAt(i));
}
}
Related
I have two AutoCompleteTextViews that are populated with data from sqlite database. I pull information from an ERP Server and store it locally in the sqlite database and populate the textview like in this:
equipment = (AutoCompleteTextView) findViewById(R.id.equipmentAutoCompleteTextView);
if(equipment.getText().toString().length() == 0){
equipment.setError("Equipment is required");
}
FieldInstallationDB sqlitedb1 = new FieldInstallationDB(this);
sqlitedb1.openForRead();
String[] items = sqlitedb.getAllItemNames();
for(int i = 0; i < items.length; i++)
{
Log.i(this.toString(), items[i]);
}
ArrayAdapter<String> adapter1 = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, items);
equipment.setAdapter(adapter1);
equipment.setThreshold(1);
And here:
customerName = (AutoCompleteTextView) findViewById(R.id.customerNameAutoCompleteTextView);
if(customerName.getText().toString().length() == 0){
customerName.setError("Customer Name is required");
}
FieldInstallationDB sqlitedb = new FieldInstallationDB(this);
sqlitedb.openForRead();
String[] accounts = sqlitedb.getAllCustNames();
for(int i = 0; i < accounts.length; i++)
{
Log.i(this.toString(), accounts[i]);
}
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, accounts);
customerName.setAdapter(adapter);
customerName.setThreshold(1);
Assuming I have these:
Black Spoon
Red Spoon
Spoonful
And I start typying "spo", I want to see all three items listed to make a selection. Instead, I get only "Spoonful" coming up. How do I get it to recognise and display all instances(items) that have the letters "spo"?
UPDATE:
After the first comment to my question, I read more articles and updated my code to look like this:
equipment = (AutoCompleteTextView) findViewById(R.id.equipmentAutoCompleteTextView);
if(equipment.getText().toString().length() == 0){
equipment.setError("Equipment is required");
}
FieldInstallationDB sqlitedb1 = new FieldInstallationDB(this);
sqlitedb1.openForRead();
String[] items = sqlitedb1.getAllItemNames();
for(int i = 0; i < items.length; i++)
{
Log.i(this.toString(), items[i]);
}
equipment.setThreshold(1);
SimpleCursorAdapter itemNameAdapter = new SimpleCursorAdapter(
this, android.R.layout.simple_dropdown_item_1line, null, items, toView, 0);
itemNameAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return suggestItemCompletions(constraint);
}
});
itemNameAdapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
public CharSequence convertToString(Cursor cur) {
int index = cur.getColumnIndex(FieldInstallationDB.ITEM_NAME);
return cur.getString(index);
}});
equipment.setAdapter(itemNameAdapter);
Here is the suggestitemcompletions method written in the activity class:
public Cursor suggestItemCompletions(CharSequence str) {
return getContentResolver().query(null, new String[] {FieldInstallationDB.ITEM_NAME}, "(" + FieldInstallationDB.ITEM_NAME + " LIKE ? ", new String[] {"%" + str + "%"}, null);
}
This suggests to use getContentResolver() which does not make sense in my case since I am accessing the database of my application and not of another application. As a result it does not work because I set the URI parameter to null since my database table has no URI. However, if i decide not to use getContentResolver() and query the FieldInstallationDB directly, I get the error at .query() saying cannot resolve method.
UPDATE II:
I used rawQuery() as suggested and it works:
public Cursor suggestItemCompletions(CharSequence str) {
fieldInstDatabase = openForRead();
String sql = "Select "+ ITEM_NAME+ " FROM "+ TABLE_EQUIPMENT+ " WHERE "+ ITEM_NAME + " LIKE ?";
String[] selectArgs = new String[]{ "%" + str + "%"};
return fieldInstDatabase.rawQuery(sql,selectArgs);
}
This method is in my db class and I am calling it in main activity here:
itemNameAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return sqlitedb1.suggestItemCompletions(constraint);
}
});
This is working except that I am getting an IllegalArgumentException here:
01-10 13:07:08.792 5361-5361/com.example.sweetiean.stlfieldinstallation1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sweetiean.stlfieldinstallation1, PID: 5361
java.lang.IllegalArgumentException: column 'Bag(TypeC) :
5900016009' does not exist
which makes sense because "Bag(TypeC) :
5900016009" is not a column, it is the first item in the ITEM NAME column in the database.
I do not know why it is reading the first item as the column name. I have tried to debug but I cannot step into
public Cursor runQuery(CharSequence constraint) {
return sqlitedb1.suggestItemCompletions(constraint);
}
As suggested in the comments, an IllegalArgumentException is occurring here because of the from parameter in my SimpleCursorAdapter. The from and to parameters of the SimpleCursorAdapter require the column name of the table and the textview to populate respectively.
In my case, I was populating the from parameter with a string array of the items I was getting from the database:
String[] items = sqlitedb1.getAllItemNames();
for(int i = 0; i < items.length; i++)
{
Log.i(this.toString(), items[i]);
}
equipment.setThreshold(1);
SimpleCursorAdapter itemNameAdapter = new SimpleCursorAdapter(
this, android.R.layout.simple_dropdown_item_1line, null, items, toView, 0);
Correcting it to:
SimpleCursorAdapter itemNameAdapter = new SimpleCursorAdapter(
this, android.R.layout.simple_dropdown_item_1line, null, fromCol, toView, 0);
With fromCol defined as final static String[] fromCol = new String[] { FieldInstallationDB.ITEM_NAME }; fixed it.
I have serveral objects in my DB with three Strings attributes. One of the shows a date information, eg. 1.4.2016, 20.10.2017. I list these objects in a ListView, but before I want to sort them by their dates.
//
//Show all Data on ListView
//
private void displayListView() {
Cursor cursor = datasource.fetchAllData();
// The desired columns to be bound
String[] columns = {
DatabaseHelper.COLUMN_TITLE,
DatabaseHelper.COLUMN_DESCRIPTION,
DatabaseHelper.COLUMN_DEADLINE,
};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.processobject_title,
R.id.processobject_description,
R.id.processobject_deadline,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.listview_viewlayout,
cursor,
columns,
to,
0);
ListView listView = (ListView) findViewById(R.id.listview);
ArrayList <ProcessObject> arrayList = new ArrayList<>();
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
activateAddButton();
OnItemClickListener();
};
I see two oppurtinities: sorting the cursor, or sorting the Array to[]. But I don't know how.
public Cursor fetchAllData(){
Cursor cursor = database.query(DatabaseHelper.TABLE_DATABASE, columns, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
Solved it:
String orderBy = DatabaseHelper.COLUMN_DEADLINE + " ASC";;
Cursor cursor = database.query(DatabaseHelper.TABLE_DATABASE, columns, null, null, null, null, orderBy);
I have build an app that take data with different attribute, adds them in the database and then shows it through a ListView.
I have done the part where data are added, but I Can't figure out how to fetch it(for now I just want the name) from the database and populate it in the ListView.
Here is the part in the database class.
public Cursor getCursor() {
Cursor c = null;
sqLiteDatabase = this.getReadableDatabase();
String query = "SELECT * FROM tbl_customer";
String where = null;
c = sqLiteDatabase.query("tbl_customer", new String[]{"Name"}, where, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
here is the part of code in activity which I want to show the ListView in.
private void populateListView(){
Cursor cursor = db.getCursor();
String []From = new String[]{"Name"};
int [] to = new int[R.id.textView];
SimpleCursorAdapter adapter;
adapter = new SimpleCursorAdapter(this,R.layout.listview_items,cursor,From,to,0);
ListView listView = (ListView)findViewById(R.id.ShowDataListView);
listView.setAdapter(adapter);
}
Please guide me, where I have gone wrong, and correct me.
you are using R.id.textView as a size of array
int [] to = new int[R.id.textView];
it should be like this
int [] to = new int[]{R.id.textView};
You've to specify the From and To params of the SimpleCursorAdapter.
adapter = new SimpleCursorAdapter(this,R.layout.listview_items,cursor,
new String[] { "Name" },to,0);
As for to, you need to put the id of your textview from R.layout.listview_items. Let's assume the id of your TextView is R.id.text1 then the adapter will look like following,
adapter = new SimpleCursorAdapter(this,R.layout.listview_items,cursor,
new String[] { "Name" },
new int[] { android.R.id.text1 },
0);
Here, have a look at the documentation to grasp it more clearly.
Right now, my app filters the data in a listview when somethings is entered into the editText, but it can only filter by one thing at a time. I want it to be able to filter by more than value. For example, if someone types in "chicken" it should filter the recipes by the word 'chicken'. But, if someone then types in "dinner", I want it to filter the recipes by both "chicken" and "dinner." Eventually, I want to make it so those values appear as checkboxes above the listview so they can be easily removed.
I can't figure out how to do this. I played around with loops at first but didn't really get anywhere.
public class SearchActivity extends NavDrawerActivity {
private DBHandler dbHelper;
private SimpleCursorAdapter dataAdapter;
ArrayList<String> filters = new ArrayList<String>();
//String[] filters;
FrameLayout frameLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main_activity3);
frameLayout = (FrameLayout) findViewById(R.id.activity_frame);
// inflate the custom activity layout
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = layoutInflater.inflate(R.layout.activity_main_activity3, null, false);
// add the custom layout of this activity to frame layout.
frameLayout.addView(activityView);
dbHelper = new DBHandler(this, null, null, 1);
//dbHelper.open();
//Clean all data
dbHelper.deleteAllRecipes();
//Add some data
dbHelper.insertSomeRecipes();
//Generate ListView from SQLite Database
displayListView();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private void displayListView() {
final Cursor cursor = dbHelper.fetchAllRecipes();
// The desired columns to be bound
String[] columns = new String[]{
//DBHandler.COLUMN_CODE,
DBHandler.COLUMN_NAME,
DBHandler.COLUMN_TYPE,
DBHandler.COLUMN_INGRED
};
// the XML defined views which the data will be bound to
int[] to = new int[]{
//R.id.code,
R.id.name,
R.id.type,
R.id.ingredient,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.recipeinfo,
cursor,
columns,
to,
0);
ListView listView = (ListView) findViewById(R.id.listView1);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
String recipeName = cursor.getString(cursor.getColumnIndexOrThrow("name"));
Intent n = new Intent(getApplicationContext(), RecipeActivity.class);
//n.putExtra("position", position);
n.putExtra("recipeName", recipeName);
startActivity(n);
}
});
//final GridView gridView = (GridView)findViewById(R.id.gridView);
final TextView tv = (TextView)findViewById(R.id.textView14);
final EditText myFilter = (EditText) findViewById(R.id.myFilter);
myFilter.setImeActionLabel("Filter",1);
myFilter.setPrivateImeOptions("actionUnspecified");
myFilter.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == 1 || id == EditorInfo.IME_NULL) {
String filter = textView.getText().toString();
dataAdapter.getFilter().filter(filter);
filters.add(filter);
tv.append(filter);
myFilter.setText("");
}
return false;
}
});
dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return dbHelper.fetchRecipesByName(constraint.toString());
}
});
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Then you start a new Activity via Intent
Intent intent = new Intent();
intent.setClass(this, RecipeActivity.class);
intent.putExtra("position", position);
// Or / And
intent.putExtra("id", id);
startActivity(intent);
}
}
fetchRecipesByName in DBHandler
public Cursor fetchRecipesByName(String inputText) throws SQLException {
SQLiteDatabase mDb = this.getWritableDatabase();
Log.w(TAG, inputText);
Cursor mCursor = null;
if (inputText == null || inputText.length () == 0) {
mCursor = mDb.query(SQLITE_TABLE, new String[] {COLUMN_ROWID,
COLUMN_NAME, COLUMN_TYPE, COLUMN_INGRED, COLUMN_IMGPATH},
null, null, null, null, null);
}
else {
mCursor = mDb.query(true, SQLITE_TABLE, new String[] {COLUMN_ROWID,
COLUMN_NAME, COLUMN_TYPE, COLUMN_INGRED, COLUMN_IMGPATH},
COLUMN_NAME + " like '%" + inputText + "%'" + " or " +
COLUMN_TYPE + " like '%" + inputText + "%'" + " or " +
COLUMN_INGRED + " like '%" + inputText + "%'",
null, null, null, null, null);
}
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
What is the implementation of dbHelper.fetchReccipesByName()? I think, as of now, it queries the table only by one thing. You should change its logic and implement your complex need in this method (obviously, it should be an SQL query execution).
As a best practice, you should call listView.setFilterText() instead of dataAdapter.getFilter().filter(), because this method is supposed to run in secondary thread for the reason that DB queries are time consuming. If you call listView.setFilterText(), the framework will take care of threading and calls filter.filter() in secondary thread.
And finally, since you are searching by more than one keyword, but setFilterText() accepts only one CharSequence param, you should encode somehow many keywords into single String (say comma separated). And while querying you could decode the constraint to get the keywords.
I am trying to display some data from DB in Activity 2 after starting intent from Activity 1, like:
{ case R.id.buttonRead:
intent = new Intent(this, ListDataActivity.class);
startActivity(intent);
break;
}
ListDataActivity has the following coding:
{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_data);
ListView lv = (ListView) findViewById(R.id.view_all_data);
String[] from = new String[] { DBHelper.COLUMN_NAME,
DBHelper.COLUMN_LAST_NAME };
int[] to = new int[] { R.id.textView_name_reflect,
R.id.textView_last_name_reflect };
// create Adapter
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.item, datasource.getAllEmployees(), from, to,
FLAG_REGISTER_CONTENT_OBSERVER);
// make adapter available for list
lv.setAdapter(adapter);
}
ListDataActivity in Manifest stays without Intent Filter.
When I click button and start ListDataActivity app. crashes with NullPointerException.
Most interesting is that when I delete ListView from onCreate ListDataActivity runs in normal way displaying blank screen. Could you please tell me what is wrong?
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_all_data"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
method from DataSource
public Cursor getAllEmployees() {
Log.d(LOG_TAG, "--- Rows in mytable: ---");
// make query of all data from the table and receive instance of Cursor
Cursor c = db.query(DBHelper.TABLE_STAFF, null, null, null, null, null,
null);
return c;
}
Have tried the following
case R.id.buttonRead:
ArrayList<String> value = datasource.getAllEmployees();
intent.putStringArrayListExtra("123", (ArrayList<String>)value);
startActivity(intent);
break;
}
changed
public ArrayList<String> getAllEmployees() {
ArrayList<String> empList = new ArrayList<String>();
empList.add("Start");
return empList;
}
as well as ListDataActivity
Intent intent = getIntent();
ArrayList<String> value = intent.getStringArrayListExtra("123");
ListView lv = (ListView) findViewById(R.id.view_all_data);
// create Adapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, value);
// make adapter available for list
lv.setAdapter(adapter);
and it worked fine
Have changed my getAllEmployees to see if everything correct with DB
public void getAllEmployees() {
open();
Log.d(LOG_TAG, "--- Rows in mytable: ---");
// make query of all data from the table and receive instance of Cursor
Cursor c = db.query(DBHelper.TABLE_STAFF, null, null, null, null, null,
null);
// put cursor into position of the first row of required data, if no
// rows false will return
if (c.moveToFirst()) {
// get columns numbers
int idColIndex = c.getColumnIndex(DBHelper.COLUMN_ID);
int nameColIndex = c.getColumnIndex(DBHelper.COLUMN_NAME);
int lastnameColIndex = c.getColumnIndex(DBHelper.COLUMN_LAST_NAME);
int positionColIndex = c.getColumnIndex(DBHelper.COLUMN_POSITION);
int departmentColIndex = c
.getColumnIndex(DBHelper.COLUMN_DEPARTMENT);
int inttelColIndex = c.getColumnIndex(DBHelper.COLUMN_INT_TEL);
int mobileColIndex = c.getColumnIndex(DBHelper.COLUMN_MOB_TEL);
int homeColIndex = c.getColumnIndex(DBHelper.COLUMN_HOME_TEL);
int officemailColIndex = c
.getColumnIndex(DBHelper.COLUMN_OFFICE_E_MAIL);
int personalmailColIndex = c
.getColumnIndex(DBHelper.COLUMN_PERSONAL_E_MAIL);
do {
// getting values by column numbers and put them into log
Log.d(LOG_TAG,
DBHelper.COLUMN_ID + c.getInt(idColIndex) + "\n"
+ DBHelper.COLUMN_NAME
+ c.getString(nameColIndex)
+ DBHelper.COLUMN_LAST_NAME
+ c.getString(lastnameColIndex)
+ DBHelper.COLUMN_POSITION
+ c.getString(positionColIndex)
+ DBHelper.COLUMN_DEPARTMENT
+ c.getString(departmentColIndex)
+ DBHelper.COLUMN_INT_TEL
+ c.getString(inttelColIndex)
+ DBHelper.COLUMN_MOB_TEL
+ c.getString(mobileColIndex)
+ DBHelper.COLUMN_HOME_TEL
+ c.getString(homeColIndex)
+ DBHelper.COLUMN_OFFICE_E_MAIL
+ c.getString(officemailColIndex)
+ DBHelper.COLUMN_PERSONAL_E_MAIL
+ c.getString(personalmailColIndex));
// move to next row, if no next then end loop
} while (c.moveToNext());
} else
Log.d(LOG_TAG, "0 rows");
c.close();
}
verything works fine with Logs when I call datasource.getAllEmployees(); from MainActivity but when I try to call it from ListDataActivity app crashes.
Can someone explain me what is going on?
Have checked DB everything works fine. When put ListView into the MainActivity everything works fine as well. WHY IT DOES NOT WORK with another Activity?
you forget use datasource.open() or datasource = new YOURCLASS(this) in your Oncreate() method
Sorry for being annoying to stackoverflow community but it seems that long delay in practicing Android has played a trick with me. Simply forgot to declare variable of DataSource class. PEOPLE be ATTENTIVE to what you do, to yourself and to surrounders!