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.
Related
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.
OK I've searched and seen similar issues, tried them and no avail. I have a listView with some elements and I want to click on one element and display a detail somewhere else.
This is my listView
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pedidos);
ListView listView = (ListView) findViewById(R.id.actualStoresList);
Model.initialize();
Vector<String> values = Model.stores;
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position,
long id) {
Object o = adapter.getItemAtPosition(position);
String str_text = o.toString();
Log.i("", "I have selected this: " + str_text);
}
});
CustomStringAdapter adapter = new CustomStringAdapter(this, R.layout.my_list_layout, R.id.list_content, values);
listView.setAdapter(adapter);
}
This is the my_list_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/list_content"
android:textColor="#000000"
android:gravity="center"
android:layout_margin="4dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dp"/>
</LinearLayout>
The list gets displayed correctly. When I click on an element of the list (A textView) it "steals" the click event so nothing happens (the onItemClickListener is attached to the listView, not the TextView).
The textView has an small margin where, if careful, I can click just behind it, in fact, touching the listView. In this case, the event gets fired ok and I see the log.
I've tried to set the TextView android:focusable="false" but still, the TextView is "above" of the listView and always gets the click events.
How can I either make the TextView "transparent" so it actually clicks on the listView, or add a onclickListener to the TextView so I can handle its events?
Thanks!
Alejandro
Setting clickable property of TextView to false should solve this problem. Try this:
<TextView
android:id="#+id/list_content"
android:textColor="#000000"
android:gravity="center"
android:layout_margin="4dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:clickable="false" />
To make items not focusable, do this:
listView.setItemsCanFocus(false);
source
I think this will solve your issue.
Also make sure the
android:textIsSelectable
property is not set to true.
I've done a Custom Listview with 3 columns:
Product / Selected (check box)/ Quantity.
The first column i've get from sqllite database. And second and third column, i'll write into a database.
I've the problem that when i write into qunatity column the checkbox i've checked is unchecked, and it doesn't work.
Another problem is when select edittext to write a quantity the checkbox selections changes.
//productos.java
Button btComanda = (Button) findViewById(R.id.btComanda);
btComanda.setOnClickListener(new OnClickListener() {
public void onClick (View arg0) {
Log.v("Escriu Comanda", "inici");
final ListView prodSpinner = (ListView) findViewById(R.id.list);
final CheckBox cbArticle = (CheckBox) findViewById(R.id.TextView02);
final TextView txtQuantitat = (TextView) findViewById(R.id.TextView03);
int count = 0;
Log.v("Escriu Comanda 2",String.valueOf(prodCursor.getCount())+ " " + txtQuantitat);
for(int i = 0; i < prodCursor.getCount(); i++)
{
Log.v("inserta 1", String.valueOf(Producte)+ " " + cbArticle.isChecked());
Producte = i;
String a = prodSpinner.getItemAtPosition(i).toString();
InsertaComanda();
});
recCatSpinner();
}
public void recProdSpinner() {
ListView prodSpinner = (ListView) findViewById(R.id.list);
prodCursor = recuperaProductos();
prodSpinner.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
prodAdapter = new ArrayAdapter<String>(this, R.layout.listview, R.id.TextView02);
prodAdapter.setDropDownViewResource (R.layout.listview_item_row);
prodSpinner.setAdapter(prodAdapter);
if (prodCursor.moveToFirst()) {
do {
prodAdapter.add(prodCursor.getString(1));
}
while (prodCursor.moveToNext());
if (db != null) {
db.close();
}
}
startManagingCursor(prodCursor);
prodCursor.close();
prodSpinner.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View view, int pos, long id) {
}
});
}
The xml file:
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10.77" >
<TableRow
android:id="#+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</TextView>
<CheckBox
android:id="#+id/TextView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+id/TextView02"
android:focusable="false" />
<EditText
android:id="#+id/TextView03"
android:layout_width="138dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
</TableLayout>
</LinearLayout>
Read about how ListViews work and you will understand why its happening - the ListView is populating each row when it appears on the screen (so your values and states will change when you scroll)
so what you need to do is to save the state at the moment the user is changing it to somewhere safe - array / database etc.. and when you load it under your custom list adapter you need to change the state into the right one
so for your checkboxs you need to implement a listener and save its state when it is changing and under getView you need to set the specific CheckBox to its saved state .
the thing is EditTexts inside ListViews is pretty damn problematic but it is possible if you are stubborn enough.
hope it helps and tell me if you need any more help.
in addition to
android:focusable="false"
add this also..
"android:clickable="false""
i think it works.. let me know if it doesn't..
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.
I am using a LinearLayout to display some Text and image. I have the images at drawable/ and i am implimenting this with ListActivity with some onListItemClick functionality. now i wants to change the image for the rows which are processed by onclick functionality to show the status as processed. can some one help me in this issue to change the image at runtime.
the following is my implimentation.
public class ListWithImage extends ListActivity {
/** Called when the activity is first created. */
private SimpleCursorAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// raj setContentView(R.layout.main);
Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
startManagingCursor(cursor);
String[] columns = new String[] {People.NAME, People.NUMBER};
int[] names = new int[] {R.id.contact_name, R.id.contact_number};
myAdapter = new SimpleCursorAdapter(this, R.layout.main, cursor, columns, names);
setListAdapter(myAdapter);
}
#Override
protected void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
Intent intent = new Intent(Intent.ACTION_CALL);
Cursor cursor = (Cursor) myAdapter.getItem(position);
long phoneId = cursor.getLong(cursor.getColumnIndex(People.PRIMARY_PHONE_ID));
intent.setData(ContentUris.withAppendedId(Phones.CONTENT_URI, phoneId));
startActivity(intent);
}
}
and main.xml is :
<LinearLayout
android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="250px">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name: " />
<TextView android:id="#+id/contact_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phone: " />
<TextView android:id="#+id/contact_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
I thought to add the field to DB. but i was unable to know how to change the image with code. can any one provide me an example for drawing image with code and change it based on a condition at runtime.
I've done the same thing in my application (however I didn't use a cursoradapter but a custom adapter, however the logic should be the same).
What I needed to get this working was to include a field in the db which specifies wheater or not the field is processed (or some field deciding which image to show). Then you need to bind your images address to that field. I don't know if you can do this with the simplecursoradapter, or if you need to implement your own though.
Then, when a user clicks an item you just set that item as processed in the db, and you tell your adapter that it has been updated.