This is my first app and i'm having some problem whit ListView
How can I get the ID in the database after clicking on a Item?
I can't use position because the Id may not be continuous and even if it is in order sometimes does not return the correct Id any.
this is my code, Thank you for your help:
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class livello1 extends AppCompatActivity {
DatabaseHelper myDb;
Button next;
#Override
protected void onCreate(Bundle savedInstanceState) {
myDb = new DatabaseHelper(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.livello1);
populateListView();
registerClick();
}
private void registerClick(){
ListView list =(ListView)findViewById(R.id.listViewMain);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
Intent i = new Intent(livello1.this, bossi.note.Edit.class);
i.putExtra("id", position);
//i.putExtra("id", id);
startActivity(i);
}
});
}
private void populateListView(){
Cursor res = myDb.getAllData();
String[] myItems = new String[myDb.numRow()];
int cont = 0;
if(res.getCount() == 0){
// show message
return;
}
while( res. moveToNext()){
myItems[cont] = res.getString(1);
cont ++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.da_item, myItems);
ListView list =(ListView)findViewById(R.id.listViewMain);}
There are a lot of solution approaches.
For example, you can store of Id's if ArrayList before ListView initialization.
That is, execute "SELECT id FROM mytable"
Then store in arraylist and use while click method.
Example:
//in class declaration
private ArrayList<Long> ar_ids = new ArrayList<Long>;
//
String sql = "SELECT id FROM table";
Cursor cur = db.rawQuery(sql, null);
String out = "";
ArrayList<Long> ar_ids = new ArrayList<Long>;
if (cur.moveToFirst()) {
do {
ar.add(cur.getString(0));
} while (cur.moveToNext());
}else{
}
}
cur.close();
for click event:
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
Intent i = new Intent(livello1.this, bossi.note.Edit.class);
i.putExtra("id", ar_id.get(position));
//this is awsome!
startActivity(i);
}
and initialize this something like:
private void myfunc() {
String sql = "SELECT id FROM table";
Cursor cur = myDb.rawQuery(sql, null);
String out = "";
ArrayList<Long> ar_ids = new ArrayList<Long>;
if (cur.moveToFirst()) {
do {
ar.add(cur.getString(0));
} while (cur.moveToNext());
}else{
throw new NullPointerException();
}
}
cur.close();
}
private void populateListView(){
myfunc();
Cursor res = myDb.getAllData();
String[] myItems = new String[myDb.numRow()];
int cont = 0;
if(res.getCount() == 0){
// show message
return;
}
while( res. moveToNext()){
myItems[cont] = res.getString(1);
cont ++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.da_item, myItems);
ListView list =(ListView)findViewById(R.id.listViewMain);}
well instead of using the ArrayAdapter you can extend a BaseAdapter or ListAdapter or even the ArrayAdapter to make your custom adapter. First of all make a plain java class to map your database data including id to an object. Then make a custom BaseAdapter instead of using the ArrayAdapter. In your BaseAdapter class you have to override various methods including getItem and getItemId methods. Now you can return the whole mapped object from the getItem method and simply obtain the object of selected item of the ListView by using listView.getSelectedItem() method in the Activity or Fragment class. Once you get the object you can access the id easily.
You can find a good example and explanation of a custom adapter here
About mapping the database result to an object, you can get some concept here
Here, you can replace you code class with this one, I have added a cursorAdapter and attached it with your ListView, in adapter I have added a method for getting Id that I call from click listener to retrieve id from cursor, you will have to set column number for _ID in public void getId(int position) from MyCursorAdapter class below.
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class livello1 extends AppCompatActivity {
DatabaseHelper myDb;
Button next;
private MyCursorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
myDb = new DatabaseHelper(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.livello1);
populateListView();
registerClick();
}
private void registerClick(){
ListView list =(ListView)findViewById(R.id.listViewMain);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {
Intent i = new Intent(livello1.this, bossi.note.Edit.class);
//retrieve id from cursor
int _id = adapter.getId(position)
i.putExtra("id", _id);
//i.putExtra("id", id);
startActivity(i);
}
});
}
private void populateListView(){
Cursor res = myDb.getAllData();
adapter = new MyCursorAdapter(this, res, 0);
ListView list =(ListView)findViewById(R.id.listViewMain);
list.setAdapter(adapter);
}
//adapter for list view
class MyCursorAdapter extends CursorAdapter {
Cursor cursor;
// Default constructor
public MyCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
this.cursor = cursor;
}
public void bindView(View view, Context context, Cursor cursor) {
String text = cursor.getString(1);
//make sure the TextView id is "#+id/text1" in da_item.xml
TextView tvText = (TextView) view.findViewById(R.id.text1);
tvText.setText(text);
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflator inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
return Inflater.inflate(R.layout.da_item, parent, false);
}
public int getId(int position){
cursor.moveToPosition(position);
int colId = //set id column number here
int id = cursor.getLong(colId);
return id;
}
}
Since the code is untested, you might face a build issue in start, but it should give an idea of what's going on in code. feel free to ask any question if you face any problem in compilation
Related
I have an application that uses sqlite, it stores information about hardware store items and displays them in a ListView, this list view shows the name of the item, the price, the quantity, and the supplier. And each list item also has a Sell button and when I click the button it is supposed to subtract 1 from that specific item's quantity and update the database, but since the button is created in the CursorAdapter Im not sure how to access the database and update it.
This is my CursorAdapter:
package com.example.android.inventoryapp;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.android.inventoryapp.data.InventoryContract.InventoryEntry;
public class InventoryCursorAdapter extends CursorAdapter {
public InventoryCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView itemNameView = view.findViewById(R.id.item_name);
TextView itemPriceView = view.findViewById(R.id.item_price);
TextView itemQuantityView = view.findViewById(R.id.item_quantity);
TextView itemSupplierView = view.findViewById(R.id.item_supplier);
ImageView sellButton = view.findViewById(R.id.sell_button);
int nameColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_NAME);
int priceColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_PRICE);
int quantityColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_QUANTITY);
int supplierColumnIndex = cursor.getColumnIndex(InventoryEntry.COLUMN_ITEM_SUPPLIER);
int quantity = cursor.getInt(quantityColumnIndex);
String name = cursor.getString(nameColumnIndex);
String price = String.valueOf(cursor.getInt(priceColumnIndex)) + context.getString(R.string.currency_symbol);
String quantityStr = String.valueOf(quantity);
String supplier = cursor.getString(supplierColumnIndex);
itemNameView.setText(name);
itemPriceView.setText(price);
itemQuantityView.setText(quantityStr);
itemSupplierView.setText(supplier);
}
}
In your activity that holds the adapter reference, create an inner class something like:
public class MyClickListener {
public void handleClick(Item item) {
// access your DB here, {item} is available if you need the data
}
}
then when you create your adapter
myAdapter = new InventoryCursorAdapter(context, cursor, new MyClickListener());
save the reference to that click listener in your adapter.
then in the adapter's BindView method (if you need the item data to update the database, pass it through the click listener)
sellButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Item item = myItemSet.get(position);
myListener.handleClick(item);
}
});
I have Activity that shows only listview (He pulls the data from SQLite database), There is no limit for the data he can shows, and it work out well.
Now, I want to add a new little listview to the MainActivity which will show only the last five of the data.
I could not find anywhere on the network how to do it..
DataListActivity.java
package com.example.ido.grades;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
public class DataListActivity extends ActionBarActivity {
ListView listView;
SQLiteDatabase sqLiteDatabase;
CourseDbHelper courseDbHelper;
Cursor cursor;
ListDataAdaptar listDataAdaptar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.update_course);
hideActionBar();
listView = (ListView) findViewById(R.id.list_view);
listDataAdaptar = new ListDataAdaptar(getApplicationContext(),R.layout.row_layout);
listView.setAdapter(listDataAdaptar);
registerForContextMenu(listView);
courseDbHelper = new CourseDbHelper(getApplicationContext());
sqLiteDatabase = courseDbHelper.getReadableDatabase();
cursor = courseDbHelper.getInformation(sqLiteDatabase);
registerForContextMenu(listView);
if (!cursor.moveToFirst()){
}
else {
do {
String year,semester,course,points,grade;
year = cursor.getString(0);
semester = cursor.getString(1);
course = cursor.getString(2);
points = cursor.getString(3);
grade = cursor.getString(4);
DataProvider dataProvider = new DataProvider(year,semester,course,points,grade);
listDataAdaptar.add(dataProvider);
}
while (cursor.moveToNext());
}
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_data_list, menu);
}
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int mySelectedRowIndex = info.position;
switch (item.getItemId()) {
case R.id.update_item:
courseDbHelper = new CourseDbHelper(getApplicationContext());
sqLiteDatabase = courseDbHelper.getReadableDatabase();
DataProvider raw2 = (DataProvider)listDataAdaptar.getItem(mySelectedRowIndex);
Intent i = new Intent(DataListActivity.this, UpdateCourseActivity.class);
String year = raw2.getYear();
String semester = raw2.getSemester();
String course = raw2.getCourse();
String points = raw2.getPoints();
String grade = raw2.getGrade();
int semIndex;
if (semester.equals("A'")){
semIndex =1;
}
else if (semester.equals("B'")){
semIndex =2;
}
else{
semIndex=3;
}
i.putExtra("YEAR", year);
i.putExtra("SEMESTER", Integer.toString(semIndex));
i.putExtra("COURSE", course);
i.putExtra("POINTS", points);
i.putExtra("GRADE", grade);
i.putExtra("POS", Integer.toString(mySelectedRowIndex));
startActivity(i);
return true;
case R.id.delete_item:
courseDbHelper = new CourseDbHelper(getApplicationContext());
sqLiteDatabase = courseDbHelper.getReadableDatabase();
DataProvider raw = (DataProvider)listDataAdaptar.getItem(mySelectedRowIndex);
courseDbHelper.deleteInformation(raw.getYear(), raw.getSemester(), raw.getCourse(), raw.getPoints(), raw.getGrade());
Toast.makeText(this,"delete, pos["+mySelectedRowIndex+"]",Toast.LENGTH_LONG).show();
finish();
startActivity(getIntent());
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void onBackPressed() {
startActivity(new Intent(this, MainActivity.class));
}
private void hideActionBar() {
//Hide the action bar only if it exists
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
}
}
ListDataAdapter.java
package com.example.ido.grades;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Ido on 08/08/2015.
*/
public class ListDataAdaptar extends ArrayAdapter{
List list = new ArrayList();
public ListDataAdaptar(Context context, int resource) {
super(context, resource);
}
static class LayoutHandler{
TextView YEAR,SEMESTER,COURSE,POINTS,GRADE;
}
#Override
public void add(Object object) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
LayoutHandler layoutHandler;
if (row == null){
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.row_layout,parent,false);
layoutHandler = new LayoutHandler();
layoutHandler.YEAR = (TextView)row.findViewById(R.id.textYear);
layoutHandler.SEMESTER = (TextView)row.findViewById(R.id.textSemester);
layoutHandler.COURSE = (TextView)row.findViewById(R.id.textCourse);
layoutHandler.POINTS = (TextView)row.findViewById(R.id.textPoints);
layoutHandler.GRADE = (TextView)row.findViewById(R.id.textGrade);
row.setTag(layoutHandler);
}
else{
layoutHandler = (LayoutHandler) row.getTag();
}
DataProvider dataProvider = (DataProvider) this.getItem(position);
layoutHandler.YEAR.setText(dataProvider.getYear());
layoutHandler.SEMESTER.setText(dataProvider.getSemester());
layoutHandler.COURSE.setText(dataProvider.getCourse());
layoutHandler.POINTS.setText(dataProvider.getPoints());
layoutHandler.GRADE.setText(dataProvider.getGrade());
return row;
}
}
You can move to the last position of your current cursor and move to previous rows getting required data. Sort of:
ArrayList string;
if (cursor.moveToLast()){
for (int i = 1; i<=6; i++) {
string.add(cursor.getString(cursor.getColumnIndex("your_data")));
cursor.moveToPrevious();
}
}
cursor.close();
The result will be ArrayList with last 6 strings of your cursor data. You can feed it to the new ArrayAdapter and show it on the screen.
Instead of ArrayList you can create another cursor as well with all existing data and feed it to already existing adapter for example as it's described here:
https://stackoverflow.com/a/18290921/4890659
Ignoring your code, you obviously have an Array of Objects your passing into the constructor of your Array Adapter.
Object[] data = new Object[]{...}
MyArrayAdapter myAdapter = new MyArrayAdapter(data ,... else)
You simply get this data array and append the last 6 elements to a new array.
Object[] data2 = new Object[6]
for(int i = data.length()-7; i<data.length(); i++){
data2[data.length()-i] = data[i]
Then create a new Adapter passing the new data2 array.
MyArrayAdapter myAdapter = new MyArrayAdapter(data2, ... else)
Create method that will return the last 6 rows i cursor [SQL query].
cursor = courseDbHelper.getInformationLast_6(sqLiteDatabase);
SQL:
SELECT * FROM table ORDER BY column DESC [ASC] LIMIT 6;
by this you can get 6 items in your list. Try with following code in your adapter class.
public int getCount() {
return 6;
}
than change your query to limit 6 by ascending order or descending order.
I've written a big code and I've used a list view within one of my task layouts :
I want to know how I can make a listener for each update button in this case in order to move to another activity , I know how to use more than one activity and moves between them But I want to know how to make a listener only .
The custom adapter code :
package com.example.task_9;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class TempLyaout extends ArrayAdapter<String> {
Context context;
ArrayList<String> sa;
public TempLyaout(Context context , ArrayList<String> sa) {
super(context,R.layout.temp,sa);
this.context=context;
this.sa = sa;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater l = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View rowView = l.inflate(R.layout.temp, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.textView1);
ImageView imageView = (ImageView) rowView.findViewById(R.id.imageView1);
Button update = (Button) rowView.findViewById(R.id.button1);
// myDb.open();
// Cursor cursor= myDb.getRowByName(sa.get(position));
// myDb.updateRowByName(cursor.getInt(DBAdapter.COL_ROWID), sa.get(position), cursor.getString(DBAdapter.COL_PASSWD), cursor.getInt(DBAdapter.COL_AGE), isAdmin);
// myDb.close();
textView.setText(sa.get(position));
return rowView;
}
}
This is the related class :
package com.example.task_9;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class UsersActivity extends Activity {
Intent redirect;
ListView list;
ArrayList<String> sa;
DBAdapter myDb;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
protected void onStart() {
super.onStart();
setContentView(R.layout.users);
list= (ListView) findViewById(R.id.usersList);
redirect = getIntent();
openDB();
/*********************************************/
Cursor cursor = myDb.getAllRows();
cursor.moveToFirst();
ArrayList<String> ha = new ArrayList<String>();
while(cursor.moveToNext()) {
ha.add(cursor.getString(DBAdapter.COL_NAME));
}
cursor.close();
#SuppressWarnings("rawtypes")
ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,ha);
list.setAdapter(new TempLyaout(UsersActivity.this,ha));
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
"Click ListItem Number " + position, Toast.LENGTH_LONG)
.show();
}
});
} // end onStart method
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
protected void onDestroy() {
super.onDestroy();
closeDB();
}// end onDestroy method
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void openDB() {
myDb = new DBAdapter(this);
myDb.open();
} // end openDB method
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void closeDB() {
myDb.close();
} // end closeDB method
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
}// end main class
In your getView
Button update = (Button) rowView.findViewById(R.id.button1);
update.setOnClickListener(mClickListener);
Then
private OnClickListener mClickListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(ListActivtiy.this,SecondActivity.class);
startActivity(intent);
}
};
Also use a viewholder for smooth scrolling and performance
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
I have switched from a ResourceCursorAdapter where I used newView and bindView to a SimpleCursorAdapter where I am using only the getView method.
Now I have an error in onLoaderFinished. Although it gives me NullPointerException on adapter.swapCursor(cursor) both my adapter and cursor object are NOT null. I will post all of my code below. Any help is greatly appreciated (not got much hair left to pull out).
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.ResourceCursorAdapter;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
public class ContactSelect extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int LOADER_ID = 1;
private MyAdapter adapter;
private ListView list;
private View row;
private SparseBooleanArray checkedState = new SparseBooleanArray();
#SuppressLint({ "NewApi", "NewApi" })
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_contact_select);
adapter = new MyAdapter(this, R.layout.contacts_select_row, null, null, null, 0);
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
list = (ListView)findViewById(R.id.list);
list.setAdapter(adapter);
list.setEmptyView(findViewById(R.id.empty));
}
#SuppressLint("NewApi")
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
final String projection[] = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
final Uri uri = ContactsContract.Contacts.CONTENT_URI;
final String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1" +
" AND " + ContactsContract.Contacts.IN_VISIBLE_GROUP + " =1";
final String order = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
final CursorLoader loader = new CursorLoader(this, uri, projection, selection, null, order);
return loader;
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
for(int i=0;i<cursor.getCount();i++){
checkedState.put(i, false);
}
adapter.swapCursor(cursor);
}
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
private class MyAdapter extends SimpleCursorAdapter implements OnClickListener{
private CheckBox markedBox;
private TextView familyText;
private Context context;
private Cursor cursor;
public MyAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.context = context;
this.cursor = getCursor();
}
#Override
public View getView(int position, View view, ViewGroup group) {
final LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(R.layout.contacts_select_row, group, false);
view.setTag(cursor.getPosition());
view.setOnClickListener(this);
familyText = (TextView)view.findViewById(R.id.contacts_row_family_name);
markedBox = (CheckBox)view.findViewById(R.id.contacts_row_check);
familyText.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
boolean currentlyChecked = checkedState.get(cursor.getPosition());
markedBox.setChecked(currentlyChecked);
setProgressBarIndeterminateVisibility(false);
return super.getView(position, view, group);
}
public void onClick(View view) {
int rowId = (Integer)view.getTag();
Log.d("OnClick", String.valueOf(rowId));
boolean currentlyChecked = checkedState.get(rowId);
markedBox.setChecked(!currentlyChecked);
checkedState.put(rowId, !currentlyChecked);
Log.d("checkedState", "checkedState(" + rowId + ") = " + checkedState.get(rowId));
}
}
}
A call of the swapCursor method of the SimpleCursorAdapter class will trigger a function which maps the column names from the String array provided to the constructor(the 4th parameter) to an array of integers representing the columns indexes. As you pass null in the constructor of MyAdapter for the String array representing the columns names from the cursor, this will throw a NullPointerException later when the swapCursor will try to make the mapping(the NullPointerException should appear in a method findColumns, which is the actual method that uses the column names String array).
The solution is to pass a valid String array, you may also want to do this for the int array representing the ids for the views in which to place the data:
String[] from = {ContactsContract.Contacts.DISPLAY_NAME};
int[] to = {R.id.contacts_row_family_name, R.id.contacts_row_check};
adapter = new MyAdapter(this, R.layout.contacts_select_row, null, from, to, 0);
I don't know what you are trying to do but your implementation of the getView method is not quite right:
You do the normal stuff for the getView method(creating layouts, searching views, binding data) and then you simply return the view from the superclass(?!?), you'll probably just see the default layout with nothing in it.
The way you wrote the getView method is not very efficient, you may want to look into view recycling and the view holder pattern.
cursor.getPosition() will not do what you want as you don't move the cursor to the correct position. By default cursors based adapters will do this for you in the getView method, but, as you overrode the method it's your job to move the cursor's position.
You should leave the getView method and use the two methods newView and bindView as they offer a better separation of the logic.
adapter = new MyAdapter(this, R.layout.contacts_select_row, null, null, null, 0);
and your MyAdapter class you are passing null cursor
public MyAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.context = context;
this.cursor = getCursor();
}
Hi below is some code ive been playing with but when i debug it never gets to the onitemclicklisten routine can anyone help?
package sanderson.swords.mobilesales;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.AdapterView.OnItemClickListener;
public class OrderProductSearch extends Activity {
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
HashMap<String,String> item = new HashMap<String,String>();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try{
setContentView(R.layout.orderproducts);
}
catch (Exception e) {
//
String shaw="";
shaw = e.getMessage();
}
//Create view of the list where content will be stored
final ListView listContent = (ListView)findViewById(R.id.orderproductlistview);
//Set for fast scrolling
listContent.setFastScrollEnabled(true);
//Create instance of the database
final DbAdapter db = new DbAdapter(this);
//Open the Database and read from it
db.openToRead();
//Routine to call all product sub groups from the database
final Cursor cursor = db.getAllSubGroupProduct();
//Manages the cursor
startManagingCursor(cursor);
int i=0;
cursor.moveToFirst();
while (cursor.getPosition() < cursor.getCount()) {
item.put("ProdName",cursor.getString(2));
item.put("ProdSize", cursor.getString(3));
item.put("ProdPack",cursor.getString(4));
item.put("OrdQty","0");
//list.add(item);
list.add(i, item);
item = new HashMap<String,String>();
cursor.moveToNext();
i = i + 1;
}
String[] from = new String[] {"ProdName", "ProdSize", "ProdPack", "OrdQty"};
int[] to = new int[] { R.id.productlinerow, R.id.productlinerow2, R.id.productlinerow3, R.id.productlinerow4};
SimpleAdapter notes = new SimpleAdapter(OrderProductSearch.this,list,R.layout.productlinerow,from,to);
listContent.setAdapter(notes);
//Close the database
db.close();
listContent.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String neil = "test";
neil = neil + "test";
}
});
}
}
An easier way to verify the click listener is to add some logcat prints in it, e.g.
listContent.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.d(TAG, "Click!");
}
});
If you set a breakpoint at
listContent.setOnItemClickListener(new OnItemClickListener() {
it may not break when you click.
Try setting a breakpoint at
String neil = "test";
and debugging.