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>
Related
I have created SQL database in my Android project and managed to populate ListView with data that I inserted. Next part of the project is to enable CheckBoxes for every item (from SQL database) in my ListView. I have found a way how to do it with String values, but I am not sure how to do it with values from SQL database.
Is it somehow possible to put SQL values into String ? Or I need to use different data values to populate my ListView ?
I am still nooby with SQL in Android, so every advice would be helpfull.
Here is code:
public class ModelBreakfast {
public String name; //This String need to be filled with SQL datas. If it's possible.
public boolean checked;
public ModelBreakfast(String name, boolean checked){
this.name = name;
this.checked = checked;
}
}
Just need to say that I tried to replace public String name; with my ContractClass
public FoodContract.FoodEntry entry; where I defined all String values for my database rows.
(_ID, NAME, etc). (I only saw that way to solve my problem). So, code is now looking like this:
public ModelBreakfast(FoodContract.FoodEntry entry, boolean checked){
this.entry = entry;
this.checked = checked;
}
Next class is CustomAdapter
public class CustomAdapterBreakfast extends ArrayAdapter<ModelBreakfast> {
private ArrayList<ModelBreakfast> dataSet;
Context mContext;
private static class ViewHolder {
TextView txtName;
CheckBox checkBox;
}
public CustomAdapterBreakfast(ArrayList<ModelBreakfast> data, Context context){
super(context, R.layout.activity_breakfast_checkbox, data);
this.dataSet = data;
this.mContext = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_breakfast_checkbox, parent, false);
viewHolder.txtName = (TextView) convertView.findViewById(R.id.txtName);
viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);
result=convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result=convertView;
}
ModelBreakfast item = getItem(position);
viewHolder.txtName.setText(item.name); //Need to replace or modify this part
viewHolder.checkBox.setChecked(item.checked);
return result;
}}
Last part is the MainActivity
public class BreakfastActivity extends AppCompatActivity {
ArrayList<ModelBreakfast> modelBreakfastArrayList;
private CustomAdapterBreakfast customAdapterBreakfast;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_breakfast);
ListView listView = (ListView) findViewById(R.id.listBreakfast);
modelBreakfastArrayList = new ArrayList<>();
modelBreakfastArrayList.add(new ModelBreakfast("This string will show in ListView. So I need to somehow replace that String with SQL datas.", false));
customAdapterBreakfast = new CustomAdapterBreakfast(modelBreakfastArrayList, getApplicationContext());
listView.setAdapter(customAdapterBreakfast);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ModelBreakfast modelBreakfast= modelBreakfastArrayList.get(position);
modelBreakfast.checked = !modelBreakfast.checked;
customAdapterBreakfast.notifyDataSetChanged();
}
});
}}
After I replaced public String name; with my ContractClass public FoodContract.FoodEntry entry; I understand that I can't use
modelBreakfastArrayList.add(new ModelBreakfast("This string will show in ListView", false));. But than what do I need to set, so my ListView with CheckBoxes will displaying my SQL database values ?
Should I use ArrayList instead String? And how?
Again as I said before in the last question. Look at the for loops. So within your SQLDB Activity and in the function that is taking the values out of the database, you need to populate an array list that you will call in the MainActivity.
public ArrayList<String> getAirportRegion(String code)
Cursor cursor = db.rawQuery("SELECT "+ AIRPORT_NAME +
" FROM " + AIRPORT_TABLE + " WHERE " + AIRPORT_CODE + " = " + code, null);
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
arrayList.add(cursor.getString(cursor.getColumnIndex(AIRPORT_NAME)));
cursor.moveToNext();
}
}
cursor.close();
return arrayList;
}
Now in the Main Activity get a reference to the database and set it to modelBreakfastArrayList like so
airportArrayList = mdb.getAirportRegion();
Voila it is done
Do you see how I am extracting the data? For the most part, this is the best way to extract lists from the local database. Keep these Activities separate, also I hope you have the Database activity as a singleton, otherwise, you will have multiple databases and that will guzzle up resources. Look below for how I start these database activities.
private DBHelper(Context context) {
super(context, "db", null, DATABASE_VERSION);
}
private static DBHelper INSTANCE;
public static DBHelper getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = new DBHelper(context);
}
return INSTANCE;
}
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)
So I have 2 activities.
The first (ActivityOne) displays a listview with data from SQLite cursor, and a button.
On click of that button, I want to add an item to the listview, so I display the second activity (ActivityTwo), that contains a number of editTexts and a save Button, that does the saving in the Database.
But what I want is:
after saving the new item to the DB, the ActivityTwo should close and the ActivityOne should be displayed with the refreshed content from the DB
.
This seems a reasonable workflow. How do I achieve it?
Code for ActivityOne:
public class ActivityOne extends Activity {
private ArrayList<String> idclient = new ArrayList<String>();
private ArrayList<String> numeclient = new ArrayList<String>();
private ArrayList<String> tipclient = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView mylist = (ListView) findViewById(R.id.lv_clienti);
LoadList();
Button btnex = (Button) findViewById(R.id.btnNewCli);
btnex.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View aView)
{
Toast.makeText(getApplicationContext(), "Add new client... " , Toast.LENGTH_SHORT).show();
Intent toAnotherActivity = new Intent(aView.getContext(), NewClientActivity.class);
startActivity(toAnotherActivity);
}
}
);
}
public void LoadList(){
SQLiteDatabase db = new myDbHelper(getApplicationContext()).getWritableDatabase();
Cursor mCursor = db.rawQuery("select idclient,nameclient,typeclient from clienti order by numeclient" , null);
idclient.clear();
numeclient.clear();
tipclient.clear();
if (mCursor.moveToFirst()) {
do {
idclient.add(Integer.toString(mCursor.getInt(0)));
nameclient.add(mCursor.getString(1));
typeclient.add(mCursor.getString(2));
} while (mCursor.moveToNext());
}
DisplayClientiAdapter disadpt = new DisplayClientiAdapter(ClientiActivity.this,idclient,nameclient, typeclient);
ListView lv = (ListView) findViewById(R.id.lv_clienti);
lv.setAdapter(disadpt);
mCursor.close();
db.close();
}
}
And in the ActivityTwo, I have in a button click:
db.execSQL("insert into clients (idclient, nameclient,typeclient,...");
DisplayClientiAdapter da = new DisplayClientiAdapter(getApplicationContext());
da.notifyDataSetChanged();
finish();
Also the displayAdapter is something like:
public class DisplayClientiAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> idclient;
private ArrayList<String> numeclient;
private ArrayList<String> tipclient;
public DisplayClientiAdapter(Context c){
this.mContext = c;
}
public DisplayClientiAdapter(Context c, ArrayList<String> idclient, ArrayList<String> numeclient, ArrayList<String> tipclient) {
this.mContext = c;
this.idclient = idclient;
this.numeclient = numeclient;
this.tipclient = tipclient;
}
public int getCount() {
return idclient.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int pos, View child, ViewGroup parent) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.clienti_item, null);
mHolder = new Holder();
mHolder.txt_idclient = (TextView) child.findViewById(R.id.tv_cl_id);
mHolder.txt_numeclient = (TextView) child.findViewById(R.id.tv_cl_nume);
mHolder.txt_tipclient = (TextView) child.findViewById(R.id.tv_cl_tip);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
mHolder.txt_idclient.setText(idclient.get(pos));
mHolder.txt_numeclient.setText(numeclient.get(pos));
mHolder.txt_tipclient.setText(tipclient.get(pos));
return child;
}
public class Holder {
TextView txt_idclient;
TextView txt_numeclient;
TextView txt_tipclient;
}
Of course it does not work like this. The list is not refreshed... I assume it has to do with the displayAdapter !?!?!
I cannot call the LoadList method since it is static or something like that...
Please help.
Thank you
Its not a problem with your adapter. You have to call Loadlist() in onresume method instead of oncreate method in ActivityOne. It will work then.
First of all, have a look at this two articles:
http://www.doubleencore.com/2013/05/layout-inflation-as-intended/
http://www.doubleencore.com/2013/06/context/
You shouldn't inflate your views with null in your inflate method if you have parent view available.
Also, using application context for inflating may cause strange behaviour, as it may not use correct theme you may've set in app manifest for your Activity.
On the other hand - why don't you use CursorAdapter instead of BaseAdapter?
The problem with your adapter is, that you don't set the data in it! :)
///EDIT:
I checked the wrong activity - why do you create second adapter in there?
The easiest solution would be to move the LoadList() to onStart.
If you want to do it right, you should use ContentObserver and (probably) CursorAdapter.
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)