Custom SimpleCursorAdapter - refresh, update DB - android

My issue today is related to a custom SimpleCursorAdapter I've implemented. Here are my activities onCreate() and the custom SimpleCursorAdapter :
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
customSharedPreference = getSharedPreferences("myCustomSharedPrefs", Activity.MODE_PRIVATE);
editor = customSharedPreference.edit();
setContentView(R.layout.activity_1);
op = new OperationsClass(getApplicationContext());
op.open();
Cursor cursor = op.getList();
startManagingCursor(cursor);
String[] columns = new String[] { "AAA", "BBB", "CCC"};
int[] to = new int[] { R.id.entry_aaa,R.id.entry_bbb, R.id.entry_ccc};
MyCursorAdapter mAdapter = new MyCursorAdapter(this, R.layout.custom_entry, cursor, columns, to);
this.setListAdapter(mAdapter);
op.close();
}
OperationsClass manages a database and the getList() function returns a cursor of the entries.
public class MyCursorAdapter extends SimpleCursorAdapter{
private Context context;
private MyCursorAdapter here = this;
private int layout;
public MyCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.layout = layout;
}
#Override
public View newView(final Context context, Cursor cursor, ViewGroup parent) {
Cursor c = getCursor();
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
int col1 = c.getColumnIndex("aaa");
String name1 = c.getString(col1 );
int col2 = c.getColumnIndex("bbb");
String name2 = c.getString(col2 );
int col3 = c.getColumnIndex("ccc");
int name3 = c.getInt(col3 );
final TextView text1 = (TextView) v.findViewById(R.id.entry_aaa);
final TextView text2 = (TextView) v.findViewById(R.id.entry_bbb);
final TextView text3 = (TextView) v.findViewById(R.id.entry_ccc);
text1.setText(name);
text2.setText(name2);
if (name3 == 0)
text3.setText("Not checked");
else {
text3.setText("Checked");
text3.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
text3.setText("Not checked");
// Here I would like to update my DB using
// OperationsClass and the SharedPrefs,
// and refresh the ListView with the new
// text value.
}
});
}
}
return v;
}
#Override
public void bindView(View v, final Context context, Cursor c) {
// Same operations as higher
}
}
Basically what I want to achieve is to refresh the ListView when the users clicks on the third column, which means its value changes (has been clicked or has not been). In the same time I wish to update the DB and the SharedPreferences(I could create a new object of both classes and recover from the application context, but that seems pretty heavy).
I also wish to know if there is a way to trigger one of the implemented methods in one activity when an AlertDialog has been opened (in the same app, I actually want to add an element to my database through an AlertDialog and make the Activity that popped it up retrieve a new cursor and refresh its List).

"Basically what I want to achieve is"
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// if (the id of selected view matches what you want) {
boolean checked;
if (text3.getText().toString() == "checked") {
boolean checked = true;
} else {
boolean checked = false;
}
op.updateRead(id, checked);
refreshCursorAdapter();
setSharedPrefs();
// }
"to refresh the ListView when the users clicks on the 3rd column, which means its value changes (has been clicked or has not been)."
private void refreshCursorAdapter() {
Cursor cursor = op.getList();
mAdapter.changeCursor(cursor);
}
"In the same time I wish to update the DB"
private boolean updateRead(long rowId, boolean checked) {
ContentValues args = new ContentValues();
if (checked) {
args.put("read", "1");
} else {
args.put("read", "0");
}
return db.update(DB_TABLE, args, "_id =" + rowId, null) > 0;
}
"and the SharedPrefereces"
private void setSharedPrefs() {
SharedPreferences settings = getSharedPreferences("MYPREFS", 0);
SharedPreferences.Editor editor = settings.edit();
if (checked) {
editor.putBoolean("read", false);
} else {
editor.putBoolean("read", true);
}
editor.commit();
}
"I also wish to know if there is a way to trigger one of the implemented methods in one activity when an AlertDialog has been opened"
Quite honestly i don't understand what the mystique behind this one is. The process would involve copying and pasting the same code else to some other event.

