I have my ListView setup but it only shows 3 rows with numbers 1-3 and it's not showing the entries from my database.I've tried to find the answer for this but this ListView subject is very vague and I can't find a clear answer on how to show the text from my DB entries.
Here is the codes from my xml layout,ListView class and Cursor entry in database.
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/nfbackground"
android:orientation="vertical" >
<ImageView
android:id="#id/titlebar"
android:layout_width="wrap_content"
android:layout_height="66dp"
android:src="#drawable/nftitlebar" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/searchimageview"
android:textColor="#color/black"
android:textSize="25dp"
android:textStyle="bold"
android:text=""
android:orientation="vertical" >
</ListView>
</LinearLayout>
Code:
package com.fullfrontalgames.numberfighter;
import com.fullfrontalgames.numberfighter.DBAdapter;
import com.fullfrontalgames.numberfighter.R;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
public class PlayAFriend extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.playafriend);
ListView FriendLV = (ListView) findViewById(android.R.id.list);
DBAdapter db = new DBAdapter(this);
db = db.open();
Cursor friendslist = db.GetAllFriends();
String[] from = new String[] {"ID","USERNAME","FRIENDS"}; // your column/columns here
int[] to = new int[] {android.R.id.text1};
#SuppressWarnings("deprecation")
ListAdapter cursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, friendslist, from, to);
FriendLV.setAdapter(cursorAdapter);
db.close();
}
}
Code:
public Cursor GetAllFriends()
{
Cursor cursor = db.rawQuery("select rowid _id,* from NFDB", null);
int iRow = cursor.getColumnIndex("ID");
int iName = cursor.getColumnIndex("USERNAME");
int iFriends = cursor.getColumnIndex("FRIENDS");
if (cursor.moveToFirst()) {
do {
TextView friendslist = new TextView(context);
friendslist.setId(Integer.parseInt(cursor.getString(iRow)));
friendslist.setText(cursor.getString(iName));
friendslist.setText(cursor.getString(iFriends));
} while (cursor.moveToNext());
}
return cursor;
}
You need to create a layout with 2 TextView for your listview columns
list_items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="vertical" >
<TextView
android:id="#+id/textview_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textview_friends"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
change
String[] from = new String[] {"USERNAME","FRIENDS"}; // your column/columns here
int[] to = new int[] {textview_name, textview_friends};
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.list_items, friendslist, from, to, 0);
FriendLV.setAdapter(cursorAdapter);
//db.close(); Close the db in onDestroy
change
public Cursor GetAllFriends()
{
return db.rawQuery("select * from NFDB", null);
}
Related
I'm building my first AndroidApp and can't get the ListView to populate with data from my database. The data is definitely there because I can loop through it and Toast() it and the data shows up - I just can't get it into the ListView for some reason. Below is the code:
ListSmsRecipients.java
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class ListSmsRecipients extends Base_Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.smslist);
Button addSmsRecipient = (Button) findViewById(R.id.btn_listSms_addSms);
DbHelper dbhelper = new DbHelper(getApplicationContext());
SQLiteDatabase db = dbhelper.getWritableDatabase();
String[] from = new String[] { DbHelper.SMS_NAME, DbHelper.SMS_PHONE, DbHelper.SMS_MESSAGE };
String[] column = new String[] {DbHelper.SMS_ID, DbHelper.SMS_NAME, DbHelper.SMS_PHONE, DbHelper.SMS_MESSAGE };
int[] toViewIDs = new int[] { R.id.temp_smslist_item_name, R.id.temp_smslist_item_phone, R.id.temp_smslist_item_message };
Cursor cursor = db.query(DbHelper.SMS_TABLE_NAME, column, null, null, null, null, null);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.smslist_item, cursor, from, toViewIDs);
ListView list = (ListView)findViewById(R.id.listview_smsList);
list.setAdapter(adapter);
// This works
cursor.moveToFirst();
while (cursor.moveToNext())
{
String name = cursor.getString(cursor.getColumnIndex(DbHelper.SMS_NAME));
String phone = cursor.getString(cursor.getColumnIndex(DbHelper.SMS_PHONE));
String message = cursor.getString(cursor.getColumnIndex(DbHelper.SMS_MESSAGE));
Toast.makeText(getApplicationContext(), "Name = " + name + "\nPhone = " + phone + "\nMessage = " + message, Toast.LENGTH_SHORT).show();
}
cursor.close();
}
}
BaseActivity.java
import android.support.v4.app.FragmentActivity;
public class Base_Activity extends FragmentActivity
{
}
smslist.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="#+id/listview_smsList"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
smslist_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/temp_smslist_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text" />
<TextView
android:id="#+id/temp_smslist_item_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text" />
<TextView
android:id="#+id/temp_smslist_item_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
The problem is at adapter declaration. Change the getApplicationContext() to getActivity() as following
SimpleCursorAdapter adapter = new SimpleCursorAdapter(getActivity(), R.layout.smslist_item, cursor, from, toViewIDs);
Hope this will help you.
After the help from Anu and Ramesh_D, I simply changed my code to Extend Activity cursor.close(), and then changed the adapter call to the following: SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.smslist_item, cursor, from, toViewIDs);
I can't understand why I doesen't get any data out of the database. I have to admit that I am confues about listviews, textviews and adapters.
The database contains a person and a gift. That should be poured into a textview. Somehow it seems that I have to make a listview, but.... I am confused.
I have read a lot, and worked hard, but I have no idea. I would appreciate it if anyone could help me :-)
The only thing that happens is that na empty list is appearing.
Here is the code:
Main Activity.java:
package com.example.julegaveliste2;
import android.app.ListActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends ListActivity {
DatabaseHelper db;
Button knapp1;
Button knapp2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final DatabaseHelper db = new DatabaseHelper(MainActivity.this);
knapp1 = (Button) findViewById(R.id.Legg_Til);
knapp2 = (Button) findViewById(R.id.Les_database);
knapp2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
visliste(db.getWritableDatabase());
}
});
knapp1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
LagTabell(db.getWritableDatabase());
}
});
}
public static void LagTabell(SQLiteDatabase db)
{
ContentValues jul = new ContentValues();
jul.put("person", "Ida");
jul.put("gave", "blomst");
db.insert("julegaveliste2", "person", jul);
}
public void visliste(SQLiteDatabase db)
{
Cursor cursor=db.rawQuery("SELECT _id, person, gave FROM julegaveliste2", null);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.activity_list_item, cursor, new String[]{"person","gave"}, new int[]{R.id.person,R.id.gave},0);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
#Override
protected void onDestroy()
{
super.onDestroy();
db.close();
}
}
DatabaseHelper.java:
package com.example.julegaveliste2;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper
{
private static final String DATABASE_NAME="julegaveliste2.db";
private static final int SCHEMA=1;
public DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, SCHEMA);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE julegaveliste2 (_id INTEGER PRIMARY KEY AUTOINCREMENT, person TEXT NOT NULL, gave TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
throw new RuntimeException("How did we get here?");
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android1="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="#+id/person"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<TextView
android:id="#+id/gave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
<Button
android:id="#+id/Legg_Til"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="15dp"
android:layout_marginRight="17dp"
android:text="#string/opprett_database" />
<Button
android:id="#+id/Les_database"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/Legg_Til"
android:layout_alignBottom="#+id/Legg_Til"
android:layout_toRightOf="#+id/person"
android:text="#string/les_database" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_above="#+id/Legg_Til"
android:layout_alignParentLeft="true"
android:layout_marginBottom="42dp" >
</ListView>
<ListView
android1:id="#+id/listView1"
android1:layout_width="match_parent"
android1:layout_height="100dp" >
</ListView>
</RelativeLayout>
You should try to replace your SimpleCursorAdapter with an ArrayAdapter. To do this we would need a few modifications to your code. We need a new class in your application, which I will call PresentItem, an ArrayAdapter for your list, an XML layout for each row in the list, and a method for converting SQLite rows to PresentItems. First out is the new model, PresentItem:
public class PresentItem {
private String name, present;
private int id;
public PresentItem(int id, String name, String present) {
// Init
}
// Getters, setters, etc.
}
So, when we now read from your database, we can convert each rows we get from our query to new PresentItems:
public List<PresentItem> getPresentItems(SQLiteDatabase db) {
Cursor cursor = db.query("julegaveliste2",
new String[] {"_id", "person", "gave"}, null, null, null, null, null);
List<PresentItem> result = new ArrayList<PresentItem>();
PresentItem item;
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndex("_id");
int id = cursor.getInt(index));
index = cursor.getColumnIndex("name");
String name = cursor.getString(index));
index = cursor.getColumnIndex("present");
String present = cursor.getString(index);
item = new PresentItem(id, name, present);
result.add(item);
}
return result;
}
Once we have the PresentItems parsed from the database, we need a way to display them. To display the PresentItems in your app, we need our own ArrayAdapter, which would look something like this:
public class PresentListAdapter extends ArrayAdapter<PresentItem> {
private Context ctx;
private List<PresentItem> presentItems;
public PresentListAdapter(Context ctx, int layoutResourceId, List<PresentItem> presentItems) {
super(context, layoutResourceId, presentItems);
this.ctx = ctx;
this.presentItems = presentItems;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = ((Activity) ctx).getLayoutInflater();
convertView = inflater.inflate(mLayoutResourceId, parent, false);
}
PresentItem item = presentItems.get(position);
((TextView) convertView.findViewById(R.id.row_id)).setText("" + item.getId());
((TextView) convertView.findViewById(R.id.name)).setText(item.getName());
((TextView) convertView.findViewById(R.id.present)).setText(item.getPresent());
return convertView;
}
To use the adapter in your app, do something like this:
public void visListe(SQLiteDatabase db){
List<PresentItem> items = getPresentItems(db);
PresentItemAdapter adapter = new PresentItemAdapter(this, R.layout.presentListItem, items);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
And, as you might notice, our adapter uses presentListItem as its layout, which we define in res/layout/presentListItem.xml as:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/row_id"
/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/name"
/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/present"
/>
</LinearLayout>
I hope I made it clear and beware bugs in the code - I wrote most of it from memory with a few quick Google searches to help me :) Ask if you need anymore help ^^
basically, I'm a noob in Android programming and among other problems I'm stuck with this one: I have a GridView declared in my main layout and the XML definition for this grid in the separate xml. I'm adapting grid with SimpleCursorAdapter (not custom adapter). The thing is that I want to remember the value of corresponding ROW_ID when I touch the checkbox in the one of the displayed rows of data ... So, is there an option to do this without the need to customize SimpleCursorAdapter (BTW, is it possible?).
Here are snippets of Layout XML files and code, where I adapt cursor with SimpleCursorAdapter:
main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BAF0ED"
android:gravity="right" >
<GridView
android:id="#+id/gridView1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_below="#+id/view1"
android:numColumns="2" >
</GridView>
</RelativeLayout>
grid.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TableRow>
<TextView
android:id="#+id/row_ID"
android:layout_width="50px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="5px"
android:textColor="#4BA79E"
android:textSize="22dp" />
<TextView
android:id="#+id/name"
android:layout_width="50px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="5px"
android:textSize="22dp" />
<TextView
android:id="#+id/email"
android:layout_width="50px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="5px"
android:textSize="22dp" />
<CheckBox
android:id="#+id/chk"
android:layout_width="10px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="x"/>
</TableRow>
</TableLayout>
Using SimpleCursorAdapter:
public void showGridData() {
#SuppressWarnings("static-access")
String[] fromColumns = { db.KEY_ROWID, db.KEY_NAME, db.KEY_EMAIL };
int[] toViews = new int[] { R.id.row_ID, R.id.name, R.id.email };
db.openDatabase();
#SuppressWarnings("deprecation")
SimpleCursorAdapter sCAdapter = new SimpleCursorAdapter(this,
R.layout.table_row, db.getContacts(), fromColumns, toViews);
sCAdapter.setViewResource(R.layout.table_row);
gv.setAdapter(sCAdapter);
db.closeDatabase();
}
...and the method to read the value of the ROW_ID in the same record as the chebox is positioned (I'am getting allways the value of the first ROW_ID, wheather I touch first, second or n-th checkbox and this is the problem!):
public void x(View view) {
TextView tv = (TextView) findViewById(R.id.row_ID);
recordIds.add(Long.valueOf(tv.getText().toString()));
long[] longArray = new long[recordIds.size()];
for (int i = 0; i < recordIds.size(); i++) {
longArray[i] = recordIds.get(i);
Toast.makeText(this, String.valueOf(longArray[i]),Toast.LENGTH_LONG).show();
}
}
Thanks in advance and sorry for bothering you, regards,
Erik D.
add1 (1. edit)
Dear friends! Thank you all very much for the answer, but unfortunatelly this suggestions doesn't work for me. Let me post entire code, which I had altered with "setOnItemClickListener(new OnItemClickListener()". It still doesn't work...
I'm posting entire code (xml & java) if someone would have some spare time to look at it--I can't figure out what is wrong.
**activity_main.xml**
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="right" >
<GridView
android:id="#+id/gridView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/editText2"
android:layout_marginTop="20dp"
android:numColumns="3" />
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/button1"
android:layout_toRightOf="#+id/button1"
android:ems="10"
android:inputType="textEmailAddress" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/gridView1"
android:layout_toLeftOf="#+id/button1"
android:ems="10"
android:inputType="textPersonName" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:onClick="AddRecord"
android:text="Insert" />
</RelativeLayout>
**table_row.xml**
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TableRow>
<TextView
android:id="#+id/row_ID"
android:layout_width="50px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:padding="5px"
android:textSize="22dp" />
<TextView
android:id="#+id/name"
android:layout_width="50px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:padding="5px"
android:textSize="22dp" />
<TextView
android:id="#+id/email"
android:layout_width="50px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:padding="5px"
android:textSize="22dp" />
<CheckBox
android:id="#+id/chk"
android:layout_width="10px"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
</TableLayout>
*MainActivity.java*
> package net.learn2develop.databases;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
DBAdapter db;
EditText name, mail;
GridView gv;
Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = (EditText) findViewById(R.id.editText1);
mail = (EditText) findViewById(R.id.editText2);
db = new DBAdapter(this);
gv = (GridView) findViewById(R.id.gridView1);
showGridData();
}
public void AddRecord(View view) {
if (!(name.getText().toString().isEmpty())
&& !(mail.getText().toString().isEmpty())) {
db.openDatabase();
if (db.insertContact(name.getText().toString(), mail.getText()
.toString()) >= 0) {
showMessage("Record added succesfully!", "Inserting...");
db.closeDatabase();
showGridData();
}
} else {
showMessage("You can't add empty record!", "Inserting...");
}
}
public void showGridData() {
String[] fromColumns = { db.KEY_ROWID, db.KEY_NAME, db.KEY_EMAIL };
int[] toViews = new int[] { R.id.row_ID, R.id.name, R.id.email };
db.openDatabase();
SimpleCursorAdapter sCAdapter = new SimpleCursorAdapter(this,
R.layout.table_row, db.getContacts(), fromColumns, toViews);
sCAdapter.setViewResource(R.layout.table_row);
gv.setAdapter(sCAdapter);
// Implement On Item click listener
gv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(getApplicationContext(),
((TextView) v).getText(), Toast.LENGTH_SHORT).show();
}
});
db.closeDatabase();
}
public void showMessage(String message, String source) {
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setCancelable(false);
dlgAlert.setMessage(message);
dlgAlert.setTitle(source);
dlgAlert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dlgAlert.setCancelable(true);
dlgAlert.create().show();
}
}
*DBAdapter.java*
package net.learn2develop.databases;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
static final String KEY_ROWID = "_id";
static final String KEY_NAME = "name";
static final String KEY_EMAIL = "email";
static final String TAG = "DBAdapter";
static final String DATABASE_NAME = "MyDB";
static final String DATABASE_TABLE = "contacts";
static final int DATABASE_VERSION = 1;
static final String DATABASE_CREATE = "create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
+ KEY_NAME + " text not null, " + KEY_EMAIL + " text not null);";
final Context context;
DatabaseHelper DBHelper;
SQLiteDatabase db;
public DBAdapter(Context ctx) {// CONSTRUCTOR!!
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(DATABASE_CREATE);
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
}
public DBAdapter openDatabase() throws SQLException {
db = DBHelper.getWritableDatabase();
return this;
}
public void closeDatabase() {
DBHelper.close();
}
public long insertContact(String name, String email) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_EMAIL, email);
return db.insert(DATABASE_TABLE, null, initialValues);
}
public boolean deleteContact(long rowId) {
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
public Cursor getContacts() {
return db.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_NAME,
KEY_EMAIL }, null, null, null, null, null);
}
public Cursor getContact(long rowId) throws SQLException {
Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID, KEY_NAME, KEY_EMAIL }, KEY_ROWID + "=" + rowId,
null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public boolean updateContact(long rowId, String name, String email) {
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_EMAIL, email);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}
Dear friends, thanks in advance once again, regards,
Erik D.
You can use setTag and getTag methods of View class to tie a piece of information to your views.
You need to implement ItemClickListener. onItemClick will be invoked for each item clicked in the gridview and provides the position of click.
Check this sample code on how to implement it. Fetch this position data from adapter.
I have found the origin of the problem - basically, all it has to be done is defining the view element of the GridView with:
android:focusable="false"
android:focusableInTouchMode="false"
for instance:
<TextView
android:id="#+id/row_ID"
android:layout_width="50px"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:textSize="20dp" />
With these two parameters elements of the GridView do not steal the focus of the grid and listener on the grid works.
Have a great time,
Erik D.
(noob question)
Hello,
I am using this code to make a list of all contacts and display the phone number.
Currently I just want to display the name, but I am facing difficulties and I get a force close error.
ActivityManager: Starting: Intent { act=android.intent.action.MAIN
cat=[android.intent.category.LAUNCHER]
cmp=com.beta.cphonebook/.CPhonebook }
The code I am using is this:
PhoneList.java:
package com.beta.cphonebook;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.app.ListActivity;
import android.os.Bundle;
import android.content.ContentResolver;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.content.ContentUris;
import android.net.Uri;
import android.database.Cursor;
public class PhoneList extends ListActivity {
private SimpleCursorAdapter myAdapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
ArrayList<String> nlist = new ArrayList<String>();
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
nlist.add(name);
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
//Query phone here. Covered next
}
}
}
String[] nlistString = new String[nlist.size()];
nlist.toArray(nlistString);
Arrays.sort(nlistString);
int[] mapto = new int[] {R.id.contact_name};
//------------------------------------------------------------------
//This is where I get the error. While trying to use the list adapter
ListAdapter mAdapter = new SimpleCursorAdapter(this,R.layout.phonelist,cur,test,mapto);
this.setListAdapter(mAdapter);
//------------------------------------------------------------------
}
}
phonelist.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:src="#drawable/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name: "
/>
<TextView android:id="#+id/contact_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number: "
/>
<TextView android:id="#+id/contact_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
I know it should be something very simple, but for the past 3 hours, I just can't find it!!
instead of using the SimpleCursorAdapter class you can use ArrayAdapter....because u need to sort the name...and it is after iterating cursor....
so your code can be like the following
private ArrayAdapter<String> myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
ArrayList<String> nlist = new ArrayList<String>();
if (cur.getCount() > 0) {
if(cur.moveToFirst()) {
do {
Log.i("Test", "---------------------count-------------------" + cur.getCount());
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
nlist.add(name);
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
//Query phone here. Covered next
//String num = cur.getString(cur.getColumnIndex(ContactsContract.PhoneLookup.NUMBER));
}
}while (cur.moveToNext()) ;
}
}
String[] nlistString = new String[nlist.size()];
nlist.toArray(nlistString);
Arrays.sort(nlistString);
myAdapter = new ArrayAdapter<String>(this, R.layout.phonelist, R.id.contact_name, nlistString);
this.setListAdapter(myAdapter);
}
}
I'm trying to use a SimpleCursorAdapter with a ViewBinder to get an image from the database and put it into my ListView item view. Here is my code:
private void setUpViews() {
mNewsView = (ListView) findViewById(R.id.news_list);
Cursor cursor = getNews();
SimpleCursorAdapter curAdapter = new SimpleCursorAdapter(
getApplicationContext(), R.layout.cursor_item, cursor,
new String[] { "title", "content", "image" },
new int[] { R.id.cursor_title, R.id.cursor_content,
R.id.news_image });
ViewBinder viewBinder = new ViewBinder() {
public boolean setViewValue(View view, Cursor cursor,
int columnIndex) {
ImageView image = (ImageView) view;
byte[] byteArr = cursor.getBlob(columnIndex);
image.setImageBitmap(BitmapFactory.decodeByteArray(byteArr, 0, byteArr.length));
return true;
}
};
ImageView image = (ImageView) findViewById(R.id.news_image);
viewBinder.setViewValue(image, cursor, cursor.getColumnIndex("image"));
curAdapter.setViewBinder(viewBinder);
mNewsView.setAdapter(curAdapter);
}
I am getting:
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 60
while executing byte[] byteArr = cursor.getBlob(columnIndex);. Does anyone have an idea what am I doing wrong?
I extended SimpleCursorAdapter, and while I did not use a ViewBinder here is my code for using an image stored as a blob in an sqlite database in a listview. This was adapted from an article I read here.
My layout file for a row is:
row_layout_two_line.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/select_item">
<ImageView
android:id="#+id/pic"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:contentDescription="#string/imagedesc"
android:src="#drawable/icon"
android:layout_gravity="center_vertical">
</ImageView>
<LinearLayout
android:id="#+id/linearLayout0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="#+id/label"
android:textStyle="bold"
android:textColor="#000"
android:textSize="20sp" >
</TextView>
<TextView
android:id="#+id/label1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="#+id/label1"
android:textStyle="bold"
android:textColor="#000"
android:textSize="20sp" >
</TextView>
</LinearLayout>
<TextView
android:id="#+id/label2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="35dp"
android:text="#+id/label2"
android:textColor="#000"
android:textSize="15sp" >
</TextView>
</LinearLayout>
The calling code
...
adapter = null;
mCursor = search();
startManagingCursor(mCursor);
// Now create a new list adapter bound to the cursor.
BaseAdapter adapter = new ImageCursorAdapter(this, // Context.
R.layout.row_layout_two_line, // Specify the row template
// to use (here, two
// columns bound to the
// two retrieved cursor
// rows).
mCursor, // Pass in the cursor to bind to.
// Array of cursor columns to bind to.
new String [] {"personImage", "firstName", "lastName", "title"},
// Parallel array of which template objects to bind to those
// columns.
new int[] { R.id.pic, R.id.label, R.id.label1, R.id.label2 });
// Bind to our new adapter.
setListAdapter(adapter);
...
ImageCursorAdapter.java
import android.content.Context;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class ImageCursorAdapter extends SimpleCursorAdapter {
private Cursor c;
private Context context;
public ImageCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.row_layout_two_line, null);
}
this.c.moveToPosition(pos);
String firstName = this.c.getString(this.c.getColumnIndex("firstName"));
String lastName = this.c.getString(this.c.getColumnIndex("lastName"));
String titleStr = this.c.getString(this.c.getColumnIndex("title"));
byte[] image = this.c.getBlob(this.c.getColumnIndex("personImage"));
ImageView iv = (ImageView) v.findViewById(R.id.pic);
if (image != null) {
// If there is no image in the database "NA" is stored instead of a blob
// test if there more than 3 chars "NA" + a terminating char if more than
// there is an image otherwise load the default
if(image.length > 3)
{
iv.setImageBitmap(BitmapFactory.decodeByteArray(image, 0, image.length));
}
else
{
iv.setImageResource(R.drawable.icon);
}
}
TextView fname = (TextView) v.findViewById(R.id.label);
fname.setText(firstName);
TextView lname = (TextView) v.findViewById(R.id.label1);
lname.setText(lastName);
TextView title = (TextView) v.findViewById(R.id.label2);
title.setText(titleStr);
return(v);
}
}
Here is what it looks like in the end
I think the cursor.moveToFirst() has not been called so the cursor is throwing android.database.CursorIndexOutOfBoundsException.
Before using a cursor you should always check is the cursor is empty or not by calling cursor.moveToFirst(). This will also position the cursor at the first position.
Contact List using ListView and SimpleCusrorAdapter with Contact Photos and Filter/Search
I had been looking for a simpler solution and my final solution is quite closer to the one Daniel mentioned here so I thought I should share mine here. I am using Fragment to show Device Contacts as a list of names with their pictures. Result is pretty similar to that of Daniel's but is showing only names. More information can be shown very easily once you understand the code.
In my case I was fetching names and pictures from ContactsContract using PHOTO_URI so I didn't have to extend SimpleCursorAdapter as Daniel had to.
My example also includes filtering the list of contacts as user types in SearchView to find a contact
I have a Fragment called FragmentContacts and two Layout files, first the main Layout frag_contacts.xml and second for each contact row list_row_contact.
frag_contacts.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#android:color/holo_blue_light"
android:padding="8dip">
<android.support.v7.widget.SearchView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:id="#+id/searchView"/>
</FrameLayout>
<LinearLayout
android:id="#+id/ll_contactList"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="9"
android:orientation="vertical" >
<ListView
android:id="#+id/lv_ContactList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#aaaaaa"
android:dividerHeight="1dp" >
</ListView>
</LinearLayout>
</LinearLayout>
list_row_contact.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants">
<FrameLayout
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:id="#+id/imgContact"
android:layout_width="35dip"
android:layout_height="35dip"
android:layout_gravity="center"
android:layout_margin="5dip" />
</FrameLayout>
<TextView
android:id="#+id/contact_name"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="6"
android:gravity="center_vertical"
android:textSize="18sp"
android:paddingLeft="10dip">
</TextView>
</LinearLayout>
FragmentContacts.java
public class FragmentContacts extends Fragment
implements LoaderManager.LoaderCallbacks<Cursor>{
private ListView lv_ContactList;
private SearchView searchView;
private SimpleCursorAdapter mCursorAdapter;
private static final String DISPLAY_NAME = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY : Contacts.DISPLAY_NAME;
private static final String[] contactsColumns = { Contacts._ID, Contacts.LOOKUP_KEY, DISPLAY_NAME, Contacts.PHOTO_URI };
private final String contactsFilter = "(" +Contacts.HAS_PHONE_NUMBER+ "='1') AND (" + Contacts.IN_VISIBLE_GROUP + "='1')";
private final String contactsSortOrder = DISPLAY_NAME + " COLLATE LOCALIZED ASC";
private final static String[] listDisplayColumns = { DISPLAY_NAME, Contacts.PHOTO_URI };
private final static int[] listDataViewIDs = { R.id.contact_name, R.id.imgContact };
String[] mSelectionArgs;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_contacts, null);
lv_ContactList = (ListView)view.findViewById(R.id.lv_ContactList);
searchView = (SearchView)view.findViewById( R.id.searchView);
return view;
}
#Override
public void onResume(){
super.onResume();
mCursorAdapter= new SimpleCursorAdapter( getActivity(), R.layout.list_row_contact, null, listDisplayColumns, listDataViewIDs, 0);
lv_ContactList.setAdapter(mCursorAdapter);
getLoaderManager().initLoader(0, null, this);
searchView.setOnQueryTextListener( new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit( String query ) {return false;}
#Override
public boolean onQueryTextChange( String newText ) {
if( newText.isEmpty() ) mSelectionArgs = null;
else mSelectionArgs = new String[]{ "%"+newText.trim()+"%"};
getLoaderManager().restartLoader( 0, null, FragmentContacts.this );
return false;
}
} );
}
#Override
public Loader<Cursor> onCreateLoader( int id, Bundle args ) {
if(mSelectionArgs == null)
return new CursorLoader( getActivity(), Contacts.CONTENT_URI, contactsColumns, contactsFilter, null, contactsSortOrder );
else
return new CursorLoader( getActivity(), Contacts.CONTENT_URI, contactsColumns, contactsFilter + " AND (" + DISPLAY_NAME+" LIKE ?)", mSelectionArgs, contactsSortOrder );
}
#Override
public void onLoadFinished( Loader<Cursor> loader, Cursor data ) {
mCursorAdapter.swapCursor(data);
}
#Override
public void onLoaderReset( Loader<Cursor> loader ) {
mCursorAdapter.swapCursor(null);
}
}