I'm having trouble loading data from my ListView that I've populated with my CharacterSheetDBHelper. I've tried searching for several answers, one including using SimpleCursorAdapter, but I'm still having trouble. Can someone steer me into the right direction for this? I want to click on a list item and then fill out the form with the data stored on the database for editing.
My Code below:
The LoadCharacter class
public class LoadCharacter extends AppCompatActivity {
TextView testView;
ListView charListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.load_character);
CharacterDBHelper db = new CharacterDBHelper(getApplicationContext());
charListView = (ListView) findViewById(R.id.charListView);
//get list of names from the Database helper.
List<String> names = new ArrayList<>(db.getNames());
//attempting to create a listAdapter
ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, names);
charListView.setAdapter(adapter);
charListView.setTextFilterEnabled(true);
charListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent passIntent = new Intent(getApplicationContext(), CreateCharacter.class);
//Logically onItemClick would open up a game in progress rather than the character sheet screen.
//I was going to load character data into the Create Character class as an example.
//This is not working right now.
//Cursor c= (Cursor)charListView.getItemAtPosition(position);
//passIntent.putExtra("Characters", c.getColumn);
startActivity(passIntent);
}
});
}
public boolean onCreateOptionsMenu(Menu menu){
menu.add(0,0,0, "New Character");
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==0){
Intent intent = new Intent(this, CreateCharacter.class);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
}
My CharacterDBHelper Class:
public class CharacterDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "char.db";
private static final int DATABASE_VERSION = 1;
private SQLiteDatabase charDB = null;
public CharacterDBHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
//Create database
String CREATE_CHAR_TABLE = "CREATE TABLE IF NOT EXISTS Characters(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, " +
"brawling TEXT NOT NULL, highflying TEXT NOT NULL, technical TEXT NOT NULL, startinghealth TEXT NOT NULL," +
"remainingpoints TEXT NOT NULL)";
db.execSQL(CREATE_CHAR_TABLE);
}
public List<String> getNames(){
List<String> names = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
//Read from database and get ALL entries by name.
Cursor cursor = db.rawQuery("SELECT * FROM Characters", null);
if (cursor.moveToFirst()){
do {
//add extracted names to array.
names.add(cursor.getString(cursor.getColumnIndex("name")));
}while(cursor.moveToNext());
}
//close cursor and database.
cursor.close();
db.close();
return names;
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS Characters");
onCreate(db);
}
public void insertData(String name, String brawl, String flying, String tech, String health, String points){
SQLiteDatabase charDB = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("brawling", brawl);
values.put("highflying", flying);
values.put("technical", tech);
values.put("startinghealth", health);
values.put("remainingpoints", points);
//row insert
charDB.insert("Characters", null, values);
charDB.close();
}
}
I believe that you look like you are having problems using intent extras. Here's and example of adding some from a cursor, from within onItemClickListener:-
intent.putExtra("Caller", THIS_ACTIVITY + "Update");
intent.putExtra("AisleID", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_ID_INDEX));
intent.putExtra("AISLEID", aisleadapter.getCursor().getLong(ShopperDBHelper.AISLES_COLUMN_ID_INDEX));
intent.putExtra("AisleName", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_NAME_INDEX));
intent.putExtra("AisleOrder", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_ORDER_INDEX));
intent.putExtra("AisleShopRef", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_SHOP_INDEX));
intent.putExtra("SHOPID", aisleadapter.getCursor().getLong(ShopperDBHelper.AISLES_COLUMN_SHOP_INDEX));
startActivity(intent);
Note!! ShopperDBHelper.AISLES_COLUMN_??????_INDEX equates to the offset within the cursor of the column.
Here's an example of retrieving from the intent within the started actvity:-
shopid = getIntent().getLongExtra("SHOPID", -1)
Note cursor should be set to the appropriate position. However, you could always use cursor.moveToPosition(position)
Here's an example CursorAdapter :-
package mjt.shopper;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.TextView;
/**
* Created by Mike092015 on 6/02/2016.
*/
class AislesCursorAdapter extends CursorAdapter {
public AislesCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
#Override
public View getView(int position, View convertview, ViewGroup parent) {
View view = super.getView(position, convertview, parent);
Context context = view.getContext();
if (position % 2 == 0) {
view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewroweven));
} else {
view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewrowodd));
}
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView textviewaisleid = (TextView) view.findViewById(R.id.aisle_id_entry);
TextView textviewaislename = (TextView) view.findViewById(R.id.aisle_name_entry);
TextView textviewaisleorder = (TextView) view.findViewById(R.id.aisle_order_entry);
TextView textviewaisleshopref = (TextView) view.findViewById(R.id.aisle_shopref_entry);
textviewaisleid.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_ID_INDEX));
textviewaislename.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_NAME_INDEX));
textviewaisleorder.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_ORDER_INDEX));
textviewaisleshopref.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_SHOP_INDEX));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.activity_aisle_list_entry, parent, false);
}
}
Note. bindView (set the Listview's line/item/entry views with values) and newView (tell the adapter what layout to use) are required.
getView is optional (used here to alternate row background)
Related
Im busy with a Bible app, I use an SQLite db from my assets folder to retrieve the data, I use 3 listviews, each in its own activity, it goes like this:
DB column names: Book name, book id, chapter number, chapter id, verse text, verse id
1st activity, user selects a book, Genesis, Exodus, Leviticus, etc... and 2nd activity starts
2nd activity, db gets filtered so user can select chapters under that book...and 3rd activity starts
3rd activity, db gets filtered and shows all the verses under that chapter...
What I want is to put a text view at the top of the 2nd list view and then after the user selected from the 1st listview and the 2nd activity starts to show all chapters, it should show the book name that was selected from the 1st activity. And in the 3rd list view it should show the book name and chapter number that was selected from the previous two activities, I've tried using the intend, but I get errors.
Adapter:
public class customAdapterHoofstuk extends BaseAdapter {
private Context mContext;
private List<defineBybeldbAlles> defineBybeldbAlles;
public customAdapterHoofstuk(Context mContext, List<defineBybeldbAlles> defineBybelDBList) {
this.mContext = mContext;
this.defineBybeldbAlles = defineBybelDBList;
}
#Override
public int getCount() {
return defineBybeldbAlles.size();
}
#Override
public Object getItem(int position) {
return defineBybeldbAlles.get(position);
}
#Override
public long getItemId(int position) {
return (defineBybeldbAlles.get(position).getHoofstuk_id());
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(mContext, R.layout.custom_row_hoofstuk, null);
//this works->
TextView hoofstuknommer = (TextView)v.findViewById(R.id.custom_row_hoofstuktext);
hoofstuknommer.setText (defineBybeldbAlles.get(position).getHoofstuk_nommer());
//this works-->
TextView hoofstukid = (TextView)v.findViewById(R.id.hoofstuk_id);
hoofstukid.setText(String.valueOf(defineBybeldbAlles.get(position).getHoofstuk_id()));
//this doesnt work->
TextView boeknaambyhoofstuk = (TextView)v.findViewById(R.id.boeknaambyhoofstuklys);
boeknaambyhoofstuk.setText(defineBybeldbAlles.get(position).get_hebreeus());
return v;
}
}
Activity where it should be shown:
public class BybelActivityHoofstuk extends Activity {
private ListView listviewHoofstuk;
private customAdapterHoofstuk adapter_customAdapterHoofstuk;
private List<defineBybeldbAlles> defineBybeldbAllesList;
private DBHandlerHoofstuk DBHandlerHoofstuk;
ArrayList<HashMap<String, String>> HoofstukList;
//Boek id
String boek_id_na_hoofstuk;
#Override
public void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bybel_hoofstuk);
listviewHoofstuk = (ListView) findViewById(R.id.BybelHoofstukListView);
DBHandlerHoofstuk = new DBHandlerHoofstuk(this);
//Check exists database
File Database = getApplicationContext().getDatabasePath(DBHandlerHoofstuk.DBNAME);
if(false == Database.exists()){
DBHandlerHoofstuk.getReadableDatabase();}
//Get boek id
Intent boekIntent = getIntent();
boek_id_na_hoofstuk = boekIntent.getStringExtra("boek_id");
//hashmap for listview
HoofstukList = new ArrayList<HashMap<String, String>>();
//Get bybel list in db when db exists
defineBybeldbAllesList = DBHandlerHoofstuk.getListHoofstuk(boek_id_na_hoofstuk);
//Init adapter
adapter_customAdapterHoofstuk = new customAdapterHoofstuk(this,defineBybeldbAllesList);
//Set adapter for listview
listviewHoofstuk.setAdapter(adapter_customAdapterHoofstuk);
//Listview item click listener
//BybelActivityVers will be launched by passing hoofstuk_id
listviewHoofstuk.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick (AdapterView<?> arg0, View view, int arg2, long arg3){
//on selecting a hoofstk
//BybelActivityVers will be launched to show verse inside
Intent hoofstukIntent = new Intent(BybelActivityHoofstuk.this,BybelActivityVers.class);
//send hoofstuk_id to VersActivity to get verse under that book
String hoofstuk_id_na_vers = ((TextView)view.findViewById(R.id.hoofstuk_id)).getText().toString();
hoofstukIntent.putExtra("hoofstuk_id", hoofstuk_id_na_vers);
startActivity(hoofstukIntent);
}
});
}
}
DBHandler:
public class DBHandlerHoofstuk extends SQLiteOpenHelper{
public static final int DATABASE_VERSION = 1;
public static final String DBNAME = "pwl14082016-5.db";
public static final String DBLOCATION = "location goes here";
private Context mContext;
private SQLiteDatabase mDatabase;
public static final String COLUMN_BOEK_ID = "boek_id";
public static final String COLUMN_HEBREEUS = "_hebreeus";
public static final String COLUMN_AFRIKAANS = "_afrikaans";
public static final String COLUMN_HOOFSTUK_ID = "hoofstuk_id";
public static final String COLUMN_HOOFSTUK_NOMMER = "hoofstuk_nommer";
public static final String COLUMN_VERS_ID = "vers_id";
public static final String COLUMN_VERS_NOMMER = "vers_nommer";
public static final String COLUMN_VERS_TEXT = "vers_text";
public DBHandlerHoofstuk(Context context) {
super(context, DBNAME, null, DATABASE_VERSION);
this.mContext = context;
}
//Blank want db bestaan klaar
#Override
public void onCreate(SQLiteDatabase db) {
}
//blank want db word ekstern geupgrade
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
//maak db oop
public void opendatabase(){
String dbPath = mContext.getDatabasePath(DBNAME).getPath();
if (mDatabase !=null && mDatabase.isOpen()) {
return;
}
//verander dalk na 'mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);' as OPEN_READONLY nie werk nie
mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
}
//maak db toe
public void closeDatabase(){
if (mDatabase!=null) {
mDatabase.close();
}
}
public List<defineBybeldbAlles> getListHoofstuk(String boek_id_na_hoofstuk){
defineBybeldbAlles defineBybeldbHoofstuk = null;
List<defineBybeldbAlles> defineBybeldbAllesList = new ArrayList<>();
opendatabase();
Cursor cursor = mDatabase.rawQuery("SELECT * FROM PWLBybel WHERE " + COLUMN_BOEK_ID + " = '" + boek_id_na_hoofstuk + "'GROUP BY hoofstuk_id ORDER BY hoofstuk_id * 1 ASC", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()){
defineBybeldbHoofstuk = new defineBybeldbAlles(cursor.getInt(0), cursor.getString(1),cursor.getString(2),cursor.getInt(3),cursor.getString(4),cursor.getInt(5),cursor.getString(6),cursor.getString(7));
defineBybeldbAllesList.add(defineBybeldbHoofstuk);
cursor.moveToNext();
}
cursor.close();
closeDatabase();
return defineBybeldbAllesList;
}
}
XML where it gets displayed:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".defineBybeldbAlles">
<ListView
android:id="#+id/BybelHoofstukListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#ff303030"
android:dividerHeight="1dp"
android:layout_marginTop="21dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Boek naam:"
android:id="#+id/boeknaambyhoofstuklys"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textColor="#000063"
android:textSize="20dp" />
</RelativeLayout>
You can send the string through intent using
String KEY = "PUT_ANY_KEY_HERE";
String VALUE = "BOOK_NAME/CHAPTER_NAME";
Intent i = new Intent(FROM_CLASS.this, TO_CLASS.class);
i.putExtra(KEY,VALUE);
startActivity(i);
and get the string in the 2nd activity using
Intent intent = getIntent();
if(intent!=null)
String VALUE = intent.getExtras().getString(KEY);
now set the VALUE string in your textview. Also you need to put the chapterName textview above your listview or add the VALUE string as your 1st entry in the arraylist that you might be using to populate listview in 2nd and 3rd activity.
If someone might come across this, I wasn't able to pass the book and chapter name to the heading or bar, but I was able to figure out to set a title.
In your manifest under each activity, just put in android:label="title here"
to at least get a heading or title you want.
I have a listview that contains some data which I got from the web. Now I can make changes in the list item and once I make changes to the item, I am storing the updated value in the db. When i login in next time to the app, I am downloading the content from net and showing it in the listview with the changes that I have done last time. So my approach here is, I am querying the db for each item in the getview method of the list adapter to check for changes. Is it a good practice to do a db query for each item's getview method of the adapter? If not could you please suggest me some alternative. Thanks.
Never, really, never do that.
If you put your data download code in the getView method of the adapter it will make a network call for each row of the list.
Even worst, it will call it anytime that row appears on the screen, not only one time for row.
You should get all your data first, then use the adapter only to draw it.
You can at anytime call the db to check for changes and, if needed, notify the adapter to redraw the list to show the changes.
Hope this helps.
In Android development, any time you want to show a vertical list of items you will want to use a ListView which is populated using an Adapter to a data source. When we want the data for the list to be sourced directly from a SQLite database query we can use a CursorAdapter.
The CursorAdapter fits in between a Cursor (data source from SQLite query) and the ListView (visual representation) and configures two aspects:
Which layout template to inflate for an item
Which fields of the cursor to bind to views in the template
Creating the View Template
When we want to display a series of items into a list using a custom representation of the items, we need to use our own custom XML layout template for each item. We can simply create an XML layout template in res/layout/item_todo.xml representing a particular cursor row:
<?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:orientation="horizontal" >
<TextView
android:id="#+id/tvBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Study cursors"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/tvPriority"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="3"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Defining the Adapter
public class ViewAdapter extends BaseAdapter {
LayoutInflater mInflater;
public ViewAdapter() {
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return favoriteList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listitem,null);
}
final TextView nameText = (TextView) convertView.findViewById(R.id.nameText);
nameText.setText("Name : "+favoriteList.get(position).getName());
final TextView ageText = (TextView) convertView.findViewById(R.id.ageText);
ageText.setText("Age : "+favoriteList.get(position).getAge());
final Button edit = (Button) convertView.findViewById(R.id.edit);
edit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.row);
dialog.setTitle("Add Data to Database");
final EditText name = (EditText) dialog.findViewById(R.id.name);
final EditText age = (EditText) dialog.findViewById(R.id.age);
Button Add = (Button) dialog.findViewById(R.id.Add);
Add.setText("Add");
Add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(name.getText().toString() != null && name.getText().toString().length() >0 ){
if(age.getText().toString() != null && age.getText().toString().length() >0 ){
db.updateRow(favoriteList.get(position).getId(), name.getText().toString(), age.getText().toString());
favoriteList = db.getFavList();
listView.setAdapter(new ViewAdapter());
dialog.dismiss();
}else{
Toast.makeText(getApplicationContext(), "Please Enter the Age", Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(getApplicationContext(), "Please Enter the Name", Toast.LENGTH_LONG).show();
}
}
});
dialog.show();
}
});
final Button delete = (Button) convertView.findViewById(R.id.delete);
delete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
db.removeFav(favoriteList.get(position).getId());
notifyDataSetChanged();
favoriteList = db.getFavList();
listView.setAdapter(new ViewAdapter());
}
});
return convertView;
}
}
Create database
DatabaseHandler.java
public class DatabaseHandler extends SQLiteOpenHelper {
//Database Version
private static final int DATABASE_VERSION = 1;
//Database Name
private static final String DATABASE_NAME = "Test";
//Table Name
private static final String TABLE_TEST = "TestTable";
//Column Name
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_AGE = "age";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//Create Table
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_TEST + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_AGE + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TEST);
onCreate(db);
}
//Insert Value
public void adddata(Context context,String movieId,String songId) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, movieId);
values.put(KEY_AGE, songId);
db.insert(TABLE_TEST, null, values);
db.close();
}
//Get Row Count
public int getCount() {
String countQuery = "SELECT * FROM " + TABLE_TEST;
int count = 0;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
if(cursor != null && !cursor.isClosed()){
count = cursor.getCount();
cursor.close();
}
return count;
}
//Delete Query
public void removeFav(int id) {
String countQuery = "DELETE FROM " + TABLE_TEST + " where " + KEY_ID + "= " + id ;
SQLiteDatabase db = this.getReadableDatabase();
db.execSQL(countQuery);
}
//Get FavList
public List<FavoriteList> getFavList(){
String selectQuery = "SELECT * FROM " + TABLE_TEST;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
List<FavoriteList> FavList = new ArrayList<FavoriteList>();
if (cursor.moveToFirst()) {
do {
FavoriteList list = new FavoriteList();
list.setId(Integer.parseInt(cursor.getString(0)));
list.setName(cursor.getString(1));
list.setAge(cursor.getString(2));
FavList.add(list);
} while (cursor.moveToNext());
}
return FavList;
}
}
Enojoys.... :)
It is better to use cursor adapter to bind the list view.You can use Loader to get the list updated even if there is a change in the data base.
onLoadFinished (Loader loader, D data) of the Loader call back would be monitor for changes to the data, and report them to you through new calls. You should not monitor the data yourself.
I am trying to call data from two different cells in my database then combine them and print them out in an activity.
I am using the following code:
public Cursor getGermanDescription(String id) {
String[] args = { id };
return (getReadableDatabase()
.rawQuery(
"SELECT _id,Column1,Column2 FROM Databasing_Details WHERE _id=?",
args));
With the above I am only getting the content of Column1 but not Column2. I am passing the String id to another activity.
My cursor adapter is:
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Get our passed variable from our intent's EXTRAS
passedVar=getIntent().getStringExtra(ListViewTwo.ID_EXTRA);
//this is our ListView element, obtained by id from our XML layout
ListView myListView = (ListView)findViewById(R.id.list_view);
String string = passedVar;
int passedInt = Integer.parseInt(string);
if (passedInt==1) { passedVar1 = true;
}
creating our database Helper:
dbDescriptionHelper=new DatabaseHelper(this);
//a set of results from a database query
ourCursor=dbDescriptionHelper.getGermanDescription(passedVar);
//tell android to start managing the cursor,
startManagingCursor(ourCursor);
//create our adapter
adapter=new SlangAdapter(ourCursor);
//set the adapter!!!
myListView.setAdapter(adapter);
} catch (Exception e) {
Log.e("ERROR", "ERROR IN CODE: " + e.toString());
e.printStackTrace();
}
return;
}
The slangAdapterClass:
class SlangAdapter extends CursorAdapter {
SlangAdapter(Cursor c) {
super(ListViewFinal.this, c);
}
#Override
public void bindView(View row, Context ctxt,
Cursor c) {
DescriptionHolder holder=(DescriptionHolder)row.getTag();
holder.populateFrom(c, dbDescriptionHelper);
}
#Override
public View newView(Context ctxt, Cursor c,
ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.main_row, parent, false);
DescriptionHolder holder=new DescriptionHolder(row);
row.setTag(holder);
return(row);
}
}
The DescriptionHolder class:
static class DescriptionHolder {
private TextView name=null;
DescriptionHolder(View row) {
name=(TextView)row.findViewById(R.id.row);
}
void populateFrom(Cursor c, DatabaseHelper r) {
name.setText(r.getName(c));
}
}
Could someone point out where I am going wrong please.
OK, I have found the answer.
My syntax was incorrect, what I needed to write for my cursor was:
public Cursor getGermanDescription(String id) {
String[] args = { id };
return (getReadableDatabase()
.rawQuery(
"SELECT _id, ObjectDescriptionGerman ||'\n\n'|| ObjectDescription FROM Databasing_Details WHERE _id=?",
args));
}
The || needs to be used instead of "," or "AND". I have also inserted line breaks between my two returned value so I do not need to do this in my database.
so im a little confused here....
i have code that takes info from my sqlite database and populates a list, then shows the list using the standard array adapter. what i want to do is have it so that in this list, the row color is green if the "completed" table row value is "yes"
heres my db structure for the table being used:
String CREATE_ACHIEVEMENTS_TABLE = "CREATE TABLE achievements ("
+ "id INTEGER PRIMARY KEY,"
+ "name VARCHAR,"
+ "type VARCHAR,"
+ "value VARCHAR,"
+ "completed VARCHAR"
+ ")";
heres my code that gets the list from the db:
public ArrayList<String> getAchievements(Context context) {
ArrayList<String> achievementList = new ArrayList<String>();
String selectQuery = "SELECT * FROM achievements ORDER BY id asc";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
if (cursor.getString(4).equals("yes")) {
achievementList.add(cursor.getString(1)+" (completed)");
}
else {
achievementList.add(cursor.getString(1));
}
} while (cursor.moveToNext());
}
}
else {
achievementList.add(context.getResources().getString(R.string.na));
}
cursor.close();
db.close();
return achievementList;
}
heres my custom arrayadapter:
public class AchievementAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public AchievementAdapter(Context context, String[] values) {
super(context, R.layout.achievements, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.achievement_item, parent, false);
}
return row;
}
}
i really have no clue where to go from here. this is my first android app and i have learned a LOT, but i cant seem to figure out how to achieve this simple thing in regards to custom arrayadapters....all the tutorials i find contain a bunch of features that i dont want. all im trying to do is make the text color of the list item green if its "completed" table value is "yes"...
First of all, I recommend using a cursorAdapter instead of an arrayAdapter. With a cursor adapter you will have a pointer to the DB so you can get all of the information from there.
If you do that... your code for the adapter should look something like this.
private class MyCursorAdapter extends CursorAdapter {
public MyCursorAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public void bindView(View v, Context context, Cursor cursor) {
if(cursor.getString(cursor.getColumnIndex("completed").equals("yes")){
TextView tv = (TextView) v.findViewById(R.id.NAMEOFTEXTVIEW);
tv.setTextColor(Color.GREEN);
}
}
#Override
public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.achievement_item, parent, false);
return row;
}
}
and you create the adapter with:
Cursor cursor = db.rawQuery(selectQuery, null);
mAdapter = new MyCursorAdapter(this, cursor);
Having said all that... if you want to use the arrayAdapter and just change the textview,
in getView:
String item = (String) getItem(position);
if(item.contains("(completed)"){
TextView tv = (TextView) row.findViewById(R.id.NAMEOFTEXTVIEW);
tv.setTextColor(Color.GREEN);
}
I should note that with a cursorAdapter you should keep the cursor open, and close it in onStop (reopen it in onRestart)
Beginning Android programming, coming from html/php/css, I have searched the web for a simple way to separate my code from my style - for now I need to display data from a database in a list- or table view.
Simply put, I get a cursor from the database, iterate through it, creating each list-item dynamically in code as TextViews. Then I would like to apply a style from an external xml layout file to each item.
Pseudo-code:
style.xml:
//mystyle: bold, 12pt
//yourstyle: italic, 11pt
Activity:
for (each cursor-entry)
{
tv1 = new TextView();
applyStyle(tv, mystyle);
tv2 = new TextView();
applyStyle(tv, yourstyle);
//Apply content to textviews from the cursor...
}
mainLayout.setView(tv1);
mainLayout.setView(tv2);
The code examples I've found around the net, uses multiple lines of code, or multiple xml files (using inflate, or cursorAdapters), and IMO quickly become bloated. I just want a nice neat way to apply a style to a dynamically created code. Is this possible?
If you are using ListView, it is so simple to have an XML file for rows. The only thing you need is an XML file and a Adapter class. Take a look at this simple example:
To read data from database, create a helper class like this:
public class MessagingDatabaseAdapter {
protected SQLiteDatabase database;
public MessagingDatabaseAdapter(Context context) {
MessagingDatabaseHelper databaseHelper = new MessagingDatabaseHelper(context, "message_history_db");
database = databaseHelper.getWritableDatabase();
}
public void close() {
database.close();
}
public void Entity[] getAllEntities() {
Entity[] values = null;
String query = "select * from TABLE_NAME";
Cursor cursor = null;
try {
cursor = database.rawQuery(query, null);
if( cursor.moveToFirst() ) {
int s = cursor.getCount();
values = new Entity[s];
do {
Entity entity = new Entity();
entity.setSomeProperty(cursor.getInt(cursor.getColumnIndex(SOME_PROPERTY_COLUMN)));
values[i++] = entity;
} while( cursor.moveToNext() );
}
} catch(Exception ex) {
} finally {
if( cursor != null ) {
cursor.close();
}
return values;
}
}
protected class MessagingDatabaseHelper extends SQLiteOpenHelper {
public MessagingDatabaseHelper(Context context, String name) {
super(context, name, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("Your SQL to create Tables");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
In your Activity class:
MessagingDatabaseAdapter db = new MessagingDatabaseAdapter();
values = db.getAllEntities();
db.close();
list_view = (ListView) findViewById(R.id.list_view);
ListAdapter adapter = new ListAdapter(this, values);
list_view.setAdapter(adapter);
And ListAdapter class:
public class ListAdapter extends ArrayAdapter<Entity> {
final Context context;
final Entity[] values;
public ListAdapter(Context context, Entity[] values) {
super(context, R.layout.list_screen, values);
this.values = values;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_view_item, parent, false);
TextView datetimeTextView = (TextView) rowView.findViewById(R.id.list_view_datetime_text_view);
datetimeTextView.setTypeface(someTypeFace);
return rowView;
}
}
And row layout XML file (list_view_item.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/BorderedFrame" >
<TextView
android:id="#+id/inbox_list_view_datetime_text_view"
style="#style/MediumText"
android:layout_width="wrap_content" >
</TextView>
</RelativeLayout>