I have got a listview which uses a special adapter to pass data into the listview from the database.But the problem is that I am only getting one listview item being repeated and the other details are not being displayed. When I put breakpoints and debug the project, all the details are being passed to the hashmap, but the listview is only showing one particular item repeatedly. The code is shown below:
static class ViewHolder {
TextView txtmername,txtmerid,txtmeradd,txtmermeasure;
Button btnselect;
}
private LayoutInflater mInflater;
public SpecialAdapter(Context ctx,List<HashMap<String, String>> listData, int resourceId, String[] columnTags, int[] columnIds) {
super(ctx, listData, resourceId, columnTags, columnIds);
ctx=MerchantList.this;
listData=listData;
resourceId=R.layout.merchant_listview;
columnTags=columnTags;
columnIds=columnIds;
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return super.getItem(position);
}
#Override
public long getItemId(int position) {
return super.getItemId(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
Context con=getApplicationContext();
if(convertView==null)
// convertView = getActivity().getLayoutInflater().inflate(R.layout.stores_listview_layout, pa
mInflater = (LayoutInflater)con.getSystemService(con.LAYOUT_INFLATER_SERVICE);
convertView=mInflater.inflate(R.layout.merchantlistview, null);
holder = new ViewHolder();
holder.txtmername = (TextView) convertView.findViewById(R.id.lblMerchantName);
holder.txtmeradd=(TextView)convertView.findViewById(R.id.lblAddress);
holder.txtmerid=(TextView)convertView.findViewById(R.id.lblMerchantId);
holder.txtmermeasure=(TextView)convertView.findViewById(R.id.lblMeasure);
holder.btnselect=(Button)convertView.findViewById(R.id.btnSelect);
holder.btnselect.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
});
convertView.setTag(holder);
if(convertView !=null)
{
holder=(ViewHolder)convertView.getTag();
// Binding the data efficiently with the holder
SQLiteDatabase db=openOrCreateDatabase("NEW.db", MODE_PRIVATE, null);
Cursor OrderCursor = db.rawQuery("SELECT DISTINCT(A.ID), B.NAME, B.ADDRESS, A.MEASURE FROM (SELECT ID, MIN( CAST(STOCK_IN_HAND AS REAL) /REORDER_LEVEL) AS MEASURE FROM INVENTORY GROUP BY ID) A INNER JOIN MASTER B ON A.ID=B.ID ORDER BY A.MEASURE", null);
listData.clear();
if(OrderCursor!= null)
{
if(OrderCursor.moveToFirst()){
for (int i = 0; i < OrderCursor.getCount(); i++){
// String first,second,third,fourth=null;
HashMap<String,String> map = new HashMap<String, String>();
map.put(columnTags[0], OrderCursor.getString(OrderCursor.getColumnIndex("NAME")));
map.put(columnTags[1], OrderCursor.getString(OrderCursor.getColumnIndex("ADDRESS")));
map.put(columnTags[2], OrderCursor.getString(OrderCursor.getColumnIndex("ID")));
map.put(columnTags[3], OrderCursor.getString(OrderCursor.getColumnIndex("MEASURE")));
listData.add(map);
String measure = map.get("measure").toString();
String name=map.get("Name").toString();
String address=map.get("Address").toString();
String id=map.get("Id").toString();
holder.txtmerchantname.setText(name);
holder.txtmeradd.setText(address);
holder.txtmerid.setText(id);
holder.txtmermeasure.setText(measure);
double measure1=Double.parseDouble(measure);
if(measure1 > 1.5)
{
convertView.setBackgroundColor(getResources().getColor(R.color.Green));
}
else if((1.5 >= measure1 ) && (measure1>1.0))
{
convertView.setBackgroundColor(getResources().getColor(R.color.Yellow));
}
else if(1.0>=measure1)
{
convertView.setBackgroundColor(Color.RED);
}
OrderCursor.moveToNext();
}//end of for
}
OrderCursor.close();
db.close();
}
}
return convertView;
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#Override
public int getViewTypeCount() {
return super.getViewTypeCount();
}
}
Try using the following code which i guess will be helpful. Hence you are using the hashmap the arrayAdapter can be used.
https://stackoverflow.com/a/15061779/2106338
getViewTypeCount() is not matched with your listView items count therefore it adds up another item.
In your case I think its about the measure condition you are using.
In the end you should use else instead of else if
OR
if there is another condition, you must treat it.
Related
Im new in realm db. I completed add and get data in realm db. But, I couldn't sort(ascending and descending).Im my code it display items in listview. Listview contains 5 list and each list contains 4 field(name, age, skill and date). if I sort(ascending) name, need to ascending in 5 list.My code is not work
I post my code here,
private void Ascending_order() {
realm.beginTransaction();
RealmResults<Employee> result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
realm.copyFromRealm(result);
realm.commitTransaction();
employeedetailadapter.notifyDataSetChanged();
}
Adapter class:
public class EmployeeDetailAdapter extends BaseAdapter {
private ArrayList<Employee>employeeDetaillists = new ArrayList<>();
private Context c;
private LayoutInflater inflater;
private OnItemClick mCallback;
private SimpleDateFormat df = new SimpleDateFormat("dd/mm/yyyy");
public EmployeeDetailAdapter(Context c,ArrayList<Employee> employeeDetaillists, OnItemClick listener) {
this.employeeDetaillists = employeeDetaillists;
this.c= c;
inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mCallback = listener;
}
#Override
public int getCount() {
return employeeDetaillists.size();
}
#Override
public Object getItem(int position) {
return employeeDetaillists.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
Holder holder;
if (v==null){
v= (View) inflater.inflate(R.layout.list_single_item,null);
holder = new Holder();
holder.tvPersonName = (TextView) v.findViewById(R.id.tvPersonName);
holder.tvPersonAge = (TextView) v.findViewById(R.id.tvPersonAge);
holder.tvPersonSkill = (TextView) v.findViewById(R.id.tvPersonSkill);
holder.ivEditPesonDetail=(ImageView)v.findViewById(R.id.ivEditPesonDetail);
holder.tvPersondate=(TextView)v.findViewById(R.id.tvPersondate);
holder.ivDeletePerson=(ImageView)v.findViewById(R.id.ivDeletePerson);
v.setTag(holder);
}else{
holder = (Holder) v.getTag();
}
holder.tvPersonName.setText(employeeDetaillists.get(position).getName());
holder.tvPersonAge.setText(employeeDetaillists.get(position).getAge());
holder.tvPersonSkill.setText(employeeDetaillists.get(position).getSkill());
String strDate = df.format(employeeDetaillists.get(position).getSdate());
holder.tvPersondate.setText(strDate);
holder.ivDeletePerson.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Delete(employeeDetaillists.get(position).getName(),position);
}
});
return v;
}
private void Delete(String name, int position) {
mCallback.onClickdelete(name, position);
}
public void updateData(RealmResults<Employee> result) {
}
class Holder {
TextView tvPersonName, tvPersonAge, tvPersonSkill,tvPersondate;
ImageView ivDeletePerson, ivEditPesonDetail;
}
}
Your code does't change db. You just get sorted items but don't use them.
realm.copyFromRealm(result); // this line does nothing
realm.commitTransaction(); // this one too, because you change nothing
employeedetailadapter.notifyDataSetChanged(); // you data is the same, so this line also useless here
To see your data sorted you should use RealmResults in your adapter. With this approach your list always will sorted, even after adding new items. But note: your adapter should extends RealmRecyclerViewAdapter.
You should run this code before creating adapter and use result inside adapter:
RealmResults<Employee> result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
Also you can try manually update data of your adapter.
private void Ascending_order() {
RealmResults<Employee> result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
employeedetailadapter.updateData(result); // update data inside adapter before calling `notifyDataSetChanged`
employeedetailadapter.notifyDataSetChanged();
}
You need to create updateData method yourself:
public void updateData(RealmResults<Employee> result) {
employeeDetaillists = new ArrayList<Employee>(result);
}
First of all, while getting data from Realm you don't need to write it in Transaction. Write Transaction is required only when you are adding data in realm or updating any realm object.
And about your problem, To get sorted data from realm, You can do it like this
RealmResults<Employee> result = realm.where(Employee.class).sort("name", Sort.ASCENDING).findAll();
Now the data you got is sorted, If you still see wrong order in your ListView then there could be some issue in your Adapter. If you share your adapter code, then I can help further :)
Updated:
Adapter Class
public class EmployeeDetailAdapter extends BaseAdapter {
private RealmResults<Employee> employeeDetaillists;
private Context c;
private LayoutInflater inflater;
private OnItemClick mCallback;
private SimpleDateFormat df = new SimpleDateFormat("dd/mm/yyyy");
public EmployeeDetailAdapter(Context c,RealmResults<Employee> employeeDetaillists, OnItemClick listener) {
this.employeeDetaillists = employeeDetaillists;
this.c= c;
inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mCallback = listener;
}
#Override
public int getCount() {
return employeeDetaillists.size();
}
#Override
public Object getItem(int position) {
return employeeDetaillists.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
Holder holder;
if (v==null){
v= (View) inflater.inflate(R.layout.list_single_item,null);
holder = new Holder();
holder.tvPersonName = (TextView) v.findViewById(R.id.tvPersonName);
holder.tvPersonAge = (TextView) v.findViewById(R.id.tvPersonAge);
holder.tvPersonSkill = (TextView) v.findViewById(R.id.tvPersonSkill);
holder.ivEditPesonDetail=(ImageView)v.findViewById(R.id.ivEditPesonDetail);
holder.tvPersondate=(TextView)v.findViewById(R.id.tvPersondate);
holder.ivDeletePerson=(ImageView)v.findViewById(R.id.ivDeletePerson);
v.setTag(holder);
}else{
holder = (Holder) v.getTag();
}
holder.tvPersonName.setText(employeeDetaillists.get(position).getName());
holder.tvPersonAge.setText(employeeDetaillists.get(position).getAge());
holder.tvPersonSkill.setText(employeeDetaillists.get(position).getSkill());
String strDate = df.format(employeeDetaillists.get(position).getSdate());
holder.tvPersondate.setText(strDate);
holder.ivDeletePerson.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Delete(employeeDetaillists.get(position).getName(),position);
}
});
return v;
}
private void Delete(String name, int position) {
mCallback.onClickdelete(name, position);
}
public void updateData(RealmResults<Employee> result) {
}
class Holder {
TextView tvPersonName, tvPersonAge, tvPersonSkill,tvPersondate;
ImageView ivDeletePerson, ivEditPesonDetail;
}
}
In your Activity please change following function
private void Ascending_order() {
result = realm.where(Employee.class)
.sort("name", Sort.ASCENDING).findAll();
employeedetailadapter.notifyDataSetChanged();
}
"result" list should be declared on class level and should be passed to Adapter's constructor as well.
Like
class Activity {
RealmResults<Employee> result;
EmployeeDetailAdapter employeedetailadapter;
//// Other Code
public onCreate(Bundle b) {
result = realm.where(Employee.class).findAll();
employeedetailadapter = new EmployeeDetailAdapter(this, result, listener);
// Other code
}
}
I would like to ask some question about AdapterView.
In my application, there is an activity which retrieve data from database and display them in AdapterView.
However, when i install the application in different devices, I found that the part I have just mentioned could only function on some devices. The others cannot show the database results.
Here is my code:
private void showResults(String query) {
Cursor cursor = searchCustByInputText(query);
if (cursor == null) {
//
} else {
// Specify the columns we want to display in the result
String[] from = new String[] {
"cust_code",
"chinese_name"};
// Specify the Corresponding layout elements where we want the columns to go
int[] to = new int[] {
R.id.scust_code,
R.id.schinese_name};
// Create a simple cursor adapter for the definitions and apply them to the ListView
SimpleCursorAdapter customers = new SimpleCursorAdapter(this,R.layout.cust_list_item, cursor, from, to);
mListView.setAdapter(customers);
// Define the on-click listener for the list items
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor c = (Cursor) mListView.getItemAtPosition(position);
String cust_code = c.getString(c.getColumnIndex("cust_code"));
if (callFromAct.equals("Main")) {
String pay_term = c.getString(c.getColumnIndex("pay_term"));
String chinese_name = c.getString(c.getColumnIndex("chinese_name"));
String english_name = c.getString(c.getColumnIndex("english_name"));
String address_1 = c.getString(c.getColumnIndex("address_1"));
String address_2 = c.getString(c.getColumnIndex("address_2"));
String address_3 = c.getString(c.getColumnIndex("address_3"));
String address_4 = c.getString(c.getColumnIndex("address_4"));
String contact = c.getString(c.getColumnIndex("contact"));
String telephone = c.getString(c.getColumnIndex("telephone"));
String last_order_date = c.getString(c.getColumnIndex("last_order_date"));
//Pass data to another Activity
Intent it = new Intent(CustEnqActivity.this, CustEnqDetailsActivity.class);
Bundle bundle = new Bundle();
bundle.putString("cust_code", cust_code);
bundle.putString("pay_term", pay_term);
bundle.putString("chinese_name", chinese_name);
bundle.putString("english_name", english_name);
bundle.putString("address_1", address_1);
bundle.putString("address_2", address_2);
bundle.putString("address_3", address_3);
bundle.putString("address_4", address_4);
bundle.putString("contact", contact);
bundle.putString("telephone", telephone);
bundle.putString("last_order_date", last_order_date);
it.putExtras(bundle);
startActivity(it);
}
else {
returnToCallingAct(cust_code);
}
//searchView.setQuery("",true);
}
});
}
}
Besides, I discovered there were two warnings in my logcat.
The constructor SimpleCursorAdapter(Context, int, Cursor, String[], int[]) is deprecated
AdapterView is a raw type. References to generic type AdapterView should be parameterized
Are they related to the problem?
Try to create a class that extends BaseAdapter and use ViewHolders for performance
eg:
public class MyBaseAdapter extends BaseAdapter {
ArrayList<ListData> myList = new ArrayList<ListData>();
LayoutInflater inflater;
Context context;
public MyBaseAdapter(Context context, ArrayList<ListData> myList) {
this.myList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context); // only context can also be used
}
#Override
public int getCount() {
return myList.size();
}
#Override
public ListData getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.layout_list_item, null);
mViewHolder = new MyViewHolder();
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
mViewHolder.tvTitle = detail(convertView, R.id.tvTitle, myList.get(position).getTitle());
mViewHolder.tvDesc = detail(convertView, R.id.tvDesc, myList.get(position).getDescription());
mViewHolder.ivIcon = detail(convertView, R.id.ivIcon, myList.get(position).getImgResId());
return convertView;
}
// or you can try better way
private TextView detail(View v, int resId, String text) {
TextView tv = (TextView) v.findViewById(resId);
tv.setText(text);
return tv;
}
private ImageView detail(View v, int resId, int icon) {
ImageView iv = (ImageView) v.findViewById(resId);
iv.setImageResource(icon); //
return iv;
}
private class MyViewHolder {
TextView tvTitle, tvDesc;
ImageView ivIcon;
}
}
More info/example:
http://www.pcsalt.com/android/listview-using-baseadapter-android/#sthash.lNGSCiyB.dpbs
I got a list, that i would like to show in a ListView, using my own custom adapter. So this list have some null values in it, and also some "important" not-null values.
It could be like this:
(N representing Null)
(D representint some valuable data)
myList:
[N,N,D,D,N,N,D,N,D,N,N] for example.
So i got my adapter, but i cannot handle the null values in the list.
This is my adapter:
public class ItemAdapter extends ArrayAdapter {
List<Item> itemList;
private Activity act;
boolean selling;
public ItemAdapter(Activity act, List<Item> itemList, boolean selling) {
super(act, R.layout.item_view_layout, itemList);
this.itemList = itemList;
this.act = act;
this.selling = selling;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final Item itemManipulated = itemList.get(position);
if (convertView == null) {
convertView = new ItemInShopView(act, itemManipulated);
holder = new ViewHolder();
holder.convertView = convertView;
holder.itemNameTextView = (TextView) ((ItemView) convertView).getItemNameTextView();
holder.iconImageView = (ImageView) ((ItemView) convertView).getItemIconImageView();
holder.coinView = (CoinView) ((ItemInShopView) convertView).getCoinView();
holder.coinView.init(act);
holder.itemRarityHidedTextView = (TextView) ((ItemView) convertView).getItemRarityHidedTextView();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.itemNameTextView.setText(itemManipulated.getName());
holder.iconImageView.setImageResource(itemManipulated.getIcon());
holder.itemRarityHidedTextView.setText(itemManipulated.getRarity());
Colorer.setTextViewColorByItemRarity(holder.itemNameTextView, holder.getRarity(), act);
if (selling) {
holder.coinView.setCoins(itemManipulated.getSellPrice());
} else {
holder.coinView.setCoins(itemManipulated.getPrice());
}
holder.convertView.setOnClickListener(new OnClickListenerWithPreventDoubleTapper(itemManipulated));
holder.convertView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return false;
}
});
return convertView;
}
class OnClickListenerWithPreventDoubleTapper extends OnClickListenerWithPreventDoubleTap {
Item item;
public OnClickListenerWithPreventDoubleTapper(Item item) {
this.item = item;
}
#Override
protected void performAction() {
new ItemDialog(act, item).show();
}
}
static class ViewHolder {
TextView itemRarityHidedTextView;
TextView itemNameTextView;
ImageView iconImageView;
CoinView coinView;
View convertView;
public String getRarity() {
return itemRarityHidedTextView.getText().toString();
}
}
}
How could i implement some way to get the adapter handle null values and shows nothing there, or maybe show a dummy layout with nothing on it?
I couldnt make a new list without null values and pass these new list to the adapter, because the nulls have an important meaning in an other view.
I hope my problem is clear. Please help if you can.
Why not just?
if (itemManipulated != null){
holder.itemNameTextView.setText(itemManipulated.getName());
holder.iconImageView.setImageResource(itemManipulated.getIcon());
holder.itemRarityHidedTextView.setText(itemManipulated.getRarity());
Colorer.setTextViewColorByItemRarity(holder.itemNameTextView, holder.getRarity(),act);
if (selling) {
holder.coinView.setCoins(itemManipulated.getSellPrice());
} else {
holder.coinView.setCoins(itemManipulated.getPrice());
}
} else {
holder.itemNameTextView.setText("No Item");
... (whatever default values you like)
}
Edit:
If you don't want to display nulls at all you will need to do something more complex.
in getView: find the nth piece of actual data
in getCount: return the number of pieces of actual data
getView:
int posInArray = -1;
for (int i =0; i <= position; i++){
posInArray++;
while(itemList.get(posInArray) == null){
posInArray++;
}
}
itemManipulated = itemList.get(posInArray);
...
getCount:
int count = 0;
for(int i = 0; i < itemList.size(); i++){
if (itemList.get(i) != null){
count++;
}
}
return count;
I am using SQLiteDatabase in android. I am not able to refersh my listview after deleting a row.
My code is as follows:
public void delete(String i) {
// TODO Auto-generated method stub
String [] columns= new String[]{KEY_ROW_ID,KEY_FHR,KEY_ID,KEY_NAME,KEY_AGE};
Cursor c= our_db.query(KEY_TABLE, columns, null, null,null, null, null);
our_db.delete(KEY_TABLE, KEY_NAME+ "="+"\'"+i+"\'", null) ;
c.requery();
}
I call it from a viewholder in efficientadapter. Below is the code where I call it:
holder.del.setOnClickListener(new OnClickListener() {
private int pos=position;
public void onClick(View v) {
// TODO Auto-generated method stub
final long newpos;
sql_get db = new sql_get(c);
db.open();
db.delete(DATA[pos]);
notifyDataSetChanged();
db.close();
}
});
Can anyone help me finding out the problem. It doesn't give any error. it just deleted the row but doesn't update the view.
Here is the adapter i used:
private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Bitmap mIcon1;
private Bitmap mIcon2;
private Bitmap mIcon3;
private Bitmap mIcon4;
Context c;
int window;
public EfficientAdapter(Context context) {
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
this.c=context;
// Icons bound to the rows.
mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_1);
mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_2);
mIcon3 = BitmapFactory.decodeResource(context.getResources(), R.drawable.del1);
mIcon4 = BitmapFactory.decodeResource(context.getResources(), R.drawable.edit);
}
public int getCount() {
return DATA.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
//int i=0;
convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.del=(ImageView)convertView.findViewById(R.id.icon1);
holder.edit=(ImageView)convertView.findViewById(R.id.icon2);
window=position;
holder.text.setOnClickListener(new OnClickListener() {
private int pos=position;
//private int pos = position;
public void onClick(View v) {
System.out.println(window);
sql_get db = new sql_get(c);
db.open();
String ret_id= db.getid(DATA[pos]);
String ret_name = db.getname(DATA[pos]);
String ret_age= db.getage(DATA[pos]);
String ret_fhr= db.getfhr(DATA[pos]);
String[] result = {ret_id,ret_name,ret_age,ret_fhr};
db.close();
Bundle b=new Bundle();
b.putStringArray("key",result);
Intent i =new Intent(c,Tabs.class);
i.putExtras(b);
c.startActivity(i) ;
Toast.makeText(c, getItemId(position)+""+" Click- text " +pos+" "+ret_name, Toast.LENGTH_SHORT).show();
}
});
holder.del.setOnClickListener(new OnClickListener() {
private int pos=position;
public void onClick(View v) {
// TODO Auto-generated method stub
final long newpos;
sql_get db = new sql_get(c);
db.open();
db.delete(DATA[pos]);
notifyDataSetChanged();
db.close();
Toast.makeText(c, "deleting " + DATA[pos], Toast.LENGTH_SHORT).show();
}
});
convertView.setTag(holder);
}
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
holder.del.setImageBitmap(mIcon3);
holder.edit.setImageBitmap(mIcon4);
return convertView;
static class ViewHolder {
ImageView del;
TextView text;
ImageView icon;
ImageView edit;
}
}
You need to delete the row also from the object holding the data for the list view..
I think you also have to remove the same data from adapter and then use your_adapter.notifyDataSetChanged() method. That worked for me...
I found the solution. As said above, I had to change the DATA object.
I used the following commands to achieve it.
db.open();
db.delete(DATA[pos]);
DATA=db.getdata();
DATA_NAME=db.getname();
DATA_AGE=db.getage();
DATA_FHR=db.getfhr();
db.close();
I know there are lots of questions related to Custom ListView with CheckBox but still i am getting some problem in retrieving all checked items.
What i am doing is :
Displaying Custom ListView from Database (List of All Sent SMSs).
Allow user to check various list items.
When user presses the Delete Button i want to delete all the checked items (From the database as well as the view portion)
Problem :
When i go to my Activity for the first time and check some items, and delete it, it works fine.
But when i again check some items just after pressing delete button, some items gets checked and some gets unchecked and again some other items are deleted..
I think i am not able to bind id and list item perfectly..
Coding done so far:
row.xml contains
ImageView
TextView
TextView
TextView
CheckBox
In my Activity Class :
Uri uriSms = Uri.parse("content://sms/sent");
Cursor cursor = context.getContentResolver().query(uriSms, null,null,null,null);
String[] from={"address","body"};
int[] to={R.id.contactName,R.id.msgLine};
ssa=new SentSmsAdapter(context,R.layout.inbox_list_item,cursor,from,to,2);
smsList.setAdapter(ssa);
deleteSms.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ArrayList<Boolean> list=SentSmsAdapter.itemChecked;
Uri path=Uri.parse("content://sms/");
for(int i=0;i<list.size();i++)
{
if(list.get(i))
getContentResolver().delete(path,"_id="+ssa.getItemId(i),null);
}
ssa.notifyDataSetChanged();
}
I have custom SimpleCursorAdapter.
public class SentSmsAdapter extends SimpleCursorAdapter{
Cursor dataCursor;
LayoutInflater mInflater;
Context context;
int layoutType;
ArrayList<String> arrayList;
public static HashMap<String,Long> myList=new HashMap<String,Long>();
public static ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
public static ArrayList<Long> itemIds=new ArrayList<Long>();
public SentSmsAdapter(Context context, int layout, Cursor dataCursor, String[] from,
int[] to,int type) {
super(context, layout, dataCursor, from, to);
layoutType=type;
this.context=context;
this.dataCursor = dataCursor;
mInflater = LayoutInflater.from(context);
arrayList=new ArrayList<String>();
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false);
}
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView==null)
{
convertView = mInflater.inflate(R.layout.inbox_list_item, null);
holder = new ViewHolder();
holder.checkBox=(CheckBox) convertView.findViewById(R.id.checkMsg);
holder.checkBox.setTag(position);
holder.cName=(TextView)convertView.findViewById(R.id.contactName);
holder.icon=(ImageView)convertView.findViewById(R.id.msgImage);
holder.msg=(TextView)convertView.findViewById(R.id.msgLine);
holder.time=(TextView)convertView.findViewById(R.id.msgTime);
convertView.setTag(holder);
holder.checkBox.setTag(itemChecked.get(position));
}
else
{
holder=(ViewHolder)convertView.getTag();
}
holder.checkBox.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) view.findViewById(R.id.checkMsg);
int pos=Integer.parseInt(holder.checkBox.getTag());
itemChecked.set(position, cb.isChecked());
/*if (cb.isChecked()) {
itemChecked.set(position, true);
Log.i("WhenChecked",Boolean.toString(itemChecked.get(position)));
// do some operations here
}
else if (!cb.isChecked()) {
itemChecked.set(position, false);
Log.i("WhenNotChecked",Boolean.toString(itemChecked.get(position)));
// do some operations here
}
*/
}
});
dataCursor.moveToPosition(position);
String id=Integer.toString(dataCursor.getInt(dataCursor.getColumnIndexOrThrow("_id")));
itemIds.add(Long.parseLong(id));
String msgText=dataCursor.getString(dataCursor.getColumnIndexOrThrow("body"));
holder.msg.setText(msgText);
Long time=dataCursor.getLong(dataCursor.getColumnIndexOrThrow("date"));
holder.time.setText(Long.toString(time));
String address=dataCursor.getString(dataCursor.getColumnIndexOrThrow("address"));
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
Cursor cs= context.getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},null,null,null);
if(cs.getCount()>0)
address=cs.getString(cs.getColumnIndex(PhoneLookup.DISPLAY_NAME));
cs.close();
holder.cName.setText(address);
if(layoutType==1)holder.checkBox.setVisibility(View.GONE);
else
{
holder.checkBox.setVisibility(View.VISIBLE);
}
arrayList.add(id+","+address+","+msgText+","+Long.toString(time));
return convertView;
}
static class ViewHolder
{
ImageView icon;
CheckBox checkBox;
TextView cName;
TextView msg;
TextView time;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return itemIds.get(position);
}
}
Try something like this.
add this code in getView()
holder.checkBox.seTag(position);
holder.checkBox.setOnCheckedChangedListener(this);
implement this outside getView().
public void onCheckedChanged(CompoundButton view,boolean isChecked) {
if(isChecked)
{
itemChecked.add(view.getTag());
}
else
{
if(itemChecked.cantains(view.getTag()))
//remove from itemChecked.
}
}
When deleting delete all the elements from the list whose index is available in itemChecked.
Thanks and N-JOY.
If you use threads when checking, uncheking and deleting your items, they will work properly.