Basically what I want to achieve is to refresh the ListView when the
users clicks on the 3rd column, which means its value changes (has
been clicked or has not been). In the same time I wish to update the
DB and the SharedPrefereces (I could create a new object of both
classes and recover from the application context, but that seems
pretty heavy).
First of all, you shouldn't be implementing that logic in the newView method because that method will not be called for every row due to the recycling. The newView should be used only to build a new row view and nothing more. Use the bindView method for any row logic.
Regarding the code in the onClick method I don't see where do you have problems. Update the database based on your logic and then query again the database for a Cursor with the new data and then use swapCursor() to update the adapter with the new values. This should work but it's not the recommended way mainly because you're doing every database operation on the main UI thread. Don't use the startManagingCursor method because this method runs the queries on the main UI thread, instead have a look at implementing a Loader in your activity to load data off the main UI thread. With a Loader you'll update the database values and then simply restart the Loader to update the list.
I also wish to know if there is a way to trigger one of the
implemented methods in one activity when an AlertDialog has been
opened (in the same app, I actually want to add an element to my
database through an AlertDialog and make the Activity that poped it up
retrieve a new cursor and refresh its List).
You're not saying anything about how you show that AlertDialog. If you want to update the list after you add the new element then use the listeners for the AlertDialog's buttons and the same code as above.

Related

CursorAdapter changed style of SwipeMenuListView after scroll

I'm trying to develop an app to record debts in which I have a SwipeMenuListView from this github https://github.com/baoyongzhang/SwipeMenuListView for adding a swipe menu. Using a custom CursorAdapter, I populate the ListView with the name and total debt.
Now, I want to group each listview items depending on the due date. I've created a new column on my SQLite to add a header for each day. Now I just need to use different style for header and items of the ListView. By detecting the new column from bindView and depending on if it's a header or items, it will change, hide and show elements from the same layout.
The problem is that when I scroll the ListView, some of the listview items changed style. It get worse if I keep scrolling up and down. Here's the picture of the error from the listview. Notice that it's all in one session, the header style seems to have been used in some of the items and the header itself changed to red color which suppose to be color code for the items. If I click one of the item, it still get the correct item so I figure its a problem within the cursorAdapter but I just can't figure it out. It is not a mistake in the SQL database which I have checked.
Here's the cursorAdapter.
public class DebtCursorAdapterMain extends CursorAdapter {
public DebtCursorAdapterMain(Context context, Cursor c, int flags) {
super(context, c, flags);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.debt_list_item, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int x = Integer.parseInt(cursor.getString(cursor.getColumnIndex(DBHelper.DATE_SEPARATOR_COLUMN)));
TextView tvName = (TextView) view.findViewById(R.id.tvName);
TextView tvTotal = (TextView) view.findViewById(R.id.tvTotal);
if(x == 0) {
DecimalFormat df = new DecimalFormat("#.00");
String nameText = cursor.getString(cursor.getColumnIndex(DBHelper.NAME_COLUMN));
String totalText = "$ " + df.format(cursor.getDouble(cursor.getColumnIndex(DBHelper.TOTAL_COLUMN)));
String type = cursor.getString(cursor.getColumnIndex(DBHelper.TYPE_COLUMN));
if (tvName != null)
tvName.setText(nameText);
if (tvTotal != null)
tvTotal.setText(totalText);
if (type.equals("L"))
view.setBackgroundColor(Color.parseColor("#ff9999"));
if (type.equals("B"))
view.setBackgroundColor(Color.parseColor("#99ff99"));
}
if(x == 1){
String date = cursor.getString(cursor.getColumnIndex(DBHelper.DUE_DATE_COLUMN));
if (tvName != null && tvTotal != null) {
tvName.setText(date);
tvName.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22);
tvTotal.setVisibility(View.GONE);
}
}
}
}
Here is the main activity in which the cursorAdapter is called.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find SwipeMenuListView
final SwipeMenuListView swipeMenuList = (SwipeMenuListView) findViewById(R.id.swipeMenuList);
// Create Debt database cursor adapter
cursorAdapter = new DebtCursorAdapterMain(this, null, 0);
// Create SwipeMenuList and set item
SwipeMenuCreator creator = createMainActivitySwipeMenu();
swipeMenuList.setMenuCreator(creator);
swipeMenuList.setAdapter(cursorAdapter);
swipeMenuList.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
// Set SwipeMenuList on item's menu click
swipeMenuList.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
....
}
});
// Swipe menu on Click function
swipeMenuList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
....
}
});
// Initialize cursor and check database for updating top info
getLoaderManager().initLoader(0, null, this);
checkDataBase();
}
I'm still new in android development so please tell me if there's a better approach to this problem. Thanks guys.

Filling list view from multiple columns in a cursor, but only one row?

