Android app, conditional text in ListView - android

I have a list view that is being populated from an SQLite database using the SimpleCursorAdapter. One of the columns being returned in the cursor is an integer value 0 or 1. In my list view, I would like to display this in a more friendly form (ie. "Yes" or "No") and possibly with different text colors for each. Here is my source:
Cursor c = dbHelper.fetchAllItems();
startManagingCursor(c);
String[] from = {"deployed", "designation", "serial"};
int[] to = {R.id.deployed, R.id.designation, R.id.serial};
setListAdapter(new SimpleCursorAdapter(this, R.layout.list_item, c, from, to));
How would I conditionally switch elements and/or properties in the layout when the SimpleCursorAdapter simply maps each view to a column name. (Is it safe to assume I can't use SimpleCursorAdapter to accomplish this?)

Solved by adding a custom adapter, extending CursorAdapter
Modification:
Cursor c = dbHelper.fetchAllItems();
startManagingCursor(c);
setListAdapter(new RowAdapter(this, c));
New nested class:
private static class RowAdapter extends CursorAdapter {
public RowAdapter(Context context, Cursor c) {
super(context, c);
}
public void bindView(View view, Context context, Cursor c) {
TextView vDesignation = (TextView) view.findViewById(R.id.designation);
TextView vSerial = (TextView) view.findViewById(R.id.serial);
TextView vDeployed = (TextView) view.findViewById(R.id.deployed);
String designation = c.getString(c.getColumnIndexOrThrow("designation"));
String serial = c.getString(c.getColumnIndexOrThrow("serial"));
int deployed = c.getInt(c.getColumnIndexOrThrow("deployed"));
vDesignation.setText(designation);
vSerial.setText(serial);
vDeployed.setText(deployed > 0 ? R.string.yes : R.string.no);
vDeployed.setTextColor(deployed > 0 ? view.getResources().getColor(R.color.yes) : view.getResources().getColor(R.color.no));
}
public View newView(Context context, Cursor c, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.list_item, parent, false);
bindView(view, context, c);
return view;
}
}

Related

How to intercept and change data passing from DB to ListView?

In my application I read data from database, put it into cursor and pass it to ListView using adapter. These data are numbers from 1 to 12, but I need them to be presented in the ListView as names of months. How and on which step of reading and displaying these data can I intercept them and change from numbers to text?
You can modify the data, right before it the adapter sets the text to your TextView. It'll be done in adapter's getView method.
Try this
import java.text.DateFormatSymbols;
public String getMonth(int month) {
return new DateFormatSymbols().getMonths()[month-1];
}
You may right a custom adapter for that!. If your data is cursor object you can write custom adapter class extending from "CursorAdapter". Other wise you can extend from "BaseAdapter".
call it by:
ShowListCursorAdapter adapter = new ShowListCursorAdapter(getActivity(), R.layout.fragment_list_detail, cursor,
columns, views, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
getListView().setAdapter(adapter);
In custom Adapter extends cursorAdapter:
Constructor:
public ShowListCursorAdapter(Context context, int layout, Cursor cursor, String[] columns, int[] views, int flag) {
super(context,cursor,flag);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mCursor = cursor;
mLayout = layout;
mTo = views;
mFrom = columns;
}
Implement 2 methods in CursorAdapter.
#Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {//This will be called once
mView = mInflater.inflate(mLayout, viewGroup, false);
return mView;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {//This is called no.of row times
for(int i = 0; i< mTo.length;i++) {//If you have single column no need of for loop
TextView content = (TextView) view.findViewById(mTo[i]);
content.setText(mCursor.getString(mCursor.getColumnIndex(mFrom[i])));////here you can convert number to month and display
}
}

Android SimpleCursorAdapter to CursorAdapter

I'm using SimpleCursorAdapter to manage my query to the database and then showing the results in a ListView.
Here is my code:
database.open();
ListView listContent = (ListView)findViewById(android.R.id.list);
Cursor c = database.getData();
startManagingCursor(c);
String[] from = new String[]{Database._GROUP_NAME};
int[] to = new int[]{android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, query, from, to);
listContent.setAdapter(adapter);
database.close();
Although, at first look, it it working as expected, I believe that this should NOT be the way to proceed since there is CursorAdapter.
I know that this is a noob question but since just started now programming in Android I still don't know much.
How can I pass this from using SimpleCursorAdapter to CursorAdapter?
Already searched on internet but wasn't able to understand how this can be done.
Not asking code just some directions.
Thanks
favolas
UPDATE FOLLOWING mainu COMMENT
database.open();
ListView listContent = (ListView)findViewById(android.R.id.list);
Cursor c = database.getData();
MyAdapt cursorAdapter = new MyAdapt(this, query);
listContent.setAdapter(adapter);
database.close();
MyAdapt class:
public class MyAdapt extends CursorAdapter {
private final LayoutInflater mInflater;
public MyAdapt(Context context, Cursor c) {
super(context, c);
mInflater = LayoutInflater.from(context);
mContext = context;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView groupName = (TextView) view.findViewById(android.R.id.text1);
groupName.setText(cursor.getString(cursor
.getColumnIndex(Database._GROUP_NAME)));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final View view = mInflater.inflate(
android.R.layout.simple_list_item_1, parent, false);
return view;
}
}
Is this the correct way?
favolas
SimpleCursorAdapter is the simplest form of Adapter you can use for a custom adapter.
You should use SimpleCursorAdapter only, by when you dont need any customization.

Android: adding an extra String to TextView which populates its content from Database

I have a listview which populates its content from SQLite Database.
Here's my code:
ListView listView = (ListView) findViewById(R.id.lstText);
listView.setOnItemClickListener(this);
listView.setAdapter(new MySimpleCursorAdapter(this, R.layout.listitems,
managedQuery(Uri.withAppendedPath(Provider.CONTENT_URI,
Database.Project.NAME), new String[] { BaseColumns._ID,
Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, null, null, null),
new String[] { Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, new int[] {
R.id.txt_title, R.id.image, R.id.txt_list_desc, R.id.txt_org}));
I want to put an extra String to some TextViews above when its displayed on the list. For example, I want to add a String with the word "from" on R.id.txt_org, before the populated String from the database which is Database.Project.C_ORGANIZATIONTITLE
Let's say the populated String is: New Organisation,
with an extra String "from" what will be displayed is: from New Organisation
Can anybody help me with that? Thank you very much.
EDITED:
FYI, this is my SimpleCursorAdapter method:
class MySimpleCursorAdapter extends SimpleCursorAdapter {
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
loader = new ImageLoader(context);
this.context = context;
}
Context context=null;
ImageLoader loader = null;
public void setViewImage(ImageView v, String value) {
v.setTag(value);
loader.DisplayImage(value, context, v);
}
}
Since you're already using a custom adapter, override the adapter's bindView() and newView() methods, rather than getView(). That way you will not have to manually deal with recycling the row's view.
Within these method you can get the data from the resulting Cursor and manipulate it before binding it to your row's view.
GetView Vs. BindView in a custom CursorAdapter?
How to override CursorAdapter bindView
//Edit: some more code below. Note that this is just a rough outline and by no means complete or tested.
class MySimpleCursorAdapter extends SimpleCursorAdapter {
private ImageLoader mLoader = null;
private LayoutInflater mInflater = null;
private int mBusinessNameIndex = -1;
private int mSmallImageIndex = -1;
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
mLoader = new ImageLoader(context);
mInflater = getLayoutInflater();
mBusinessNameIndex = c.getColumnIndexOrThrow(Database.Project.NAME);
mSmallImageIndex = c.getColumnIndexOrThrow(Database.Project.C_SMALLIMAGE);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.row, null);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Get your views from 'view'
TextView someTextView = (TextView) view.findViewById(R.id.xxx);
ImageView someImageView = (ImageView) view.findViewById(R.id.yyy);
// Set the data
someTextView.setText("from " + cursor.getString(mBusinessNameIndex));
mLoader.DisplayImage(cursor.getString(mSmallImageIndex ), context, someImageView);
}
}

