I have a listview with custom adapter which displays names from the contacts . currently its displaying them as
Rohit
Rahul
....
I want it to be like
Rohit
Rahul
....
i.e, number should be appended automatically . I tried doing that using a count variable in both bindview() & newview() method but it gets messed up when i scroll down and come back
the way I am setting text is
name = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
contactName.setText(count + ". " + name);
try
name = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
contactName.setText(cursor.getPosition() + ". " + name);
Maybe try :long count = cursor.getPosition();
This should be fine for what you need:
public class CustomCursoAdapter extends SimpleCursorAdapter{
public CustomCursoAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
// TODO Auto-generated constructor stub
}
#Override
public void bindView(View view, Context context, Cursor cursor)
{
int count =cursor.getPosition()+1;
RelativeLayout rl = (RelativeLayout) view;
TextView tv = (TextView) rl.findViewById(R.id.serial_no);
tv.setText(""+count);
super.bindView(view, context, cursor);
}
}
You get the position from Cursor by using
long count = cursor.getPosition();
Then
name = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
contactName.setText(cursor.getPosition() + ". " + name);
Related
I trying to populate a listview with data from an SQL database using the following code
final DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getAsset6("MARK BARR");
int mx=1;
String[] lvdata = new String[mx];
while (c.moveToNext()) {
lvdata[mx]=c.getString(1) + "-" + c.getString(2) + "-" + c.getString(6);
mx++;
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, lvdata));
getListView().setTextFilterEnabled(true);
db.close();
When I run the app crashes I'm am sure it something to do with the way i'm adding the data into a string in the while loop and then setting the adapter but I cant work out where I'm going wrong
Any help is appreciated
Mark
EDIT
OK the following works OK now But he app crashed when I reach the last listview entry
final DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getAsset6("MARK BARR");
int mx=0;
String[] lvdata = new String[c.getCount()];
while (c.moveToNext()) {
lvdata[mx]=c.getString(1) + "-" + c.getString(2) + "-" + c.getString(6);
mx++;
}
// use your custom layout
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.rowlayout, R.id.label, lvdata);
setListAdapter(adapter);
}
Well I am probably not worthy of even tying Vogella's shoes but this how I do it. I like using CursorAdapter because it allows you do all kinds of things with images and I think it's easier. If if you don't use this please check it out as you may need this in the future. Put this where you want to view the data whether in onCreate or from some button being pushed.
SQLiteDatabase sqLiteDatabase = controller.getReadableDatabase();
String query = "SELECT DISTINCT * FROM YOURTABLENAME";
Cursor cursor = sqLiteDatabase.rawQuery(query, null);
((ListView) YOURLISTVIEWNAME).setAdapter(new ANYNAMEADAPTER(context,
cursor, 0));
Then we create ANYNAMEADAPTER to get all the data into one organized place
private static final class ANYNAMEADAPTER extends CursorAdapter {
ANYNAMEADAPTER(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
mInflater = LayoutInflater.from(context);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
return v;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView theline = (TextView) view.findViewById(android.R.id.text1);
String thedata =cursor.getString(1) + "-" + cursor.getString(2) + "-" + cursor.getString(6);
theline.setText(thedata);
}
LayoutInflater mInflater;
}
Well, I have read almost 50 links related to this question, but my code still not working.
I have a Custom adapter which extends SimpleCursorAdapter class, and I use that adapter to fill the ListView on onCreate method
private void populateListView()
{
String[] from = new String[] { SchemaHelper.TASK_DESCRIPTION, SchemaHelper.TASK_CREATED_ON, SchemaHelper.TASK_ID };
int[] to = new int[] {R.id.lv_row_description, R.id.lv_row_created_on};
tasksCursor = schemaHelper.getTasks();
startManagingCursor(tasksCursor);
tasksAdapter = new TasksAdapter(this, R.layout.tasks_listview_row, tasksCursor, from, to);
setListAdapter(tasksAdapter);
}
The App is a simple task manager, I want to update the ListView contents when the user submits a new task without calling setListAdapter() again.
I have tried notifyDataSetChanged (running on ui thread), invalidate, requery(deprecated)... almost everything.
I'm doing something wrong?
EDIT:
This is the method where I add a new task to the database
private void addTask(String description)
{
String message = "";
schemaHelper.open();
if(schemaHelper.isAlreadyInDatabase(description))
{
message = getString(R.string.task_already_exists);
}
else
{
message = getString(R.string.task_succesfully_added);
schemaHelper.insertTask(description);
populateListView();
newTask.setText("");
}
schemaHelper.close();
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
ADAPTER CLASS:
private class TasksAdapter extends SimpleCursorAdapter
{
private LayoutInflater layoutInflater;
private Cursor cursor;
public TasksAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
{
super(context, layout, c, from, to);
cursor = c;
cursor.moveToFirst();
layoutInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(cursor.getPosition() < 0)
{
cursor.moveToFirst();
}
else
{
cursor.moveToPosition(position); // Here throws the error
}
View row = layoutInflater.inflate(R.layout.tasks_listview_row, null);
TextView description = (TextView) row.findViewById(R.id.lv_row_description);
TextView createdOn = (TextView) row.findViewById(R.id.lv_row_created_on);
description.setText(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_DESCRIPTION)));
createdOn.setText(getString(R.string.added_on) + " " + TaskHelper.formatDateWithSuffix(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_CREATED_ON))));
return row;
}
}
i dont know much of the taskCursor and taskAdapter but i used ArrayAdapter i guess, well have a look in my code and take your own conclusions.
//LISTVIEW database CONTATO
ListView user = (ListView) findViewById(R.id.lvShowContatos);
//String = simple value ||| String[] = multiple values/columns
String[] campos = new String[] {"nome", "telefone"};
list = new ArrayList<String>();
Cursor c = db.query( "contatos", campos, null, null, null, null, "nome" + " ASC ");
c.moveToFirst();
String lista = "";
if(c.getCount() > 0) {
while(true) {
list.add(c.getString(c.getColumnIndex("nome")).toString());
if(!c.moveToNext()) break;
}
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, list);
user.setAdapter(adapter);
If you don't want to use requery() you can simply pass a new Cursor with the same query:
tasksCursor.close();
tasksCursor = schemaHelper.getTasks();
startManagingCursor(tasksCursor);
tasksAdapter.changeCursor(tasksCursor);
I assume that when you call addTask() you have already called populateListView() once. Try changing addTask() to this:
private void addTask(String description)
{
String message = "";
schemaHelper.open();
if(schemaHelper.isAlreadyInDatabase(description))
{
message = getString(R.string.task_already_exists);
}
else
{
message = getString(R.string.task_succesfully_added);
schemaHelper.insertTask(description);
// Remove call to populateListView(), just update the Cursor
tasksCursor.close();
tasksCursor = schemaHelper.getTasks();
startManagingCursor(tasksCursor);
tasksAdapter.changeCursor(tasksCursor);
newTask.setText("");
}
schemaHelper.close();
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
If this "doesn't work", please be more specific. Is it throwing an error, if so what kind?
You are doing a little too much work in your adapter. Please watch Android's Romain Guy at Google Talks discuss adapters and getView(). However since you only want to pass one special string to your createdOn TextView, let's do something very different and override setViewText():
Try this:
public class TasksAdapter extends SimpleCursorAdapter {
String prefix;
public TasksAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to) {
super(context, layout, cursor, from, to);
// This is constant so set it once and consider adding the space to the end of the String in strings.xml
prefix = getString(R.string.added_on) + " ";
}
#Override
public void setViewText(TextView v, String text) {
if(v.getId() == R.id.lv_row_created_on)
v.setText(prefix + TaskHelper.formatDateWithSuffix(text));
else
super.setViewText(v, text);
}
}
The rest of the data is taken care of with SimpleCursorAdapter's existing methods.
I try create my own Adapter for ListView with checkboxes on each row. All works fine, but problem is, when I check some checkbox and then scroll down, other one is checked too.
(When I check first, 11th, 21th, ..., is checked too) Can me anyone explain wher is the problem?
Thank you.
My adapter:
public class WordAdapter extends CursorAdapter {
public WordAdapter(Context context, Cursor cursor, int flags){
super(context, cursor, flags);
}
#Override
public void bindView(View oldView, Context ctx, Cursor c) {
int wordQuestionIndex = c.getColumnIndex( WordDBAdapter.QUESTION );
int wordAnswerIndex = c.getColumnIndex( WordDBAdapter.ANSWER );
int activeIndex = c.getInt(c.getColumnIndex( WordDBAdapter.ACTIVE ));
String question = c.getString(wordQuestionIndex);
String answer = c.getString(wordAnswerIndex);
int active = c.getInt(activeIndex);
Log.d("WordAdapter", "isActive: "+ active + " - " + question + ", " + answer);
((TextView) oldView.findViewById(R.id.adapter_question)).setText(question);
((TextView) oldView.findViewById(R.id.adapter_answer)).setText(answer);
CheckBox checkBox =(CheckBox) oldView.findViewById(R.id.myCheckBox);
//checkBox.setChecked(vh.isChecked);
}
#Override
public View newView(Context ctx, Cursor c, ViewGroup root) {
LayoutInflater inflater = LayoutInflater.from(ctx);
View view = inflater.inflate(R.layout.word, root, false);
return view;
}
}
This is because of the reuse of the old view...
I would suggest, you maintain a list of check boxes items which are ticked and reset the check box item in bindview every time you initialize with new values..
Similar Question and solution is found here
I have a spinner populated from a cursor using SimpleCursorAdapter
I want to delete some values from this adapter depending on a variable
I try something like this but doesn't work fine
SimpleCursorAdapter toListAdapter = new SimpleCursorAdapter(MoreTicketSalesActivity.this, R.layout.generic_spinneritem, cursor, column,
viewIds) {
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
if (cursor.getLong(3) < session.getStopIndex()) {
view.setVisibility(View.INVISIBLE);
}
}
};
Please help me
So i find a solution who is just perfect for me
TextView textView = (TextView) view.findViewById(R.id.spinner_item_name);
int index = cursor.getInt(cursor.getColumnIndex("index"));
String name = cursor.getString(cursor.getColumnIndex("name"));
textView.setText(name);
if (index <= this.index) {
textView.setTextColor(Color.LTGRAY);
textView.setClickable(true);
} else {
textView.setTextColor(Color.BLACK);
textView.setClickable(false);
}
First of All you check value of your variable and get location of items to be deleted from the cursor.
Then remove those values from Cursor ( by remove(position of value) or etc ).
Then use toListAdapter.notifyDataSetChanged();
Ok so Ive spent the last two days looking for a good simple example of how to use the images on a device to populate a list view and Ive come to the conclusion that there is no easy way to do this. I know that everytime I put together bits and pieces from some one elses examples that I usually end up with lots of extra code i dont need. Can some one please show me how to simply load images from the device to a list view. There is no book, tutorial, or post on here that just simply shows how to do this and its kind of funny and crazy at the same time.
Here's the rest of the code, using the SDImageLoader linked to above from here: http://www.samcoles.co.uk/mobile/android-asynchronously-load-image-from-sd-card
The ListAdapter class:
public class PBListAdapter extends SimpleCursorAdapter {
//MEMBERS:
private int mLayoutId;
private SpecimenHunterDatabaseAdapter mDbHelper;
private final SDImageLoader mImageLoader = new SDImageLoader();
//METHODS:
public PBListAdapter(Context context, int layout, Cursor c) {
super(context, layout, c, new String[] {}, new int[] {});
mLayoutId = layout;
mDbHelper = new SpecimenHunterDatabaseAdapter(context);
mDbHelper.open();
}
#Override
public View newView(Context context, Cursor c, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(mLayoutId, parent, false);
return v;
}
#Override
public void bindView(View v, Context context, Cursor c) {
String title = c.getString(c.getColumnIndexOrThrow(SpecimenHunterDatabaseAdapter.KEY_CAPTURES_TITLE));
String species = mDbHelper.fetchSpeciesName(c.getInt(c.getColumnIndexOrThrow(SpecimenHunterDatabaseAdapter.KEY_CAPTURES_SPECIES)));
int pounds = c.getInt((c.getColumnIndexOrThrow(SpecimenHunterDatabaseAdapter.KEY_CAPTURES_POUNDS)));
int ounces = c.getInt((c.getColumnIndexOrThrow(SpecimenHunterDatabaseAdapter.KEY_CAPTURES_OUNCES)));
int drams = c.getInt((c.getColumnIndexOrThrow(SpecimenHunterDatabaseAdapter.KEY_CAPTURES_DRAMS)));
String weight = pounds + context.getString(R.string.addcapture_pounds) + " " +
ounces + context.getString(R.string.addcapture_ounces) + " " +
drams + context.getString(R.string.addcapture_drams);
String photoFilePath = c.getString(c.getColumnIndexOrThrow(SpecimenHunterDatabaseAdapter.KEY_CAPTURES_PHOTO));
String comment = c.getString(c.getColumnIndexOrThrow(SpecimenHunterDatabaseAdapter.KEY_CAPTURES_COMMENT));
TextView nameView = (TextView)v.findViewById(R.id.pb_row_species_name);
TextView weightView = (TextView)v.findViewById(R.id.pb_row_capture_weight);
TextView titleView = (TextView)v.findViewById(R.id.pb_row_capture_title);
TextView commentView = (TextView)v.findViewById(R.id.pb_row_capture_comment);
ImageView photoView = (ImageView)v.findViewById(R.id.pb_row_capture_photo);
mImageLoader.load(context, photoFilePath, photoView);
nameView.setText(species);
titleView.setText(title);
weightView.setText(weight);
commentView.setText(comment);
}
}
In the actual ListActivity, in your onCreate() set the list adapter:
private void bindData() {
Cursor c = mDbHelper.fetchAllPBs();
startManagingCursor(c);
setListAdapter(new PBListAdapter(this, R.layout.pb_list_item, c));
}
In my example the absolute filepaths for the images are stored in the database when added via the app.