Sorry if this seems stupid, but I'm sort of new to all this stuff. The situation is that i have a lot of data stored in a database that I need to present in list views. The first view pulls 15 rows and uses only two out of 14 columns in the db. I use this adapter to present this in a list view:
private class CustomListAdapter extends SimpleCursorAdapter {
private Cursor cursor;
public CustomListAdapter(Context context, int textViewResourceId, Cursor cursor, String from[], int to[]) {
super(context, textViewResourceId, cursor, from, to);
this.cursor = cursor;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
cursor.moveToPosition(position);
if (cursor != null) {
TextView lt = (TextView) v.findViewById(R.id.lefttext);
TextView rt = (TextView) v.findViewById(R.id.righttext);
if (lt != null) {
lt.setText(/*cursor.getString(cursor.getColumnIndex(EwstableContentProvider.TIMESTAMP))*/cursor.getString(cursor.getColumnIndex(EwstableContentProvider._ID))); }
if (rt != null){
rt.setText(cursor.getString(cursor.getColumnIndex(EwstableContentProvider.TOTALEWS)));
}
}
return v;
}
}
}
This may even be stupid, but at least it works.
Now, on the next activity i need to present data from all the columns, but only from the row that the user selected on the previous activity. I was looking at putting it inside a list view like the one from http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/, which is also where i modified the adapter from.
this way, i would put data from two fields in the db into each item in the list view. this is perfect, it would be one data point and a comment that goes with it.
The problem is that at this point i only have one row in the cursor, so the bit after #Override is only executed once, so instead of the 7 items in the list view, I get one.
I'd really appreciate any help, even if it is to do it in an entirely different way.
Assuming that you know the number of columns, could you just use a for loop to iterate through all the columns, storing each string into a String array.
String[] arr = new String[cursor.getColumnCount()];
for(int i=0; i < cursor.getColumnCount(); i++)
arr[i] = cursor.getString(i);
Then use the String[] with an ArrayAdapter for your listview.
UPDATE: sorry didn't read the question carefully; see other answer.
You need to use a cursor adapter. I recommend the SimpleCursorAdapter (example below).
You will also need to change the "from" parameter to the column name (key) for the text you want displayed. An example from my personal code is below. This line,
new String[] { DBAdapter.KEY_NAME },
is the important one. It is defined in DBAdapter to be:
public static final String KEY_NAME = "name";
which matches the name of the first column in my own database.
DBAdapter dba = new DBAdapter(this);
dba.open();
Cursor c = dba.list_listMode();
SimpleCursorAdapter ca = new SimpleCursorAdapter(
this,
R.layout.list_item,
c,
new String[] { DBAdapter.KEY_NAME },
new int[] { R.id.list_item_text });
lv.setTextFilterEnabled(true);
lv.setAdapter(ca);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id_long) {

Android Spinners in ListView, do I have to use a ViewHolder?

I have an issue with Spinners in a ListView. I have a ListView with a CheckBox, a label, and two Spinners. The Spinner are populated from SQLite and that is working fine. I am not using the ViewHolder method because so far when the ListView row is clicked the CheckBoxes are checked or unchecked and the change is immediately saved to the database. When the row is checked the Spinners are made visible but are not visible when the row is not checked.
So the issue that I haven't managed to find a solution for is that I have no idea how to get the actual Spinner or even get the ListItem row that the clicked Spinner is on. The Activity extends ListActivity. Anyone know a way I can do this without using a ViewHolder or do I have to use a ViewHolder?
Here is the code that declares and populates the ListView:
mSsCursor = mDbHelper.fetchAllSsPlaylistSs(mPlId);
startManagingCursor(mSsCursor);
String[] from = new String[]{"pl_selected", BTDbAdapter.KEY_NAME, BTDbAdapter.KEY_NAME2};
int[] to = new int[]{R.id.pl_selected, R.id.name, R.id.name2};
mAllSs = new SimpleCursorAdapter(this, R.layout.pl_edit_ss_row, mSsCursor, from, to);
mAllSs.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
//custom handling of setting the value
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(columnIndex == 3) {
ViewGroup row = (ViewGroup)view.getParent().getParent();
mSId = cursor.getInt(0);
if (cursor.getInt(3) > 0) {
mCheckBox = (CheckBox) row.findViewById(R.id.pl_selected);
mCheckBox.setChecked(true);
mTSpin = (Spinner) row.findViewById(R.id.pl_t_spin);
mMSpin = (Spinner) row.findViewById(R.id.pl_m_spin);
mtvT = (TextView) row.findViewById(R.id.pl_t);
mtvM = (TextView) row.findViewById(R.id.pl_m);
mTSpin.setVisibility(View.VISIBLE);
mtvT.setVisibility(View.VISIBLE);
mMSpin.setVisibility(View.VISIBLE);
mtvM.setVisibility(View.VISIBLE);
//set the values in the t spinner
PopulateTSpinner(cursor.getInt(4));
//set the values in the m spinner
PopulateMSpinner(cursor.getInt(5));
}
else {
mCheckBox = (CheckBox) row.findViewById(R.id.pl_selected);
mCheckBox.setChecked(false);
mTSpin = (Spinner) row.findViewById(R.id.pl_t_spin);
mMSpin = (Spinner) row.findViewById(R.id.pl_m_spin);
mtvT = (TextView) row.findViewById(R.id.pl_t);
mtvM = (TextView) row.findViewById(R.id.pl_m);
mTSpin.setVisibility(View.GONE);
mtvT.setVisibility(View.GONE);
mMSpin.setVisibility(View.GONE);
mtvM.setVisibility(View.GONE);
}
return true;
}
return false;
}
});
setListAdapter(mAllSs);
Thanks.
I don't know if I understood your question: If your app flow is:
show a list of data(CheckBox + TextView(Spinners hidden)) ->
user clicks a row(the Spinners appear for that row with(individual) data) ->
user selects something in those Spinners->
save that selection in the database
then I think you should go with a custom adapter and take care yourself of the row creation + data binding(I don't see how you would set a listener for the Spinners). Below is a small example on how you might do this(although probably not a pretty way of doing it):
public class CustomAdapter extends SimpleCursorAdapter {
private LayoutInflater mInflater;
public CustomAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
mInflater = LayoutInflater.from(context);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag(); // the holder
// pattern
// set the text for the TextView in your row
holder.name
.setText(cursor.getString(cursor.getColumnIndex("name")));
// status of the CheckBox from the database
int status = cursor.getInt(cursor.getColumnIndex("pl_selected"));
// set the CheckBox status
holder.ckb.setChecked((status > 0) ? true : false);
// get the id of this particular row, we'll use this later in the
// Spinner's listeners
long theId = cursor.getLong(cursor.getColumnIndex("_id"));
// see if it is time to show the Spinners
if (status > 0) {
// it is time to show the Spinners. Here you would do stuff
// like: setting up the Spinner's adapters + setting the
// listener
// I used a Spinner with entries set in the xml layout(so my
// selection result is a String)
holder.spin1.setVisibility(View.VISIBLE);
holder.spin2.setVisibility(View.VISIBLE);
// set theId as a tag so you know which Spinner was acted on
holder.spin1.setTag(new Long(theId));
holder.spin1
.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
Long realRowId = (Long) parent.getTag();
// I don't know
ContentValues cv = new ContentValues();
// the column where I saved the spinner selected
// item is called "saved_item"
cv.put("saved_item", (String) parent
.getItemAtPosition(position));
// mDb is my SQLiteDatabase instance
mDb.update("tbl", cv, "_id = ?",
new String[] { String
.valueOf(realRowId) });
// I don't know how you saved the data, the
// above is just an example
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
// also implement the second Spinner like the first one
} else {
// required to prevent a recycled View from causing damage
holder.spin1.setVisibility(View.GONE);
holder.spin2.setVisibility(View.GONE);
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = mInflater.inflate(R.layout.adapters_listspinner_row,
parent, false);
ViewHolder holder = new ViewHolder();
holder.spin1 = (Spinner) v.findViewById(R.id.spinner1);
holder.spin1.setFocusable(false);
holder.spin2 = (Spinner) v.findViewById(R.id.spinner2);
holder.spin2.setFocusable(false);
holder.name = (TextView) v.findViewById(R.id.textView1);
holder.ckb = (CheckBox) v.findViewById(R.id.checkBox1);
holder.ckb.setFocusable(false);
v.setTag(holder);
return v;
}
class ViewHolder {
Spinner spin1, spin2;
TextView name;
CheckBox ckb;
}
}
Also, the required onListItemcClick method:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// manage the CheckBox state
CheckBox ckb = (CheckBox) v.findViewById(R.id.checkBox1);
ckb.setChecked(!ckb.isChecked());
ContentValues cv = new ContentValues();
cv.put("pl_selected", ckb.isChecked() ? 1 : 0);
mDb.update("tbl", cv, "_id = ?",
new String[] { String.valueOf(id) });
// requery the database so the changes are seen by the adapter, this is horrible!
Cursor re = mDb.query("tbl", null, null, null, null, null, null);
mAllSs.changeCursor(re);
}
As an advice, maybe you could modify the layout of your app and move the Spinners out of the ListView row.