Make listview from SQLite database

I'm trying to populate listview from my SQLite database... this is how I get my data from database:
Cursor c = database.rawQuery("SELECT * FROM " + TableName, null);
int Column1 = c.getColumnIndex("uri");
int Column2 = c.getColumnIndex("file");
int Column3 = c.getColumnIndex("id");
c.moveToFirst();
if (c != null) {
do {
String uri = c.getString(Column1);
String file = c.getString(Column2);
int id = c.getInt(Column3);
} while (c.moveToNext());
}
I would normally add an array to listview like that:
ListView my_listview2 = (ListView) findViewById(R.id.listView1);
String my_array[] = {"Android", "iPhone"};
my_listview2.setAdapter(new ArrayAdapter<String>(this, R.layout.row, R.id.my_custom_row, my_array));
How can I make an array to setadapter from my sql query?
The best way to do this is to use a CursorAdapter or a SimpleCursorAdapter. This will give you the best performance and once you figure it out you'll find it's the simplest approach when using a SQLite db.
http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html
Below is a simple CustomCursorAdapter that I use frequently. Just add the CustomCursorAdapter class as an inner class.
protected class CustomCursorAdapter extends SimpleCursorAdapter {
private int layout;
private LayoutInflater inflater;
private Context context;
public CustomCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout = layout;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Log.i("NewView", newViewCount.toString());
View v = inflater.inflate(R.layout.list_cell, parent, false);
return v;
}
#Override
public void bindView(View v, Context context, Cursor c) {
//1 is the column where you're getting your data from
String name = c.getString(1);
/**
* Next set the name of the entry.
*/
TextView name_text = (TextView) v.findViewById(R.id.textView);
if (name_text != null) {
name_text.setText(name);
}
}
Create an instance of the CustomCursorAdapter like so...
You'll need to create your cursor just like you're already doing.
protected String[] from;
protected int[] to;
//From is the column name in your cursor where you're getting the data
//to is the id of the view it will map to
from = new String[]{"name"};
to = new int[]{R.id.textView};
CustomCursorAdapter adapter = new CustomCursorAdapter(this, R.layout.list, cursor, from, to);
listView.setAdapter(adapter);
I found working with the notepad tutorial very useful for learning about this.
It shows you how to implement the listview using the sqlite database in very easy steps.
http://developer.android.com/resources/tutorials/notepad/index.html

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