I had populated a listview using simplecursoradapter. However, I want to add images, wherein if the answer is correct it should display check on the right and if null or incorrect it should display an x-mark. It does not display anything but there is no error. Here is my activity code:
public class Results extends ListActivity{
DBAdapter db = new DBAdapter(this);
private Cursor mCursor;
ImageView iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.resultslist);
db.open();
fillData();
db.close();
}
private void fillData() {
mCursor = db.getAllInfo();
startManagingCursor(mCursor);
String[] from = new String[]{DBAdapter.KEY_QUESTIONS, DBAdapter.KEY_CORRECTANSWERS, DBAdapter.KEY_YOURANSWERS};
int[] to = new int[]{R.id.textViewquestionresults, R.id.textViewcorrectansresults, R.id.textViewyouranswerresults};
SimpleCursorAdapter c=
new SimpleCursorAdapter(this, R.layout.rowresults, mCursor, from, to);
setListAdapter(c);
}
private class c extends SimpleCursorAdapter{
Context lcontext;
public c(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
lcontext = context;
}
#Override
public View getView(final int pos, View v, ViewGroup parent) {
v = super.getView(pos, v, parent);
final ImageView iv = (ImageView) v.findViewById(R.id.imageViewresults);
final TextView tvQuestion = (TextView) v.findViewById(R.id.textViewQuestion);
final TextView tvCorrectAns = (TextView) v.findViewById(R.id.textViewcorrectansresults);
final TextView tvYourAns = (TextView) v.findViewById(R.id.textViewyouranswerresults);
if(tvYourAns.equals(tvCorrectAns)){
iv.setImageResource(R.drawable.greencheckmark);
}else{
iv.setImageResource(R.drawable.redxmark);
}
return v;
}
}
}
When extending SimpleCursorAdapter, you shouldn't override getView().
You should override newView() and bindView() instead.
In newView() inflate your layout and initialize your views.
In bindView() set your views' values.
Related
I'm currently working on a simple Android application which will allow a user to add/remove/delete a record from a sqlite DB using checkboxes.
The main activity has a listview which renders objects from an exercise adapter. The adapter extends from cursor adapter.
The issue I'm having is when selecting a checkbox, then scrolling down the list so that the checkbox is out of view, the state is lost.
Here are extracts of my main activity and my exercise adapter:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbManager = new DBManager(this);
dbManager.open();
adapter = new ExerciseAdapter(this, dbManager.fetch());
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
}
public void deleteExercise(View view) {
for (int i = 0; i < adapter.getCount(); i++) {
CheckBox c = listView.getChildAt(i).findViewById(R.id.checkBox);
if (c.isChecked()) {
deleteIds.add(adapter.getItemId(i));
}
}
for (Long deleteId : deleteIds) {
dbManager.delete(deleteId);
adapter.update(dbManager.fetch());
}
}
ExerciseAdapter:
public class ExerciseAdapter extends CursorAdapter {
public ExerciseAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.exercise, parent, false);}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Find fields to populate in inflated template
TextView exerciseTitle = view.findViewById(R.id.exerciseTitle);
TextView exerciseDesc = view.findViewById(R.id.exerciseDescription);
TextView exerciseDate = view.findViewById(R.id.exerciseDate);
// Extract properties from cursor
String title = cursor.getString(cursor.getColumnIndexOrThrow("title"));
String desc = cursor.getString(cursor.getColumnIndexOrThrow("description"));
String date = cursor.getString(cursor.getColumnIndexOrThrow("date"));
// Populate fields with extracted properties
exerciseTitle.setText(title);
exerciseDesc.setText(String.valueOf(desc));
exerciseDate.setText(String.valueOf(date));
}
public void update(Cursor cursor) {
this.swapCursor(cursor);
this.notifyDataSetChanged();
}
}
This is adopted code so would like to keep the classes similar to how they are now, unless there is no other option and a big change is required.
Thanks.
I am using Database to inflate my list view and i am using simple cursor adapter to do that. Now i want to expand row on list item click(Like if user Clicks on row, two text views of current row visible to him). I searched a lot but not find any answer. please help!!!! Thank you.
public class CallLogs extends Activity {
EditText from,to;
Button call;
TextView call_from,call_to,date_call,verify;
private SQLiteDatabase database;
String fields[] = { "from", "to", "date" };
private CursorAdapter dataSource;
long profile_counts;
SQLiteDatabase sqLiteDatabase;
DataBaseHandler dbHelper;
MyDataBaseHelper databaseHelper;
MyDBHelper databaseHelper_new;
Button get;
ListView listView;
RelativeLayout r2;
private SimpleCursorAdapter dataAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.call_logs);
databaseHelper_new= new MyDBHelper(this);
from = (EditText)findViewById(R.id.from);
to = (EditText)findViewById(R.id.to);
call_from = (TextView)findViewById(R.id.textView4);
call_to = (TextView)findViewById(R.id.textView6);
date_call = (TextView)findViewById(R.id.textView8);
verify = (TextView)findViewById(R.id.call_from);
call = (Button) findViewById(R.id.call);
get = (Button) findViewById(R.id.get);
call.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String from_num = from.getText().toString();
call_from.setText(from_num);
String to_num = to.getText().toString();
call_to.setText(to_num);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String currentDateandTime = sdf.format(new Date());
DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy, HH:mm:ss");
String date = df.format(Calendar.getInstance().getTime());
date_call.setText(date);
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
Log.d("currentDateandTime",date+"");
String duration = "6 seconds";
databaseHelper_new.addFriend(from_num,to_num,duration,date);
dataAdapter.notifyDataSetChanged();
}
});
displayListView(); }
private void displayListView() {
Cursor cursor = databaseHelper_new.getFriends();
// The desired columns to be bound
String[] columns = new String[] { "call_from", "call_to","call_duration","call_date"};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.code,
R.id.name,
R.id.continent,
R.id.region,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new MyCursorAdapter(
this, R.layout.country_info,
cursor,
columns,
to,
0);
listView = (ListView) findViewById(R.id.listView);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String countryCode = cursor.getString(cursor.getColumnIndexOrThrow("call_from"));
Toast.makeText(getApplicationContext(),countryCode, Toast.LENGTH_SHORT).show();}});}
private class MyCursorAdapter extends SimpleCursorAdapter{
public MyCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//get reference to the row
View view = super.getView(position, convertView, parent);
//check for odd or even to set alternate colors to the row background
if(position % 2 == 0){
view.setBackgroundColor(Color.rgb(238, 233, 233));
}
else {
view.setBackgroundColor(Color.rgb(255, 255, 255));
}
return view;
}}}
Maybe it's not possible please use class that extends BaseAdapter
I want to make a list from some data that I have in my database.
The first two sets of data in my database are first name and last name.
I want my list to show both first and last name instead of now where it only shows the first name. How do I do that? My code looks like this:
private void fillData()
{
Cursor contactCursor = mDbHelper.fetchAllReminders();
startManagingCursor(contactCursor);
String[] from = new String[]{DbAdapter.KEY_FIRST};
int[] to = new int[]{R.id.contactlist};
SimpleCursorAdapter contacts = new SimpleCursorAdapter(this, R.layout.list, contactCursor, from, to);
setListAdapter(contacts);
}
Here is a full implementation. You will need to create a custom row and a custom Array adapter.
Here is a full tutorial http://commonsware.com/Android/excerpt.pdf
This will tell you everything you need to know to get this done.
Also refer here where ive posted another example.
How to add an EditText to a ListView
EDIT: How to build a custom listview and return data from a databse
You first create a listview activity.
public class meeting_list extends ListActivity {
Cursor model = null;
meetingAdapter adapter = null;
//This should be what ever your database helper is from your SQLite base.
meetingHelper helper = null;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.meeting_list);
helper = new meetingHelper(this);
model = helper.getAll();
startManagingCursor
(model);
adapter = new meetingAdapter(model);
setListAdapter(adapter);
registerForContextMenu(getListView());
//Ondestroy is used to close the database to free up resources
#Override
public void onDestroy(){
super.onDestroy();
helper.close();
}
#Override
public void onListItemClick(ListView list, View view, int position, long id){
Intent i = new Intent(meeting_list.this, meeting_create_edit.class);
//
i.putExtra(ID_EXTRA, String.valueOf(id));
startActivity(i);
}
//Here create a class to extend the Cursor Adapter
class meetingAdapter extends CursorAdapter{
meetingAdapter(Cursor c){
super(meeting_list.this, c);
}
#Override
public void bindView(View row, Context ctxt, Cursor c) {
meetingHolder holder = (meetingHolder)row.getTag();
holder.populateFrom(c, helper);
}
#Override
public View newView(Context ctxt, Cursor c, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.mrow, parent, false);
meetingHolder holder = new meetingHolder(row);
row.setTag(holder);
return row;
}
}
//Here create a class to actually hold the view for the row in the listview.
static class meetingHolder{
private TextView mtitle = null;
private TextView maddress = null;
private ImageView Icon = null;
meetingHolder(View row){
mtitle=(TextView)row.findViewById(R.id.mtitle);
maddress = (TextView)row.findViewById(R.id.address);
Icon = (ImageView)row.findViewById(R.id.Micon);
}
//Here populate the row with the data from your database
void populateFrom(Cursor c, meetingHelper helper){
mtitle.setText(helper.getMettingTitle(c));
maddress.setText(helper.getAddress(c));
This should do it. Just substitute your informations where it should be. This is a tutorial ive put together for you.
Now i have tried to edit the code according to your guide, what i have done for now looks like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
mDbHelper = new DbAdapter(this);
mDbHelper.open();
fillData();
}
private void fillData()
{
Cursor contactCursor = mDbHelper.fetchAllReminders();
startManagingCursor(contactCursor);
String[] from = new String[]{DbAdapter.KEY_FIRST};
int[] to = new int[]{R.id.contactlist};
SimpleCursorAdapter contactsfirst = new SimpleCursorAdapter(this, R.layout.list, contactCursor, from, to);
String[] from2 = new String[]{DbAdapter.KEY_LAST};
int[] to2 = new int[]{R.id.contactlist};
SimpleCursorAdapter contactslast = new SimpleCursorAdapter(this, R.layout.list, contactCursor, from2, to2);
setListAdapter(contactsfirst,last);
}
And my xml file looks like this:
<?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"
>
<TextView
android:id="#+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40sp"
/>
<TextView
android:id="#+id/last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40sp"
/>
</LinearLayout>
I have a listview which populates its content from SQLite Database.
Here's my code:
ListView listView = (ListView) findViewById(R.id.lstText);
listView.setOnItemClickListener(this);
listView.setAdapter(new MySimpleCursorAdapter(this, R.layout.listitems,
managedQuery(Uri.withAppendedPath(Provider.CONTENT_URI,
Database.Project.NAME), new String[] { BaseColumns._ID,
Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, null, null, null),
new String[] { Database.Project.C_PROJECTTITLE,
Database.Project.C_SMALLIMAGE, Database.Project.C_PROJECTDESCRIPTION, Database.Project.C_ORGANIZATIONTITLE}, new int[] {
R.id.txt_title, R.id.image, R.id.txt_list_desc, R.id.txt_org}));
I want to put an extra String to some TextViews above when its displayed on the list. For example, I want to add a String with the word "from" on R.id.txt_org, before the populated String from the database which is Database.Project.C_ORGANIZATIONTITLE
Let's say the populated String is: New Organisation,
with an extra String "from" what will be displayed is: from New Organisation
Can anybody help me with that? Thank you very much.
EDITED:
FYI, this is my SimpleCursorAdapter method:
class MySimpleCursorAdapter extends SimpleCursorAdapter {
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
loader = new ImageLoader(context);
this.context = context;
}
Context context=null;
ImageLoader loader = null;
public void setViewImage(ImageView v, String value) {
v.setTag(value);
loader.DisplayImage(value, context, v);
}
}
Since you're already using a custom adapter, override the adapter's bindView() and newView() methods, rather than getView(). That way you will not have to manually deal with recycling the row's view.
Within these method you can get the data from the resulting Cursor and manipulate it before binding it to your row's view.
GetView Vs. BindView in a custom CursorAdapter?
How to override CursorAdapter bindView
//Edit: some more code below. Note that this is just a rough outline and by no means complete or tested.
class MySimpleCursorAdapter extends SimpleCursorAdapter {
private ImageLoader mLoader = null;
private LayoutInflater mInflater = null;
private int mBusinessNameIndex = -1;
private int mSmallImageIndex = -1;
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
mLoader = new ImageLoader(context);
mInflater = getLayoutInflater();
mBusinessNameIndex = c.getColumnIndexOrThrow(Database.Project.NAME);
mSmallImageIndex = c.getColumnIndexOrThrow(Database.Project.C_SMALLIMAGE);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.row, null);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Get your views from 'view'
TextView someTextView = (TextView) view.findViewById(R.id.xxx);
ImageView someImageView = (ImageView) view.findViewById(R.id.yyy);
// Set the data
someTextView.setText("from " + cursor.getString(mBusinessNameIndex));
mLoader.DisplayImage(cursor.getString(mSmallImageIndex ), context, someImageView);
}
}
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