Android ListView with a checkbox - android

I've now spent a full day on trying to get a custom row to load. There seem to be plenty of examples here on StackOverflow and other places on how to bind a checkbox to a row of data within an Android listview, but they all seem to be incomplete.
Here's what I have (row.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="40dip"
android:orientation="horizontal" android:background="#drawable/row_bk"
android:layout_gravity="center_vertical">
<TextView android:id="#+id/ItemID"
android:layout_weight="0" android:visibility="gone"
android:layout_width="0dp" android:gravity="center"
android:layout_height="wrap_content" />
<TextView android:id="#+id/Title"
android:layout_width="0dp" android:textColor="#666"
android:layout_weight="1" android:layout_height="40dip"
android:padding="5dp" android:gravity="center_vertical"
android:textSize="17dip" />
<CheckBox android:id="#+id/chkCheck" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:focusable="false" android:focusableInTouchMode="false" android:clickable="true"></CheckBox>
</LinearLayout>
In code, I have a SimpleCursorAdapter, populating the ListView.
Cursor oLoop = db
.rawQuery(
"select _id, title, is_checked from tbl",null);
startManagingCursor(oLoop);
String[] from = new String[] { "_id", "title", "is_checked" };
int[] to = new int[] { R.id.ItemID, R.id.Title, R.id.chkCheck };
SimpleCursorAdapter oList =
new SimpleCursorAdapter (this, R.layout.task_item_row, oLoop, from,
to);
setListAdapter(oList);
Past this, I'm not really sure what to do. If someone could point me at a good example, that would be great. The goal is to actually be able to toggle the checkboxes.
Thanks in advance!
Alex

Alex,
The next step is to implement ViewBinder.setViewValue()
It would look something like this:
getViewAdapter().setViewBinder(
new ViewBinder(){
public boolean setViewAdapter(View view, Cursor cursor, int columnIndex){
<JavaType> object = cursor.get<JavaType>(columnIndex);
boolean isHandled = false;
if(view.getId() == R.id.checkBox){
CheckBox cb = (CheckBox) view;
cb.setChecked(isObjectChecked(object));
// object depends on your underlying data type
// in the data base, use the debugger to find the actually implemented type.
isHandled = true;
}
return isHandled;
}
}
);
This can be a very powerful method with conditionally visible views and loading Uri's from the network, etc.

Related

Can't get view to set elements of LISTVIEW