CheckedTextViews will randomly appear checked in a list if I click one further up the list

Ok, so this has been somewhat addressed alot on this site, however I do not believe the exact problem with what my code uses. I am filling a listView with CheckedTextViews which works completely. However when I click on an item it gets checked but when I scroll up and down random rows are also checked. I realize it must have something to do with how the ListView keeps track of the items. I am running into some errors at the moment. I attempted to fill a hashmap with the list of the rows so I can keep track which one is set to true and which are false. However I am not positive where to implement the map and try to fill it.
Here is my OnCreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewmenu);
//Get table name of menu clicked.
Bundle extras = getIntent().getExtras();
tableName = extras.getString("table");
// map each contact's name to a TextView in the ListView layout
String[] from = new String[] { "name" };
int[] to = new int[] { R.id.toppingCheckedTextView };
for(int i=0; i< from.length; i++){
map.put(i, false);
}
contactAdapter = new SimpleCursorAdapter(
ViewToppingListing.this, R.layout.toppings_list_item, null, from, to);
setListAdapter(contactAdapter); // set contactView's adapter
}
I attempt to place the map in the onCreate to fill it however it complains about a nullpointer.
Here is where I tried using the OnListItemClick method
#Override
protected void onListItemClick(ListView arg0, View arg1, int arg2, long arg3){
final int index = arg2 - arg0.getFirstVisiblePosition();
View v = arg0.getChildAt(index);
CheckedTextView ctv = (CheckedTextView) v.findViewById(R.id.toppingCheckedTextView);
if((Boolean)map.get(index) == true){
ctv.setChecked(true);
ctv.setVisibility(View.VISIBLE);
} else{
ctv.setVisibility(View.GONE);
}
}
I have read alot on this, and it seems that alot of solutions involves using getView(), however I don't know if that applies to my situation. Any help would be greatly appreciated!
First of all do you need a SimpleCursorAdapter? You set the adapter with a null cursor:
contactAdapter = new SimpleCursorAdapter(
ViewToppingListing.this, R.layout.toppings_list_item, null, from, to); // the third parameter is the cursor and you set it to null!
The behavior you see it's because of the ListView is recycling views and yes you'll have to implement your own adapter and override bindView(). The code bellow is based on another answer to a similar question maybe you'll want to look at it( Getting the selected View from ListView ). Here is an example:
public class TestCursorAdapter extends ListActivity {
MySimpleAdapter adapter;
private HashMap<Long, Boolean> positionHide = new HashMap<Long, Boolean>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] columns = new String[] { "_id", "name" };
MatrixCursor mc = new MatrixCursor(columns); // cursor for testing
for (int i = 1; i < 35; i++) {
long id = i;
mc.addRow(new Object[] { id, "Name" + i });
}
String[] from = new String[] { "name" };
int[] to = new int[] { R.id.checked_text };
adapter = new MySimpleAdapter(this,
R.layout.adapter_mysimpleadapter_row, mc, from, to);
setListAdapter(adapter);
}
private class MySimpleAdapter extends SimpleCursorAdapter {
public MySimpleAdapter(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);
CheckedTextView ctv = (CheckedTextView) view
.findViewById(R.id.checked_text);
long pos = cursor.getLong(0); // the id from the cursor
if (positionHide.get(pos) == null) {
ctv.setChecked(false);
// we don't have this id in the hashmap so the value is by
// default false, the TextView is GONE
} else {
// we have the value in the Hashmap so see what it is and set
// the textview visibility from this value
Boolean tmp = positionHide.get(pos);
if (tmp.booleanValue()) {
ctv.setChecked(true);
} else {
ctv.setChecked(false);
}
}
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Boolean tmp = positionHide.get(id);
if (tmp == null) {
// if null we don't have this key in the hashmap so
// we add it with the value true
positionHide.put(id, true);
} else {
positionHide.put(id, !tmp.booleanValue());
// if the value exists in the map then inverse it's value
}
adapter.notifyDataSetChanged(); // notify the adapter that something has
// changed
}
}

