Working of a simplecursoradapter - android

Cursor c = managedQuery(People.CONTENT_URI,null,null,null,People.NAME);
String[] cols = new String[]{People.NAME};
int[] views = new int[]{android.R.id.text1};
SimpleCursorAdapter sca = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1,c,cols,views);
listview.setAdapter(adapter);
I'm using this code snippet to connect my ListView with Cursor.
I want to ask what
String[] cols = new String[]{People.NAME};
int[] views = new int[]{android.R.id.text1};
exactly does ??
and please explain about the arguments required for the constructor of SimpleCursorAdapter

It is a map, telling the adapter which columns from your cursor to use to fill which Widgets in your layout.
They get used in the order given. The data in the first column listed in the from array ( you called it cols ) will go into the first id listed in the to array ( you called it views), and so on.
The other parameters are the layout containing the view ids your specify in the to array and the cursor containing the data to be used in the array.

list_item.xml Refer this LINK
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
HelloListView.java
public class HelloListView extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, getNames()));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
Toast.LENGTH_SHORT).show();
}
});
}
private ArrayList<String> getNames(){
ArrayList<String> namesArray = new ArrayList<String>();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME};
Cursor names = getContentResolver().query(uri, projection, null, null, null);
int indexName = names.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
names.moveToFirst();
do {
namesArray.add(names.getString(indexName));
} while (names.moveToNext());
return namesArray;
}
}

Related

ListView with custom layout for hidden fields?

Currently I have a listview bound to an adapter (in a DialogFragment):
adapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_2,
null,
new String[] { "_id", "name" },
new int[] { android.R.id.text1, android.R.id.text2 },
0);
listView.setAdapter(adapter);
However, I would like to show only the name, but still keep the id, because when the user selects an item, the id is returned to the calling activity.
Would I need to have a custom layout with a hidden TextView or is there a better way to get the id from the current item?
Ok You may go with Custom adapter.
But if you don't want to do it.
You can change the default behavior of your code by Overriding a bindView().
adapter = new SimpleCursorAdapter(NavDrawer.this,
android.R.layout.simple_list_item_1,
null,
new String[] { "_id", "name" },
new int[] { android.R.id.text1},
0){
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
String name = cursor.getString(cursor.getColumnIndex("name"));
String _id = cursor.getString(cursor.getColumnIndex("_id"));
TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText(name);
//here you can store your id on textview tag
tv.setTag(_id);
}
};
for getting the id
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView tv = (TextView) view.findViewById(android.R.id.text1);
String _id = tv.getTag().toString();
}
});
You can use this layout for your SimpleCursorAdapter :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txt_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="#+id/txt_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Name it as custom_layout then change your SimpleCursorAdapter as follows:
adapter = new SimpleCursorAdapter(getActivity(),
R.layout.custom_layout,
null,
new String[] { "_id", "name" },
new int[] { R.id.txt_id, R.id.txt_name},
0);
listView.setAdapter(adapter);
The txt_id TextView will be hidden and only the txt_name will be visible to the user.
Instead creating again a wheel, you could use CursorAdapter.
Below example how to use it in fragment (I'm using getActivity() to get context).
//test: generating elements
ArrayList<String> values = new ArrayList<>();
for (int i = 0; i < 10; i++) {
values.add("word" + values.size());
}
//test: adding elements to cursor
MatrixCursor mc = new MatrixCursor(new String[]{"_id", "name"});
for (int i = 0; i < values.size(); i++) {
mc.addRow(new Object[]{i, values.get(i)});
}
listView = (ListView) inflate.findViewById(R.id.listView);
adapter = new CursorAdapter(getActivity(), mc, false) {
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view.findViewById(android.R.id.text1)).setText(cursor.getString(cursor.getColumnIndex("name")));
//just example how to get _id
Log.d("xxx", "it's id is " + cursor.getString(cursor.getColumnIndex("_id")));
}
};
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("xxx", "clicked id:" + id);
}
});
listView.setAdapter(adapter);
Simply , just donot set text for the item that you donot want to show.. hope this works..
thanks

How to display more than one column data from the same table on ListView?

My ListView currently is able to display only one column data. I want it to display two column data.
Here is the code for my ListView:
public class ProjectExplorer extends ListActivity {
private projectdatabase database;
protected Cursor cursor;
protected ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = new projectdatabase(ProjectExplorer.this);
getinfo();
}
private void getinfo() {
database.open();
cursor = database.getDataforDisplay();
adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, new String[] {"project_name"}, new int[] { android.R.id.text1 }, 0);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView parent, View view, int position, long id) {
super.onListItemClick(parent, view, position, id);
Cursor c = ((SimpleCursorAdapter)parent.getAdapter()).getCursor();
c.moveToPosition(position);
// get project name here
String str_projectname= c.getString(c.getColumnIndex("project_name"));
Toast.makeText(this, str_projectname, Toast.LENGTH_LONG).show();
}
Here is the method in database class which return the cursor:
public Cursor getDataforDisplay () {
String[] columns = new String[] {KEY_ROWID, PROJECT_NAME, PROJECT_FINISH_DATE, PROJECT_DIFFICULTY, PROJECT_STATUS};
Cursor c = projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
projectDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
c.moveToFirst();
return c;
}
I also want to display KEY_ROWID which is defined as _id
You can use android.R.layout.simple_list_item_2 specifying column no.2 from table from where data can be retrieved and specifies location with help of it can be displayed on Activity - android.R.id.text2
adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, new String[] {"project_name","column_no2"}, new int[] { android.R.id.text1, andriod.R.id.text2 }, 0);
You can also create your on custom Adapter specifying your own Listview and creating it from scratch and customized everything.
The best way to achieve this at least in my opinion is to create custom Adapter for your ListView in that case you can set your own design how single listview element should look like . Just populate some arrays using your Cursor and set them to your custom adapter.

