How fill Custom ListView with Data from SQLite database?
Which type of Adapter I should use?
screenshot http://www.codelearn.org/android-tutorial/assets/list_view/Custom_Base_adapter-6c6a43148474a723639fcbb8c85f5786.png
If you want to do ListView with Data from SQLite try use CursorAdapter.
ListAdapter.java
public class ListAdapter extends CursorAdapter {
public ListAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
return LayoutInflater.from(context).inflate(R.layout.items, parent, false);
}
// The bindView method is used to bind all data to a given view
#Override
public void bindView(View view, Context context, final Cursor cursor) {
TextView txt1 = (TextView) view.findViewById(R.id.TitleLabel);
TextView txt2 = (TextView) view.findViewById(R.id.SecondLabel);
TextView txt3 = (TextView) view.findViewById(R.id.ThirdLabel);
// Extract properties from cursor
// getString(int) - number of column
String value1 = cursor.getString(1);
String value2 = cursor.getString(2);
String value3 = cursor.getString(3);
String value4 = cursor.getString(4);
txt1.setText(value1);
txt2.setText("value2: " + value2);
txt3.setText("value3: " + value3 + "value4: " + value4);
}
}
MainActivity.java
helper - Database helper class
ListView listview = (ListView) findViewById(R.id.listView);
SQLiteDatabase db = helper.getWritableDatabase();
final Cursor ListCursor = db.rawQuery("SELECT * FROM tablename", null);
final ListAdapter todoAdapter = new ListAdapter(this, ListCursor, 0);
// Attach cursor adapter to the ListView
listview.setAdapter(todoAdapter);
If you want to display single field in listview then use simple Arrayadapter i.e.
DBHelper mydb = new DBHelper(this);
ArrayList array_list = mydb.getAllCotacts();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1, array_list);
ListView obj = (ListView)findViewById(R.id.listView1);
obj.setAdapter(arrayAdapter);
other wise implement custom adapter extends with BaseAdapter.
Related
I have created an android app in which i have to fetch data from sqlite database and set it on custom listview. Problem is that data is not shown. my code is same as a required for showing output.
You need to create a class which extends CursorAdapter. Below is the demo code:
public class PassCursorAdapter extends CursorAdapter {
public PassCursorAdapter(Context context, Cursor c) {
super(context, c,0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.item_todo,parent,false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView textID = (TextView) view.findViewById(R.id.textView6);
TextView textName = (TextView) view.findViewById(R.id.textView3);
TextView textUser = (TextView) view.findViewById(R.id.textView4);
TextView textPass = (TextView) view.findViewById(R.id.textView5);
int idColumnIndex = cursor.getColumnIndex(PassDBHelper.COLUMN_ID);
int nameColumnIndex = cursor.getColumnIndex(PassDBHelper.PASS_COLUMN_NAME);
int userColumnIndex = cursor.getColumnIndex(PassDBHelper.PASS_COLUMN_USERNAME);
int passColumnIndex = cursor.getColumnIndex(PassDBHelper.PASS_COLUMN_PASSWORD);
String id = cursor.getString(idColumnIndex);
String name = cursor.getString(nameColumnIndex);
String user = cursor.getString(userColumnIndex);
String pass = cursor.getString(passColumnIndex);
textID.setText(id);
textName.setText(name);
textUser.setText(user);
textPass.setText(pass);
}
}
In the newView method you are returning the layout file. This is how your List View layout file will be with 4 Text Views. In the End there is the method bindView where you set the id's.
Now to display the database you need to get the data from the sq-lite database as follows:
private void displayDataBaseInfo() {
PassDBHelper passDBHelper = new PassDBHelper(this);
SQLiteDatabase db = passDBHelper.getReadableDatabase();
String [] columns = {
PassDBHelper.COLUMN_ID,
PassDBHelper.PASS_COLUMN_NAME,
PassDBHelper.PASS_COLUMN_USERNAME,
PassDBHelper.PASS_COLUMN_PASSWORD
} ;
Cursor cursor = db.query(PassDBHelper.TABLE_NAME,columns,null,null,null,null,null);
ListView listView = (ListView)findViewById(R.id.list);
PassCursorAdapter passCursorAdapter = new PassCursorAdapter(this,cursor);
listView.setAdapter(passCursorAdapter);
}//displayDatabaseInfo
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;
}
I've created a subclass of CursorAdapter which is used to display 4 separate lists of data in my application.
Each list uses a different column from the database. My question is, how should I tell the adapter which column to use?
In the 2 brief examples below, which would be considered the better practice:
Option 1
Pass the column name to the constructor of my adapter.
This means the fragment will need to know the name of the column.
-
// In my fragment:
DBHelper helper = new DBHelper(getActivity());
Cursor cursor = helper.getTitleCursor();
adapter = new CustomCursorAdapter(getActivity(), cursor, DBHelper.COL_TITLE);
// The constructor of my CursorAdapter:
public CustomCursorAdapter(Context context, Cursor cursor, String colName) {
super(context, cursor, 0);
inflater = LayoutInflater.from(context);
this.displayColumn = colName;
}
// In my cursor adapter:
public void bindView(View view, Context context, Cursor cursor) {
TextView title = (TextView) view.findViewById(R.id.row_title);
String titleText = cursor.getString(cursor.getColumnIndex(displayColumn));
title.setText(titleText);
}
Option 2
When creating the cursor, use AS to give the column a specific name.
This means the fragment doesn't need to know the name of the column, though I'm not sure it's a better solution.
_
// In my DB Helper
public Cursor getTitleCursor() {
String query = "SELECT title AS displayCol FROM myTable"
return db.rawQuery(query, null);
}
// In my DB Helper
public Cursor getGenreCursor() {
String query = "SELECT genre AS displayCol FROM myTable"
return db.rawQuery(query, null);
}
// In my fragment:
DBHelper helper = new DBHelper(getActivity());
Cursor cursor = helper.getTitleCursor();
adapter = new CustomCursorAdapter(getActivity(), cursor);
// The constructor of my CursorAdapter:
public CustomCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
inflater = LayoutInflater.from(context);
}
// In my cursor adapter
public void bindView(View view, Context context, Cursor cursor) {
TextView title = (TextView) view.findViewById(R.id.row_title);
String titleText = cursor.getString(cursor.getColumnIndex("displayCol"));
title.setText(titleText);
}
I'm new in Android programming and I'm wondering witch is the most appropriate way to fill a ListView from DataBase.
Here the method I'm using in database to get my items
// Getting All stats
public List<StatParcours> getAllSats() {
List<StatParcours> statList = new ArrayList<StatParcours>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_STATS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
StatParcours stat = new StatParcours();
stat.setID(Integer.parseInt(cursor.getString(0)));
stat.setDate(cursor.getString(1));
stat.setDuration(cursor.getString(2));
stat.setDistance(Double.parseDouble(cursor.getString(3)));
stat.setSpeed(Double.parseDouble(cursor.getString(4)));
stat.setCondition(cursor.getString(5));
// Adding contact to list
statList.add(stat);
} while (cursor.moveToNext());
}
// return contact list
return statList;
}
and in the main activity, I'm using this. I know there is something wrong with the populateMyStatsList method, but I still don't know how to fix it.
public class History extends Activity {
public DatabaseHandler db;
private List<StatParcours> MyStats = new ArrayList<StatParcours>();
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("oncreate", "ok");
super.onCreate(savedInstanceState);
setContentView(R.layout.history);
populateMyStatsList ();
populateListView();
registerClickCallback();
}
private void populateMyStatsList (){
MyStats = db.getAllSats();
}
private void populateListView() {
ArrayAdapter<StatParcours> adapter = new MyListAdapter();
ListView list = (ListView) findViewById(R.id.HistListView);
list.setAdapter(adapter);
Log.i("Populate", "ok");
}
private void registerClickCallback() {
ListView list = (ListView) findViewById(R.id.HistListView);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked,
int position, long id) {
StatParcours clickedCar = MyStats.get(position);
String message = "You clicked position " + position
+ " Which is car make " + clickedCar.getDate();
Toast.makeText(History.this, message, Toast.LENGTH_LONG).show();
}
});
}
private class MyListAdapter extends ArrayAdapter<StatParcours> {
public MyListAdapter() {
super(History.this, R.layout.item_view, MyStats);
Log.i("MyListAdapter", "ok");
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if (itemView == null) {
Log.i("Make sure", "ok");
itemView = getLayoutInflater().inflate(R.layout.item_view, parent, false);
}
Log.i("getview", "ok");
StatParcours currentStat = MyStats.get(position);
TextView makeText = (TextView) itemView.findViewById(R.id.item_txtMake);
makeText.setText(currentStat.getDate());
TextView yearText = (TextView) itemView.findViewById(R.id.item_txtYear);
yearText.setText("" + currentStat.getDistance());
TextView condionText = (TextView) itemView.findViewById(R.id.item_txtCondition);
condionText.setText(currentStat.getCondition());
return itemView;
}
}
}
You need to use a SimpleCursor Adapter. I can't reach the developer site for the documentation but here is an example with your code above.
EDIT: Here is the link to the android developer website.
http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html
SECOND EDIT: This would go in the populateListView()
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_STATS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// Set your layout to int[]
int[] to = new int[]{R.id.item_txtMake,R.id.item_txtYear,R.id.item_txtCondition};
//set your columns to string[]; fill in your actual column names
string[] from = new string[]{"make","year","condition"};
//set up adapter
SimpleCursorAdapter adapter = new SimpleCursorAdapter(getActivity(),R.layout.item_view, cursor, from,to,null);
//set adapter to listview
ListView list = (ListView) findViewById(R.id.HistListView);
list.setAdapter(adapter);
Since you only have TextView in your ListView you can just simply use SimpleCursorAdapter.
// Getting All stats
public Cursor getAllSats() {
List<StatParcours> statList = new ArrayList<StatParcours>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_STATS;
SQLiteDatabase db = this.getWritableDatabase();
return db.rawQuery(selectQuery, null);
}
And in your History class
public class History extends Activity {
public DatabaseHandler db;
private List<StatParcours> MyStats = new ArrayList<StatParcours>();
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("oncreate", "ok");
super.onCreate(savedInstanceState);
setContentView(R.layout.history);
Cursor c = getAllSats();
String[] fromColumns = {Your database column name for date,
Your database column name for distance,
Your database column name for condition};
int[] toViews = {R.id.item_txtMake,
R.id.item_txtYear,
R.id.item_txtCondition};
adapter = new SimpleCursorAdapter(this, R.layout.item_view,
c, fromColumns, toViews, 0);
ListView list = (ListView) findViewById(R.id.HistListView);
list.setAdapter(adapter);
registerClickCallback();
}
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