Strange behaviour with custom cursor adapter android

i have been having this issue for some time now, and have not gotten an answer for it yet. i have this custom Cursor adapter which i use to populate a list view from an sqlite database. Now my issue is that i want to populate the listview based on certain conditions.An example is if the condition is important, the listview should display only data that fits into that criteria and so on. I already have working methods that query the database accordingly.
now my problem is that, i can't seem to populate the listviews based on those methods and conditions without:
1) creating a copy of the exact same custom cursor adapter and just changing the names variables.
2) creating a copy of the exact xml layout and changing the id's.
As i say, its working this way, but i feel am having unnecessary classes and xml layout since its exactly the same thing. I know am doing something wrong, i just don't know what. Please any help and explanation would be appreciated. here is the necessary part of the code Code for the CustomCursorAdapter:
public class ViewItems extends ListActivity implements OnItemClickListener{
DBAdapter adapter;
Cursor cursor;
ListView list;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_list);
adapter = new DBAdapter(this);
adapter.open();
fillData();
list = (ListView)findViewById(android.R.id.list); // default android listView id
list.setOnItemClickListener(this);
}
// Different method calls
protected void fillImportantData() {
Cursor cursor = adapter.retrieveImportant();
startManagingCursor(cursor);
String[] from = new String[]{DBAdapter.NAME, DBAdapter.DATE, DBAdapter.TIME, DBAdapter.PRIORITY};
int[] to = new int[]{R.id.viewNameId, R.id.viewDateId, R.id.viewTimeId};
customCursorAdapter items = new customCursorAdapter(this, R.layout.view_items, cursor, from, to);
setListAdapter(items);
}
public class customCursorAdapter extends SimpleCursorAdapter {
private int layout;
Context context;
public customCursorAdapter(Context context, int layout, Cursor cursor, String[]from, int[] to) {
super(context, layout, cursor, from, to);
this.layout = layout;
this.context = context;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder;
if(view != null){
holder = new ViewHolder();
holder.viewName = (TextView)view.findViewById(R.id.viewNameId);
holder.viewStartDate = (TextView)view.findViewById(R.id.viewDateId);
holder.viewStartTime = (TextView)view.findViewById(R.id.viewTimeId);
view.setTag(holder);
}else{
holder = (ViewHolder)view.getTag();
}
int namecol = cursor.getColumnIndex(DBAdapter.NAME);
String name = cursor.getString(namecol);
if(holder.viewName != null){
holder.viewName.setText(name);
holder.viewName.setTextColor(Color.RED);
}
String startDate = cursor.getString(cursor.getColumnIndex(DBAdapter.DATE));
holder.viewStartDate.setText(startDate);
String startTime = cursor.getString(cursor.getColumnIndex(DBAdapter.TIME));
holder.viewStartTime.setText(startTime);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
final View view = inflater.inflate(layout, parent, false);
return view;
}
#Override
public long getItemId(int id){
return id;
}
#Override
public Object getItem(int position){
return position;
}
}
static class ViewHolder{
TextView viewName;
TextView viewStartDate;
TextView viewStartTime;
}
}
// methods in database
public Cursor retrieveAll(){
String[] resultColumns = new String[] {KEY_ID, NAME DATE, TIME, PRIORITY};
Cursor cursor = db.query(DATABASE_TABLE, resultColumns, null, , null, null, null);
return cursor;
}
public Cursor retrieveImportant(){
String[] resultColumns = new String[] {KEY_ID, NAME DATE, TIME, PRIORITY};
String[] condition = {"important"};
Cursor cursor = db.query(DATABASE_TABLE, resultColumns, PRIORITY + "=" + "?", condition, null, null, null);
return cursor;
}
If you change the data you wish to display, you will need to run a fresh query on the database and get a Cursor back that reflects that changed data. Depending on the nature of the changes, this may require a fresh CursorAdapter or merely a call to changeCursor(). If the new query returns the same columns and you want them displayed the same way, changeCursor() is probably sufficient. Otherwise, you will need to create a new CursorAdapter and call setAdapter() on your ListView to switch over to it.
You only need a different row layout if you are truly changing the row layout. You do not need to change IDs just for grins. Since you are not doing this in the code you have shown above, I am unclear what specifically you are worried about.

Categories

Resources