Listview and SimpleCursorAdapter

I'm trying to display a ListView of all contacts and enable the user to select multiple records. I want to use ListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE) but I'm not sure how to apply it here. The code below pulls up a list of contacts but I can't select from it.
Any tips very much appreciated
Cheers
public class addContacts extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_contacts);
Uri allContacts = Uri.parse("content://contacts/people");
Cursor c = managedQuery(allContacts, null, null, null, null);
String[] columns = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts._ID };
int[] views = new int[] { R.id.contactName, R.id.contactID };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.add_contacts, c, columns, views);
this.setListAdapter(adapter);
}
}
Since you are using a ListActivity you can fetch the ListView with getListView(), use:
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
But I noticed that you are using the layouts incorrectly:
setContentView(R.layout.add_contacts);
...
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.add_contacts, c, columns, views);
Understand that:
The layout passed to setContentView() should have a ListView with the id android:id="#android:id/list".
The row layout passed to SimpleCursorAdapter should never have a ListView... You are trying to create a ListView with ListViews on every row.
Try using built in layouts like this:
public class addContacts extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri allContacts = Uri.parse("content://contacts/people");
Cursor c = managedQuery(allContacts, null, null, null, null);
String[] columns = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts._ID };
int[] views = new int[] { android.R.id.text1, android.R.id.text2 };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, c, columns, views);
this.setListAdapter(adapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
}

setOnItemClickListener on ListView how to show database values

I have a ListView with Contact info(name, phone number) so i want when i click in the contact name i want to show its name and phone number in a dialog box (which a have a code for it already) which is:
public void ShowMessage(String titulo,String msg){
AlertDialog.Builder dialogo = new AlertDialog.Builder(this);
dialogo.setMessage(msg);
dialogo.setTitle(titulo);
dialogo.setNeutralButton("OK", null);
dialogo.show();
}
Then i have seen about the setOnItemClickListener but when i try to put this up in my .java file it doens't even suggest the code, does anyone know why or how to do it?
EDIT:
//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, null);
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);
that is the code of my listview/adapter
OBS: better if you can explain (no tuts link (better if possible))
(I see that you are processing a Cursor yourself and using an ArrayAdapter, understand that a SimpleCursorAdapter does this for you. See my note below.)
Anyway, change your Cursor into a class variable and try adding this in onCreate():
user.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
c.moveToPosition(position);
String nome = c.getString(c.getColumnIndex("nome"));
String telefone = c.getString(c.getColumnIndex("telefone"));
showMessage(nome, telefone);
}
});
You aren't specific on how the title and message correlate to the contact's name, so I made that part up.
A class variable is simply a variable defined in a place that makes it visible to the entire class. For example this turns c into a class variable so you can use it in onItemClick():
public class MyActivity extends Activity {
Cursor c;
public void onCreate(...) {
...
c = db.query( "contatos", campos, null, null, null, null, "nome");
...
}
}
Understand that you can simplify how you read your contacts:
list = new ArrayList<String>();
Cursor c = db.query("contatos", campos, null, null, null, null, "nome");
int nameIndex = c.getColumnIndex("nome");
while(c.moveToNext()) {
list.add(c.getString(nameIndex));
}
I made a couple changes:
You only need to fetch the index of the "nome" column once, it won't change unless you change the Cursor.
moveToFirst() returns true if there is data to read and false if not.
This is faster to write and faster to run than your existing method.
A SimpleCursorAdapter is the standard adapter to bind data from your Cursor to a ListView. This will give you the same results as your original method, but with much less code.
How to use a SimpleCursorAdapter:
Cursor c = db.query("contatos", campos, null, null, null, null, "nome");
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, c,
new String[] {"nome"}, new int[] {android.R.id.text1});
user.setAdapter(adapter);
Assuming the adapter used in your ListView has a custom type (I'll call it ContactInfo), the following should work.
getListView().setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// Get String provided to this particular row
ContactInfo info = getListView().getAdapter().getItem(position);
// Construct title, message etc from information within info
showMessage("Contact Info", info);
}
});

displaying flag image in listview from sqlite database

I have a database with a "flagname" field. What I want to do is display a listview with the relevant flag in the image view that corresponds with the database field, along side a text field. The text field from the database is being displayed ok, but I'm having trouble displaying the relevant flag beside it. Can someone please let me know where I'm going wrong. My code is listed below:
public class favourites extends Activity{
Cursor cursor;
ListView lv;
ImageView iv;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listmain);
iv = (ImageView)findViewById(R.id.imgFlag);
DBAdapter db = new DBAdapter(this);
db.open();
lv = (ListView)findViewById(R.id.list);
//Get cursor for list items
cursor = db.getAllRadioStations();
//assign fields to columns
String[] columns = new String[]{DBAdapter.KEY_STATION_NAME.toString()};
int[] to = new int[]{R.id.txtFlag};
startManagingCursor(cursor);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.flagchoice, cursor, columns, to);
lv.setAdapter(adapter);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
What you need to do is override the Adapter.setViewBinder(). Try this:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.flagchoice, cursor, columns, to);
adapter.setViewBinder(new ViewBinder() {
public boolean setViewValue(View aView, Cursor aCursor, int aColumnIndex) {
String country=aCursor.getString(aColumnIndex);
int id = getResources().getIdentifier("yourpackagename:drawable/" + country , null, null);
iv = (ImageView)findViewById(R.id.imgFlag);
iv.setImageDrawable(getResources().getDrawable(id));
TextView tv=(TextView) aView;
tv.setText(aCursor.getString(aColumnIndex));
return true;
}
});
lv.setAdapter(adapter);

Categories

Resources