My getView() method for customized ListViewAdapter is as follows :
public class ListViewAdapter extends BaseAdapter {
Context mContext;
LayoutInflater mInflater;
ArrayList mArray;
ArrayList<Item> mArray2;
DBHelper mydb;
String dbName;
public ListViewAdapter(Context context, LayoutInflater inflater) {
mContext = context;
mInflater = inflater;
mArray = new ArrayList();
mArray2 = new ArrayList<>();
mydb = new DBHelper(mContext);
}
#Override
public int getCount() {
return mArray.size();
}
#Override
public Object getItem(int position) {
return mArray.get(position);
}
public Item getItem2(int position) { return mArray2.get(position); }
#Override
public long getItemId(int position) {
// your particular data set uses String IDs
// but you have to put something in this method
return position;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
ViewHolder holder;
// check if the view already exists
// if so, no need to inflate and findViewById again!
if (convertView == null) {
// Inflate the custom row layout from your XML.
convertView = mInflater.inflate(R.layout.list_item, null);
// create a new "Holder" with subviews
holder = new ViewHolder();
holder.itemNameView = (TextView) convertView.findViewById(R.id.item_name);
holder.itemExpiryView = (TextView) convertView.findViewById(R.id.item_expiry);
// Taking care of the buttons
holder.editButton = (Button) convertView.findViewById(R.id.button_edit);
holder.deleteButton = (Button) convertView.findViewById(R.id.button_delete);
// hang onto this holder for future recycling
convertView.setTag(holder);
} else {
// skip all the expensive inflation/findViewById
// and just get the holder you already made
holder = (ViewHolder) convertView.getTag();
}
// Set listener on the buttons
holder.editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, "Edit Button CLicked", Toast.LENGTH_SHORT).show();
}
});
holder.deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = getItem(position).toString();
int id = mydb.getID(dbName, name);
mydb.deleteItem(dbName, id);
mArray2 = mydb.getAllItemsAsCollection(dbName);
notifyDataSetChanged();
Toast.makeText(mContext, "Item deleted", Toast.LENGTH_SHORT).show();
}
});
// Doing for 2nd case
Item _item = getItem2(position);
String name2 = _item.name;
System.out.println(name2);
String ex = _item.expiry;
System.out.println(ex);
// For the second case
holder.itemNameView.setText(name2);
holder.itemExpiryView.setText(ex);
return convertView;
}
// this is used so you only ever have to do
// inflation and finding by ID once ever per View
private static class ViewHolder {
public TextView itemNameView;
public TextView itemExpiryView;
public Button editButton;
public Button deleteButton;
}
public void updateData2(ArrayList<Item> arrayPassed) {
// update the adapter's data set
mArray2 = arrayPassed;
notifyDataSetChanged();
}
public void setDbName(String dbName){
this.dbName = dbName;
}
}
The DBHelper class function getAllItemsAsCollection() is defined as below :
public ArrayList<Item> getAllItemsAsCollection(String dbName)
{
ArrayList<Item> array_list = new ArrayList<Item>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from " + dbName, null );
res.moveToFirst();
while(res.isAfterLast() == false){
String n = res.getString(res.getColumnIndex(COLUMN_NAME));
String e = res.getString(res.getColumnIndex(COLUMN_EXPIRY));
String c = dbName;
Item _item = new Item(n, e, c);
array_list.add(_item);
res.moveToNext();
}
return array_list;
}
And also, the insertItem() function inside DBHelper is this :
public boolean insertItem (String dbName, String name, String expiry)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
contentValues.put("expiry", expiry);
db.insert(dbName, null, contentValues);
return true;
}
I have added a separate class for customizable object handing :
public class Item {
String name;
String expiry;
String category;
Item(String n, String e, String c){
this.name = n;
this.expiry = e;
this.category = c;
}
}
And the addItem() method inside MainActivity.java works like :
public void addItem(final View v) {
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
LinearLayout lila1 = new LinearLayout(this);
lila1.setOrientation(LinearLayout.VERTICAL);
final EditText name = new EditText(this);
name.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
final EditText days = new EditText(this);
days.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
TextView text_ex = new TextView(this);
text_ex.setText("In how many days will it expire..");
alert.setTitle("Hello!");
alert.setMessage("What did you buy today..");
lila1.addView(name);
lila1.addView(text_ex);
lila1.addView(days);
alert.setView(lila1);
// Make an "OK" button to save the name
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Grab the EditText's input
String inputName = name.getText().toString();
String daysToExpiry = days.getText().toString();
System.out.println(daysToExpiry);
mydb.insertItem(currentDB, inputName, daysToExpiry);
System.out.println("Worked");
// For 2nd Case
currentList2 = mydb.getAllItemsAsCollection(currentDB);
System.out.println("Random Musings");
itemAdder2.updateData2(currentList2);
// addItemToList(inputName, v);
dialog.dismiss();
}
});
// Make a "Cancel" button
// that simply dismisses the alert
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
alert.show();
}
I have initiaized every variable correctly. When I try to run my app, and try to add a new item, the Dialog box just vanishes and there is nothing shown in the layout. I tried with a simple ArrayList<Strings> before and it worked perfectly. That is why I believe there should not be any problem with the .xml Layout. And might be with the ListViewAdapter.updateData2() function. Please Help. Appreciate your patience going through these long pieces of code. If any further info is required, please let me know. Thanks a lot. :)
Forgot to attach the .xml for actual view. This worked perfectly with ArrayList<String>. I have already tested. When I tried to pass complex object, in this case, Item-class object, and correspondingly an ArrayList<Item>, my guess is, I could not write the adapter portion code correctly.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:id="#+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/item_expiry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/item_name" />
<Button
android:id="#+id/button_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/item_expiry"
android:layout_alignParentLeft="true"
android:text="Edit"
android:clickable="true" />
<Button
android:id="#+id/button_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/item_expiry"
android:layout_alignParentRight="true"
android:text="Delete"
android:clickable="true" />
</RelativeLayout>
Related
list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="5dp">
<TextView
android:id="#+id/mytitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dp"
android:layout_toRightOf="#+id/icon"
android:background="#drawable/textbox1"
android:paddingBottom="10dp"
android:text="Title"
android:textColor="#CC0033"
android:textSize="20dp" />
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/mytitle"
android:layout_marginLeft="20dp"
android:scaleType="fitXY"
android:paddingLeft="10dp"
android:paddingRight="10dp" />
<TextView
android:id="#+id/descri"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/mytitle"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/icon"
android:layout_marginTop="16dp"
android:background="#drawable/textbox1"
android:text="Description"
android:textColor="#3399FF"
android:textSize="14dp" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/mytitle"
android:layout_toLeftOf="#+id/mytitle"
android:layout_marginLeft="5dp"
android:background="#drawable/buttontextview"
android:text=" Click To Share"
android:textColor="#android:color/white"
android:textSize="13sp" />
This is my RowItem class
public class RowItem {
private String imagepath;
private String title;
private String desc;
public boolean isclicked;
public RowItem(String imagepath,String title,String desc) {
System.out.println("ImagePath is:---"+imagepath);
this.imagepath = imagepath;
System.out.println("Title is:---"+title);
this.title = title;
System.out.println("Description is:---"+desc);
this.desc = desc;
isclicked = false;
}
public String getImagepath() {
return imagepath;
}
public boolean isIsclicked() {
return isclicked;
}
public void setIsclicked(boolean isclicked) {
this.isclicked = isclicked;
}
public void setImagepath(String imagepath) {
this.imagepath = imagepath;
}
public String getTitle() {
return title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public void setTitle(String title) {
this.title = title;
}
#Override
public String toString() {
return title + "\n" + desc;
}
}
This is my onCreate() Method from the Activity
{ int k = 0;
if(i>0){
rowItems = new ArrayList<RowItem>();
for (int j = 0;j<i ; j++) {
System.out.println("Loop Value:--"+j);
System.out.println("Location Details:-----"+location.get(j));
System.out.println("Description Details:------"+description.get(j));
System.out.println("Image Details:------"+images.get(j));
RowItem item = new RowItem(images.get(j),location.get(j),description.get(j));
rowItems.add(item);
}
listView = (ListView) findViewById(R.id.list);
adapter = new CustomListViewAdapter(PicActivity.this, rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
This is my listitem onClicklistner method
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
System.out.println("My List Item Clicked");
mylistid = position;
Button deleteBtn = (Button) findViewById(R.id.delete);
deleteBtn.setOnClickListener(this);
File myimagefile = new File(images.get(position));
lastlistid = mydb.getlastlistid();
int list = Integer.valueOf(lastlistid.get(0));
listno=0 ;
listno = list-position;
SharedPreferences mylistpref = getSharedPreferences(Constants.listiddetails, 0);
Editor edit= mylistpref.edit();
edit.putInt("listid", listno);
edit.commit();
System.out.println("First Position Value:-"+position);
Toast toast = Toast.makeText(getApplicationContext(),
"Title " + (position + 1) + ": " + rowItems.get(position),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
Intent intermediate = new Intent (PicActivity.this,InterMediateActivity.class);
intermediate.putExtra("savenshare", "notshare");
intermediate.putExtra("flag", "false");
startActivity(intermediate);
finish();
}
The Checkbox is coming in the listview but onItemclicklistner is not working.
My deleteButton onClicklistner is like this
case R.id.delete:
System.out.println("My List item:-"+mylistid);
((CustomListViewAdapter)listView.getAdapter()).notifyDataSetChanged();
break;
Here mylistid is a global integer which i am setting while on listitemonclick.
Why my list item onclicklistner not working if i add checkbox in my list and also how can i delete the row and update the listitem.I have followed many tutorials but unable to implement.
Please help !!!!
UPDATE
This is my customListViewAdapter Class
public class CustomListViewAdapter extends BaseAdapter {
private List<RowItem> arr = new ArrayList<RowItem>();
ArrayList<Integer> checks=new ArrayList<Integer>();
private Context context;
Bitmap mybitmap;
private Activity activity;
ViewHolder holder = null;
int mypos=0;
File f;
RowItem rowItem;
public CustomListViewAdapter(Context context,List<RowItem> items) {
//super();
this.arr = items;
this.context=context;
}
private class ViewHolder {
//ImageView imageView;
TextView txtTitle;
TextView txtDesc;
ImageView image;
// CheckBox mychk;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return arr.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
//mypos=arg0;
return arr.get(arg0);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
rowItem = (RowItem) getItem(position);
f = new File(rowItem.getImagepath());
System.out.println("My list item Position from GetView:--"+position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.txtDesc = (TextView) convertView.findViewById(R.id.descri);
holder.txtTitle = (TextView) convertView.findViewById(R.id.mytitle);
// holder.mychk = (CheckBox) convertView.findViewById(R.id.checkBox1);
holder.image = (ImageView) convertView.findViewById(R.id.icon);
// holder.mychk.setOnCheckedChangeListener(this);
// holder.mychk.setTag(arr.get(position));
// holder.mychk.setChecked(false);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
// holder.mychk.setOnCheckedChangeListener(this);
System.out.println("My Description is:--"+holder.txtDesc.getText());
System.out.println("My Title is:--"+holder.txtTitle.getText());
holder.txtDesc.setText(" "+rowItem.getDesc());
holder.txtTitle.setText(" "+rowItem.getTitle());
if(f.exists())
{
mybitmap = BitmapFactory.decodeFile(f.getAbsolutePath());
Bitmap myeditedbitmap = Bitmap.createScaledBitmap(mybitmap, 180, 150, false);
holder.image.setImageBitmap(myeditedbitmap);
//holder.mychk.setChecked(true);
//setImageResource(rowItem.getImagepath());
}
//holder.txtTitle.setText(rowItem.getTitle());
/* for(int i=0;i<ArrayId.size();i++)
{
rowItem.remove(ArrayId[i]);
}
*/
return convertView;
}
}
}
UPDATE 2
I have updated my ListItem xml to some code and now onItemClick is working..
android:descendantFocusability="blocksDescendants"
Now The other part is..delete row item..which is still not working.and also if i select one checkbox then others are also getting selected.like if i select 1..then 3..5..7 is getting selected..How to avoid this ??
My deleteItem row code..
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SparseBooleanArray checkedItemPositions = listView.getCheckedItemPositions();
int itemCount = listView.getCount();
for(int i=itemCount-1; i >= 0; i--){
if(checkedItemPositions.get(i)){
// adapter.remove(rowItems.get(i)); This line is giving me error.first i want to delete row temp and give a toast message.then i will update the database later.but as i am using customarrayadapter class.so i dont have the method remove.Can someone help me regarding the remove method ?
}
}
checkedItemPositions.clear();
adapter.notifyDataSetChanged();
}
});
UPDATE 3
case R.id.delete:
SharedPreferences del = getSharedPreferences(Constants.checkedid,0);
int checkmyid = 0;
checkmyid = del.getInt("check", 0);
int mycount = listView.getCount();
System.out.println("My List item COUNT FROM DELETE METHOD:-"+mycount);
System.out.println("My List item FROM DELETE METHOD:-"+checkmyid);
rowItems.remove(checkmyid);
mydb.delete(checkmyid);
((CustomListViewAdapter)listView.getAdapter()).notifyDataSetChanged();
break;
and my Delete method from database is
public void delete(int id){
String sql = "delete from picdetails where id="+id;
Cursor mych;
mych = myDataBase.rawQuery(sql, null);
}
But when i am reopening the database the data is showing once again.How to avoid ? Also When i am selecting one checkbox to delete that particular checkbox is not getting deleted.the bottom row is getting deleted.
UPDATE 4
i have updated the delete button code..now the row item is getting deleted..but for the first selection its not deleted.its getting deleted from bottom.but the checkitemid is perfect
SharedPreferences del = getSharedPreferences(Constants.checkedid,0);
int checkmyid = 0;
checkmyid = del.getInt("check", 0);
int mycount = listView.getCount();
System.out.println("My List item COUNT FROM DELETE METHOD:-"+mycount);
SparseBooleanArray checked = listView.getCheckedItemPositions();
System.out.println("*****My SELECTED List item FROM DELETE METHOD:-*****"+checkmyid);
rowItems.remove(checkmyid);
For ListView onClickListner not working
It happens due to focusability of CheckBoxin listitem layout.
Add below line to root layout of your ListView's Item layout.
android:descendantFocusability="blocksDescendants"
in list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="5dp"
android:descendantFocusability="blocksDescendants">
To delete row (not sure but will work if make some changes)
for(int i=0; i < itemCount; i++){
if(checkedItem.contains(i)){
View rowView=listView.getChildAt(i) OR listView.removeViewAt(i);
listView.removeView(rowView);
//Also Remove data from **rowItems**
}
}
Here checkedItem is arraylist(or something else) where you supposed store position of checked listrow.
onClick...{
rowItems.remove(position);
notifyDataSetChanged();
}
this should work...
Question part: 1
I have created an activity which contains product id and product name as list items. Each row contains an edittext which can be used to enter quantity for a particular product. The rows also contain a checkbox to select the particular product.
This is how the list looks like:
When I click on the list items, I can get the id and name of the particular list item, but I also want to get the quantity entered by the user for the list item.
This is the activity responsible for generating the listview:
public class PollStationActivity extends Activity {
// Hashmap for ListView
ArrayList<HashMap<String, String>> PSList = new ArrayList<HashMap<String, String>>();
String status_code_from_prev;
List<HashMap<String, String>> fillMaps=null;
String alert_message;
String quantity_message;
//quantity edittext
EditText quantity_edit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_poll_station);
//quantity edittext
quantity_edit = (EditText)findViewById(R.id.qty_editText);
//database insertion
DatabaseHelper db = new DatabaseHelper(this);
ContentValues values = new ContentValues();
try {
db.createDataBase();
values.put("_id", "1");
values.put("name", "rose");
db.insert(values);
} catch (IOException e) {
e.printStackTrace();
}
db.close();
ArrayList<TestItem> PSList = new ArrayList<TestItem>();
try {
db.createDataBase();
PSList = db.getAllData();
} catch (IOException e) {
e.printStackTrace();
}
db.close();
fillMaps = new ArrayList<HashMap<String, String>>();
Iterator<TestItem> i = PSList.iterator();
while(i.hasNext())
{
HashMap<String, String> map = new HashMap<String, String>();
TestItem objPSItem = i.next();
map.put("name", objPSItem.NAME);
map.put("Id", objPSItem.ID);
//map.put("quantity", objPSItem.QUANTITY);
fillMaps.add(map);
}
Log.i("Size: ", ""+fillMaps.size());
//populating listview from database
ListView listView1 = (ListView) findViewById(R.id.poll_list_listView);
if (null != listView1 && null != PSList) {
listView1.setAdapter(new ListAdapter(PollStationActivity.this,
R.id.ListViewContainer, new String[fillMaps.size()]));
}
}
//class for the list and on click handler
class ListAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public ListAdapter(Context context, int textViewResourceId,
String[] objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
this.context = context;
this.values = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
// return super.getView(position, convertView, parent);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.list_layout, parent,
false);
final HashMap<String, String> map = fillMaps.get(position);
TextView textView = (TextView) rowView
.findViewById(R.id.list_label_name);
textView.setText("("+map.get("Id")+") "+map.get("name"));
rowView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
rowView.setBackgroundResource(R.drawable.list_bg_pressed);
Handler handler = new Handler();
Runnable r = new Runnable() {
public void run() {
rowView.setBackgroundResource(R.drawable.list_bg);
}
};
handler.postDelayed(r, 200);
//alert box
AlertDialog.Builder alertDialog = new AlertDialog.Builder(PollStationActivity.this);
// Setting Dialog Title
alertDialog.setTitle("Please Note!");
// Setting Dialog Message
alertDialog.setMessage("Are you sure you want to select "+"("+map.get("Id")+") "+map.get("name")+"?");
// Setting Positive "Yes" Button
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
// Write your code here to invoke YES event
// Intent intent = new Intent(RegisterFirstActivity.this, RegisterSecondActivity.class);
//
// intent.putExtra("AC_Code", map.get(TAG_CODE));
// RegisterFirstActivity.this.startActivity(intent);
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
});
return rowView;
}
}
public void makeAToast(String str) {
//yet to implement
Toast toast = Toast.makeText(this,str, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
This is the TestItem class:
public class TestItem {
public String ID;
public String NAME;
public String QUANTITY;
public boolean selected;
// Empty constructor
public TestItem(){
}
// constructor
public TestItem(String id, String name, String quantity){
this.ID = id;
this.NAME = name;
this.QUANTITY = quantity;
}
// constructor
public TestItem(String name, String quantity){
this.NAME = name;
this.QUANTITY = quantity;
}
// getting ID
public String getID(){
return this.ID;
}
// setting id
public void setID(String id){
this.ID = id;
}
// getting name
public String getName(){
return this.NAME;
}
// setting name
public void setName(String name){
this.NAME = name;
}
// getting phone number
public String getQuantity(){
return this.QUANTITY;
}
// setting quantity
public void setQuantity(String quantity){
this.QUANTITY = quantity;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
This is the activity_poll_station.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/main_bg">
<RelativeLayout
android:id="#+id/ListViewContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/poll_label_textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="28dp" >
<ListView
android:id="#+id/poll_list_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
</ListView>
</RelativeLayout>
</RelativeLayout>
This is the list_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/library_linear_layout"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:background="#drawable/list_bg"
android:padding="5dp" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="44dp"
android:background="#null" >
<TextView
android:id="#+id/list_label_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="name"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="17sp" />
<CheckBox
android:id="#+id/item_checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
<EditText
android:id="#+id/qty_editText"
android:layout_width="75dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:ems="10"
android:maxLines="1"
android:inputType="number" >
</EditText>
</RelativeLayout>
</LinearLayout>
I want to how to extract text from the edittext which I have created for every list item. If I try to extract the text on
rowView.setOnClickListener(new View.OnClickListener()
like this:
// Setting Dialog Message
alertDialog.setMessage("Are you sure you want to select "+"("+map.get("Id")+") "+map.get("name")+"Quantity: "+quantity_edit.getText().toString()+"?");
The I am getting a null pointer exception getting generated due to the rowView.setOnClickListener(new View.OnClickListener()
What should I do? What should be the work around?
Thanks in advance!
//------------------------------------------------------------------------------//
Question part: 2
Now I want to do something like, I want to remove a particular row on clicking it. The row will only be deleted from the existing listview and a new list will be shown, how to do that?
Thanks once again!
You first need to get the reference to the EditText object, which you can do by using findViewById
quantity_edit = (EditText) view.findViewById("qty_editText");
you have override getView method of custom adapter. like the following.
public class SimpleAdapter1 extends ArrayAdapter<Data> {
public SimpleAdapter1(Context context, int textViewResourceId,
List<Data> catDesc) {
super(context, textViewResourceId, catDesc);
this.items = (ArrayList<Data>) catDesc;
this.context = context;
itemsid = new ArrayList<Integer>();
System.out.println(items);
}
#Override
public View getView(final int position, View convertView,
final ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.YourLayout, null);
}
edit = (EditText) v.findViewById(R.id.editText1);
String tx = edit.getText().toString();
return v;
}
}
It will be very simple if you use custom adapter for your listview.
you can see this Custom Adapter for List View
and This one also useful for you how to get EditText value from listview
I have a custom ListView with two button and I when I click either button on any row I want to get the text label on the Listview and for now just popup a toast with it. So far nothing has worked I keep getting the last item in my array.
Here is a screen shot to give you a better idea of what i mean
Here is my Adapter subclass for my custom ListView
static final String[] Names =
new String[] { "John", "Mike", "Maria", "Miguel"};
class MyArrayAdapter extends ArrayAdapter<String> {
private final Context context;
int which;
public MyArrayAdapter(Context context, String[] pValues) {
super(context, R.layout.main, pValues);
this.context = context;
values = pValues;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.main, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.logo);
Button call = (Button) rowView.findViewById(R.id.button1);
Button chat = (Button) rowView.findViewById(R.id.button2);
textView.setText(values[position]);
// Change icon based on name
s = values[position];
which = position;
call.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String name = values[which];
Toast.makeText(CustomListView.this, name, Toast.LENGTH_SHORT).show();
}
});
return rowView;
}
}
Edit:
String name = textView.getText().toString();
RelativeLayout ll = (RelativeLayout)v.getParent();
textView = (TextView)ll.findViewById(R.id.label);
Toast.makeText(CustomListView.this, name,
Toast.LENGTH_SHORT).show();
Easy to do:
call.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout rl = (RelativeLayout)v.getParent();
TextView tv = (TextView)rl.findViewById(R.id.label);
String text = tv.getText().toString();
Toast.makeText(CustomListView.this, text, Toast.LENGTH_SHORT).show();
}
});
use setTag attribute of the View..............
as
Button call = (Button) rowView.findViewById(R.id.button1);
call.setTag(position);
and
call.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int which = -1;
Obejct obj = v.getTag();
if(obj instaceof Integer){
which = ((Integer)obj).intValue();
}
if(which >-1){
String name = values[which];
Toast.makeText(CustomListView.this, name, Toast.LENGTH_SHORT).show();
}
}
});
If you have a ListActivity, and you're not using your own adapter, you can still get the list item belonging to the tapped button, like so:
In your layout file of the list row:
<ImageButton
android:id="#+id/button_call"
android:layout_height="48dip"
android:layout_width="48dip"
android:contentDescription="Call"
android:onClick="callBuddy"
android:src="#drawable/call_button_image"
/>
In your ListActivity:
public void callBuddy(View view) {
int position = getListView().getPositionForView((View) view.getParent());
Buddy buddyToCall = (Buddy) getListView().getItemAtPosition(position);
Toast.makeText(MyListActivity.this, String.format("Calling your buddy %s.", buddyToCall.name), Toast.LENGTH_SHORT).show();
}
simply use getItem() and pass the position
Ex:getItem(position).getID()
here getID() method is getter method
Set onClick="click" to xml of button/image/etc...
and in your Activity, do:
public void click(View v) {
final int position = getListView().getPositionForView(v);
String text = getListView().getItemAtPosition(position).toString();
Toast.makeText(getApplicationContext, text, Toast.LENGTH_SHORT).show();
}
I have an activity which extends ListActivity. It has many things but amongst them it shows the articles the user has purchased with an adapter. Well I have a method that the user can delete the items from the list. The problem is when there is only one item. If I try to delete the last one the app crashes. Here is a it of my code:
public class Ventas extends ListActivity {
......
lv = getListView();
......
protected void confirmRemoval(final int arg2) {
// TODO Auto-generated method stub
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle(getResources().getString(R.string.ventas));
alertDialog.setMessage(getResources().getString(R.string.confirmacion2));
alertDialog.setButton("Si",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if(adapter2.mEvents.size()>=1){
adapter2.mEvents.remove(arg2);
} else {
//doesn't work
/*adapter2=null;
adapter2.notifyDataSetInvalidated();
lv.setVisibility(View.GONE);*/
}
}
});
alertDialog.setButton2("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
alertDialog.show();
}
here is the adapter and wrapper:
private class EventAdapter2 extends BaseAdapter {
public ArrayList<Articulo> mEvents = null;
public EventAdapter2(Context c, ArrayList<Articulo> clientes) {
mContext = c;
mEvents = clientes;
}
public int getCount() {
return mEvents.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
EventEntryView2 btv;
if (convertView == null) {
btv = new EventEntryView2(mContext, mEvents.get(position));
} else {
btv = (EventEntryView2) convertView;
String title1 = mEvents.get(position).getCantidad() + "";
if (title1 != null) {
btv.setText1Title(title1);
}
String title2 = mEvents.get(position).getDescripcion();
if (title2 != null) {
btv.setText2Title(title2);
}
String title3 = mEvents.get(position).getpVenta() + "0";
if (title3 != null) {
btv.setText3Title(title3);
}
String title4 = (mEvents.get(position).getCantidad() * mEvents
.get(position).getpVenta()) + "0";
if (title4 != null) {
btv.setText4Title(title4);
}
}
return btv;
}
private Context mContext;
}
private class EventEntryView2 extends LinearLayout {
private TextView text1;
private TextView text2;
private TextView text3;
private TextView text4;
private View inflatedView;
public EventEntryView2(Context context, Articulo resp) {
super(context);
this.setOrientation(VERTICAL);
inflatedView = View.inflate(context, R.layout.results, null);
text1 = (TextView) inflatedView.findViewById(R.id.textView1);
text2 = (TextView) inflatedView.findViewById(R.id.textView2);
text3 = (TextView) inflatedView.findViewById(R.id.textView3);
text4 = (TextView) inflatedView.findViewById(R.id.textView4);
String t = resp.getCantidad() + "";
text1.setText(t);
String t1 = resp.getDescripcion();
text2.setText(t1);
String t2 = resp.getpVenta() + "0";
text3.setText(t2);
String t3 = (resp.getCantidad() * resp.getpVenta()) + "0";
text4.setText(t3);
addView(inflatedView, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
public void setText4Title(String title4) {
text4.setText(title4);
}
public void setText3Title(String title3) {
text3.setText(title3);
}
public void setText2Title(String title2) {
text2.setText(title2);
}
public void setText1Title(String title1) {
text1.setText(title1);
}
}
as you can see when I have only one item left I have tried to set adapter to null or adapter.notifyDataSetInvaliadted or even making the listview invisible, nothing works. What happens is when I click ok nothing changes then when I click a second time it all crashes
What I would like is the listView to disappear when the adapter is empty but I am now out of ideas, is it even possible?
Any ideas?
EDIT:
Thank you all for the answers but the problem was I was modifying the list from inside an inner anonymous class. It is actually pretty simple, create a method and call it from inside the dialog, once the array is empty the list disappears automatically:
protected void removeFromList(int arg2) {
adapter2.mEvents.remove(arg2);
adapter2.notifyDataSetChanged();
}
remove item from the arraylist which you add into the adapter and then call this method.
youradapter.notifyDataSetChanged();
and whatever you do for single item that was
adapter2 = null;
adapter2.notifyDataSetInavlidated();
this will obviously crash it because adapter2 object was null so how null object notify its data
Try calling lv.invalidate() after the remove() and see whether that makes any difference.
You should check in your adapter class if it is null then you should not fetch value from it......that's the main reason why you are getting exception as you are fetching the value from null variable.Put check there.
For setVisibility to Work:
You create your main.xml
Add to it a ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/sherif.android.deedz"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/myListView"
android:divider="#ffa500" android:dividerHeight="1px"
android:background="#drawable/somedrawable_xml"
android:choiceMode="singleChoice"></ListView>
</ListView>
Now you can make it GONE
If you want the whole details of this :
Check my answer
I have ONE annoying problem with SimpleCursorAdapter. My programm has list view and ListActivity. Each row has it's own layout:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:orientation="horizontal" android:weightSum="1.0">
<TableRow>
<TextView android:id="#+id/task_time"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textSize="24sp" android:text="Time">
</TextView>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent">
<TextView android:id="#+id/task_name"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textSize="20sp" android:text="Name">
</TextView>
<TextView android:id="#+id/task_categoty"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Category" android:textSize="12sp">
</TextView>
</LinearLayout>
<TextView android:id="#+id/task_state"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="State" android:textSize="12sp">
</TextView>
<CheckBox android:id="#+id/task_enabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:focusable="false">
</CheckBox>
</TableRow>
Tasks are stored in SQLite database. I have DAO object (singleton) to access the database.
TaskDao:
public void updateEnabled(int id, boolean enabled){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(ENABLED_COLUMN, enabled==true?1:0);
Log.i(TAG, "update to " + cv.get(ENABLED_COLUMN) );
try{
db.beginTransaction();
db.update(TASK_TABLE, cv, ID_COLUMN+"=?", new String[]{id+""});
db.setTransactionSuccessful();
} catch (SQLException e) {
Log.i(TAG, "edit task failed!");
} finally {
db.endTransaction();
if (db != null)
db.close();
}
}
and the Cursor method for ListActivity:
public Cursor getTasks(){
SQLiteDatabase db = dbHelper.getReadableDatabase();
return db.query(TASK_TABLE, COLUMNS, null, null, null, null, NAME_COLUMN);
}
I extended SimpleCursorAdapter (TaskDbAdapter) like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
convertView = inflater.inflate(R.layout.task_list_row, null);
}
Cursor c = getCursor();
c.moveToPosition(position);
Log.i(TAG, "getView " + position + " = " + c.getInt(enabledIdx));
enabled.setTag(c.getInt(c.getColumnIndex(BaseColumns._ID)));
enabled.setChecked(c.getInt(enabledIdx)>0?true:false);
enabled.setOnClickListener(this);
return convertView;
}
#Override
public void onClick(View v) {
CheckBox box = (CheckBox) v;
Integer id = (Integer)box.getTag();
TaskDao.getInstance(context).updateEnabled(id.intValue(), box.isChecked());
}
And at last I use all the above stuff in my main ListActivity
private void refreshList(){
c = TaskDao.getInstance(this).getTasks();
startManagingCursor(c);
adapter = new TaskDbAdapter(this, R.layout.task_list_row, c, new String[]{TaskDao.ENABLED_COLUMN}, new int[]{R.id.task_enabled});
setListAdapter(adapter);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task);
getListView().setItemsCanFocus(false);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
getListView().setVerticalScrollBarEnabled(true);
registerForContextMenu(getListView());
getListView().setOnCreateContextMenuListener(this);
refreshList();
}
#Override
protected void onResume() {
super.onResume();
refreshList();
}
#Override
protected void onPause() {
super.onPause();
}
Everything works fine. But CheckBoxes loose their states. For instance I check my first column and scroll the list down. In my trace before press I have:
getView 0 = 0
getView 2 = 0
getView 3 = 0
then
uptate to 1
and then (when I scroll up to the first element)
getView 0 = 0
getView 2 = 0
getView 3 = 0
I tried to make getCursor().requery(); in my TaskDbAdapter onClick method. But then I saw no items in the list! And exception because of cursor management(connection was closed by android). When I write startManagingCursor(c); in refreshList() method then check and uncheck methods don't work.
Please, Help!
I didn't read all your source so my suggestion may be totally wrong, but I will give a try.
Take a look at the documentation of BaseAdapter class.
public void notifyDataSetChanged ()
may do the work.
You also can register Observer for this...
public void registerDataSetObserver (DataSetObserver observer)
I struggled with this as well. I ended up storing all checked boxes in the db as either 0 or 1. Then I check their state from the database to determine if they are marked or not.
public class DetailCursorAdapter extends SimpleCursorAdapter {
private Cursor c;
private Context context;
public DetailCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.check_list, null);
}
Log.i("pos = ..................", "pos = "+pos);
this.c.moveToPosition(pos);
//this.c.moveToPosition(this.c.getInt(this.c.getColumnIndex("_id")));
CheckBox cBox = (CheckBox) v.findViewById(R.id.bcheck);
cBox.setTag(this.c.getInt(this.c.getColumnIndex("_id")));
/*
* when reloading the list, check for chkd status, this is broken. Need to query db directly.
*/
EventDbAdapter mDbHelper = new EventDbAdapter(context);
mDbHelper.open();
int idTag = (Integer) cBox.getTag();
int checked = mDbHelper.selectChk(idTag);
mDbHelper.close();
Log.i("results from selectChk.....................", ""+checked);
if (checked == 1) {
cBox.setChecked(true);
} else {
cBox.setChecked(false);
}
/*
* Populate the list
*/
TextView txtdateTime = (TextView)v.findViewById(R.id.time);
txtdateTime.setText(this.c.getString(this.c.getColumnIndex("time")));
TextView txtdateEvent = (TextView)v.findViewById(R.id.event);
txtdateEvent.setText(this.c.getString(this.c.getColumnIndex("event")));
TextView txtdateLocation = (TextView)v.findViewById(R.id.location);
txtdateLocation.setText(this.c.getString(this.c.getColumnIndex("location")));
ImageView arrow = (ImageView) v.findViewById(R.id.arrowId);
arrow.setImageResource(R.drawable.rightarrow);
Log.i("if chk in db is = 1 then set checked.........",this.c.getString(this.c.getColumnIndex("checked")) +" " +this.c.getString(this.c.getColumnIndex("time")));
/*
* Controls action based on clicked list item (background)
*/
View lv = v.getRootView();
lv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View lv) {
CheckBox cBox = (CheckBox) lv.findViewById(R.id.bcheck);
// id holds the rowid of each event. pass this to a new activity to query for description
// Call Event Detail
String id = cBox.getTag().toString();
Intent i = new Intent(context, EventDetail.class);
//i.putExtra("description", c.getString(c.getColumnIndex("description")));
i.putExtra("_id", id);
context.startActivity(i);
}
});
/*
* Begin - Controls action based on clicked Text only
txtdateEvent.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
CharSequence charseq = "Darth Vader is alive";
Toast.makeText(context, charseq, Toast.LENGTH_SHORT).show();
}
});
* End - Controls action based on clicked Text only
*/
/*
* Controls action based on clicked checkbox
*/
cBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
EventDbAdapter mDbHelper = new EventDbAdapter(context);
mDbHelper.open();
CheckBox cBox = (CheckBox) v.findViewById(R.id.bcheck);
if (cBox.isChecked()) {
//cBox.setChecked(false);
CharSequence charseq = "Added to My Schedule";
Toast.makeText(context, charseq, Toast.LENGTH_SHORT).show();
// Update the database for each checked item
mDbHelper.updateChecked(cBox.getTag().toString(), "1");
c.requery();
// Verify that the db was updated for debugging purposes
String event = c.getString(c.getColumnIndex("event"));
int id = (Integer) cBox.getTag();
Log.i("checked _id...........", "id= " + id + " " +c.getString(c.getColumnIndex("_id")));
Log.i("checked checked...........", ""+c.getString(c.getColumnIndex("checked")));
} else if (!cBox.isChecked()) {
//cBox.setChecked(true);
CharSequence charseq = "Removed from My Schedule";
Toast.makeText(context, charseq, Toast.LENGTH_SHORT).show();
// checkList.remove(cBox.getTag());
//checkList.add((Integer) cBox.getTag());
String event = c.getString(c.getColumnIndex("event"));
//int id = c.getInt(c.getColumnIndex("_id"));
int id = (Integer) cBox.getTag();
mDbHelper.updateChecked(cBox.getTag().toString(), "0");
c.requery();
//int sqlresult = mDbHelper.selectChk(id, event);
//Log.i("sqlresult checked value after update...........", ""+ sqlresult);
//Log.i("unchecked _id...........", ""+c.getString(c.getColumnIndex("_id")));
//Log.i("unchecked checked...........", ""+c.getString(c.getColumnIndex("checked")));
}
//mDbHelper.close();
}
});
return(v);
}
}