have problem with 'listView'. I searched everywhere but the problem does not arise none. Let me explain:
I have classic 'listview' in my 'layout':
<?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="fill_parent"
android:orientation="vertical"
android:id="#+id/roza"
android:tileMode="repeat">
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#80ffffff"
android:alpha="200">
</ListView>
<TextView
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/no_todos" />
</LinearLayout>
And i create custom list_row xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/list_name"
android:layout_alignParentTop="true"
android:textSize="25dp"
android:layout_alignParentStart="true"
android:layout_alignEnd="#+id/list_rune" />
------------bla bla bla -----------------
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:layout_alignTop="#+id/list_date_update"
android:layout_toLeftOf="#+id/list_rune"
android:layout_toStartOf="#+id/list_rune"
android:id="#+id/textTester" />
</RelativeLayout>
My main class -
public class MainActivity extends ListActivity implements AdapterView.OnItemLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
private NordBase dbHelper;
private Cursor cursor;
int rage = list_row; // my custom row
-------------------on create----------------
setContentView(R.layout.activity_main);
this.getListView().setDividerHeight(2);
dbHelper = new NordBase(this);
fillData();
------------------fillData-----------------
cursor = dbHelper.getAll();
startManagingCursor(cursor);
String[] from = new String[] { NordBase.NORD_NAME, NordBase.NORD_DESCRIPTION,
NordBase.NORD_PUNKTS, NordBase.NORD_PUNKTS_CROSS,
NordBase.NORD_DATE_CREATE, NordBase.NORD_DATE_UPDATE, NordBase.NORD_RUNE,
NordBase.NORD_IMPORTANT, NordBase.NORD_SUM };
int[] to = new int[] { R.id.list_name, R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum, };
notes = new SimpleCursorAdapter(this,
rage, cursor, from, to);
setListAdapter(notes);
getListView().setOnItemLongClickListener(this);
Alas, I can not get to the items inside list_row, to bind them for comparison operators. for exp: if price == 0, then textview.setvisible = false...
I try LayoutInflater, but he make view element difrent from those in listview.
I try adapter binder class - but i think its no good for that.
Mostly i have an error - can't do that for the "null element"... that case - looks like all i ever do - my program can't findViewById elements in the list_row.
There is one point of contact
int[] to = new int[] { R.id.list_name, R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum, };
notes = new SimpleCursorAdapter(this,
rage, cursor, from, to);
So help me Obi-Van Kenobi, and sorry for my dummy ENG, and i'm not sure that i past cod in right way)))
First of all your layout is not having the views which you have mention in the adapter like
R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum
put this thing in the layout list_row xml
if you mean by ------------bla bla bla -----------------
this views than ok
also simpleCursorAdapter will not solve your purpose as you want to hide and show the views based on the data in respective views
so my first suggestion Change your layout to linearLayout or tableLayout or other layout as you feel and then do this in Your CustomAdapter class
like
class MyAdapter extends BaseAdapter
{
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//here you infalteYour layout and and do your logical thing
//you can take your data out from cursor and store in the arrayList<YourModelClass> type and have better control
}
}
otherwise in relative layout just fill the data don't hide it so it may work but if you do hiding of some views chances are high it will not solve your problem
and typo mistake is there i hope so like
int[] to = new int[] { R.id.list_name, R.id.list_description, R.id.list_punkts,
R.id.list_punkts_cross, R.id.list_date_create, R.id.list_date_update,
R.id.list_rune, R.id.list_important, R.id.list_sum, };
//here no item but still u have written "," after R.id.list_sum this like "R.id.list_sum, "
notes = new SimpleCursorAdapter(this,
rage, cursor, from, to);

android ViewBinder with SimpleCursorAdapter

I would like to know if my solution using a ViewBinder is correct and suitable for my problem.
I have implememented a ContentProvider. The startactivity extends ListActivity and displays all the entries from a sqliteDB using my contentprovider. A Click on one of the entries in the listview starts another activity showing detailinformation about this entry:
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// Arzneimittel wurde durch Klick ausgewählt --> Detailansicht anzeigen
Intent intent = new Intent(this, MedikamenteDetailActivity.class);
intent.putExtra("_ID", id);
startActivity(intent);
}
This is the layout of the Detail-Activity:
<?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="vertical" >
<TextView
android:id="#+id/txtV_heading_statusinfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/heading_status_info"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="#+id/datalist"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
<TextView
android:id="#+id/txtV_PhZnr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_phznr"
android:text="TextView" />
<TextView
android:id="#+id/txtV_Znr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/znr"
android:text="TextView" />
<TextView
android:id="#+id/txtV_SName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/sname"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/txtV_OName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/oname"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/txtV_DoLC"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/dolc"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
The Detail - Activity Class:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_medikamente_detail);
_id = String.valueOf(getIntent().getExtras().getLong("_ID"));
mAdapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
null,
mFromColumns,
new int[]{android.R.id.text1},
0);
mCallbacks = this;
ListView mListView = (ListView) findViewById(R.id.datalist);
mAdapter.setViewBinder(new ViewBinder());
mListView.setAdapter(mAdapter);
getLoaderManager().initLoader(URL_LOADER, null, mCallbacks);
}
Within the activity I implemented an inner class for die ViewBinder:
private class ViewBinder implements SimpleCursorAdapter.ViewBinder {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(view.getId() == R.id.txtV_PhZnr) {
TextView phznr = (TextView)view;
phznr.setText(cursor.getString(columnIndex));
return true;
}
return false;
}
}
The binding works yet the data is bound to the listview. The other ViewElements stay empty. I can't really understand, why I set the Text of the view "R.id.txtV_PhZnr" and this text appears in the listview-element while the txtV_PhZnr stays empty.
Why do I need a listView-element. As this is a master-detail relationship, only one dataset can be shown in the detail view.
Thank you very much!
Why do I need a listView-element.
No, you do not need one. You can just load the data from your content provider and bind it to the TextViews that you have defined (the ones with ids txtV_xxx). Do this in the onLoadFinished() method.
I can't really understand, why I set the Text of the view "R.id.txtV_PhZnr" and this text appears in the listview-element while the txtV_PhZnr stays empty.
The view parameter passed to setViewValue() method of ViewBinder will only have one of the ids from the array of view ids that you instantiate the SimpleCursorAdapter with. In your case the view parameter will only have the id android.R.id.text1 since the passed-in array contains only this view id. Thus the body of if(view.getId() == R.id.txtV_PhZnr) {...} will never get executed. Hence txtV_PhZnr stays empty.
ViewBinder is used only when you need to alter the binding of data to views based on some condition. As far as your case goes, there is neither a need for a ListView nor a ViewBinder.

How to store checked list state in listview android?

I am using listview to display three textviews(values for these text views where come from database) and one checkbox. I would like to store the checkbox state when ever the user clicks the checkbox and display it when they came back. But, i am new to android development and i haven't got any idea how to do it. I have tried adding checkbox to the list view, but the onitemclick is disabled.Below are the code,
This is the cursor to retrieve values from database and list in listview,
Cursor yearcursor = db.paymentall(this);
String[] yearfrom = new String[]
{ PaymentAppDataBase.REQUESTEDDATE,PaymentAppDataBase.PAYMENTNAME,PaymentAppDataBase.AMOUNT };
int[] yearto = new int[] { R.id.Date,R.id.Name,R.id.Amount };
SimpleCursorAdapter yearadapter =
new SimpleCursorAdapter(this, R.layout.listview, yearcursor, yearfrom, yearto);
setListAdapter(yearadapter);
amount.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Cursor cursor = (Cursor) parent.getItemAtPosition(position);
String toaddressreview = cursor.getString(4);
String subjectreview = cursor.getString(5);
String emailbodyreview = cursor.getString(6);
Intent todayreview = new Intent(ReviewPayment.this,ReviewandResend.class);
todayreview.putExtra("toadd", toaddressreview);
todayreview.putExtra("subjectreveiew", subjectreview);
todayreview.putExtra("emailbody", emailbodyreview);
startActivity(todayreview);
}
});
Mt xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="4dip"
android:paddingBottom="6dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:id="#+id/Date"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:textSize="14sp"/>
<TextView android:id="#+id/Name"
android:layout_width="120dip"
android:layout_height="wrap_content"
android:layout_weight="2"
android:scrollbarAlwaysDrawHorizontalTrack="true"
android:layout_toRightOf="#+id/Date"/>
<TextView android:id="#+id/Amount"
android:layout_width="50dip"
android:layout_height="20dip"
android:scrollbarAlwaysDrawHorizontalTrack="true"
android:layout_weight="2"
android:layout_toRightOf="#+id/Name"/>
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="50dip"
android:layout_alignBottom="#+id/Amount"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/Amount" />
</RelativeLayout>
It would be great if i get the answer for two questions,
1. How to save the state of the checkbox?
2. How to enable onitemclicklistener while using checkbox?
Thanks in advance
There is no easy way but to keep an array of boolean equal to the number of your list items and store the state. You need to make this a member variable of the custom adapter that you derive from your SimpleCursorAdapter.
Again, it needs to be part of your custom adapter. In your getView() function of the adapter, you need to implement the onCheckedChangeListener() [don't recall the exact name right now] for the checkbox and in your main Activity where you have the listview, set the onItemClickListener() to the listview.
If this doesn't make sense, just go through a bit in stackoverflow. This question has been dealt with numerous times.

how to implement a checkbox in each row in a Listview

It's my first Andoid app. I can't implement a multiple choise in my ListView(i want a checkbox in every row in my listview).
I'm using the notepadv3 tutorial.
Can someone help me, i'm a newbie in java.
private void fillData() {
ListView lView = (ListView) findViewById(android.R.id.list);
// Get all of the notes from the database and create the item list
//lView = (ListView) findViewById(R.id.liste);
Cursor c = mDbHelper.fetchAllNotes();
startManagingCursor(c);
String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
int[] to = new int[] { R.id.text1 };
// Now create an array adapter and set it to display using our row
SimpleCursorAdapter notes =
new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
setListAdapter(notes);
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ListView
android:id="#+id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox android:text=""
android:id="#+id/list_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
/>
<TextView android:id="#id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/no_notes"/>
You need to include the checkbox in the xml layout R.layout.notes_row. If you post your xml code we might be able to help you more.
This thread in SO shows you how to display a CheckBox and TextView in each row of ListView and how to bind them to the database:
Android: Binding data from a database to a CheckBox in a ListView?
You might want to have a look.

Separating columns in listview

I am trying to separate different columns of data that appear in my listview. The code for the adapter is as follows:
public class SQLiteDemo extends ListActivity {
private SQLiteDatabase database;
private CursorAdapter dataSource;
private static final String fields[] = { "firstname", "lastname", "resourceid", BaseColumns._ID };
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
DatabaseHelper helper = new DatabaseHelper(this);
database = helper.getWritableDatabase();
Cursor data = database.query("cards", fields, null, null, null, null,
null);
dataSource = new SimpleCursorAdapter(this, R.layout.second, data, fields,
new int[] { R.id.firstname, R.id.secondname, R.id.name });
ListView view = getListView();
view.setHeaderDividersEnabled(true);
view.addHeaderView(getLayoutInflater().inflate(R.layout.second, null));
setListAdapter(dataSource);
I defined the listview in my layout file (do I need to do this for the inflater view?)
I have tried adding the dividers as follows....
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
android:divider = "#android:color/transparent"
android:dividerHeight ="10.sp" />
There does not seem to be any difference after adding the divider items; what am I doing wrong?
To be clear, I am a complete android noob, not looking for a complete answer (although they can be useful sometimes) just a nudge in the right direction would be more than enough. Thanks guys!
EDIT WITH R.layout.second
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:id="#+id/rowLayout"
android:orientation="horizontal"
android:layout_width="fill_parent">
<TextView android:layout_width="wrap_content"
android:layout_alignParentTop = "true"
android:layout_alignParentLeft="true"
android:layout_height="wrap_content"
android:id="#+id/firstname"
android:text="FirstName"/>
<TextView android:layout_width="wrap_content"
android:layout_toRightOf = "#+id/firstname"
android:layout_height="wrap_content"
android:id="#+id/secondname"
android:text="SecondName"
/>
<TextView android:layout_width="wrap_content"
android:layout_toRightOf = "#id/secondname"
android:layout_height="wrap_content"
android:id="#+id/name"
android:text="ResourceID"
/>
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
android:dividerHeight ="10.sp" />
</RelativeLayout>
I have removed the divider transparency now that I know what it does.
You have a misunderstanding. You are using the same Layout (R.layout.second) for two different things.
You need one Layout for the whole screen that contains a ListView (i.e. R.layout.second).
setContentView(R.layout.second)
And then you use an other Layout (i.e. mycell.xml) to define the looks of a sigle row in that ListView.
new SimpleCursorAdapter(this, R.layout.mycell, data, fields, new int[] { R.id.firstname, R.id.secondname, R.id.name });
The divider is drawn horizontally for each row in your database. You made it invisible.
If you want to have dividers between firstname,lastname , etc (for each column) you have to edit the Layout you are using for the rows (R.layout.mycell).

Categories

Resources