I have an application in which there is a listview that displays values and when a row is pressed, the third value of the row will display a value.
Example is: third value is 30 and when it's pressed, it should be
divided by 6, so the answer should be 5.
But when I scroll and press a row in listview example: I pressed row1, there will be a duplicate checked row in row10 and the value of the third row returns to it's old value (30) for example.
Is there any way to keep the checkbox from duplicating and the value of the row preserved when clicked?
Here's my code for the adapter:
public class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, String>> mData;
public MyAdapter(ArrayList<HashMap<String, String>> mData2) {
this.mData = mData2;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return this.mData.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View mView = convertView;
String betid = mData.get(i).get("betid");
ViewHolder holder ;
if (mView == null) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
mView = inflater.inflate(R.layout.row_layout, null,false);
holder = new ViewHolder();
holder.tx_number = (TextView) mView.findViewById(R.id.tx_number);
holder.tx_amount = (TextView) mView.findViewById(R.id.tx_amount);
holder.tx_counter = (TextView) mView.findViewById(R.id.tx_counter);
mView.setTag(holder);
} else {
holder = (ViewHolder) mView.getTag();
}
if (betid != null) {
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
holder.tx_number.setText(betnumber);
holder.tx_amount.setText(amountTarget);
holder.tx_counter.setText(amountRamble);
}
return mView;
}
private class ViewHolder {
TextView tx_number;
TextView tx_amount;
TextView tx_counter;
}
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkmark);
TextView tv3 = (TextView)view.findViewById(R.id.tx_counter);
EditText editText = (EditText)findViewById(R.id.editText3);
String yy = editText.getText().toString().trim();
String shitts = listView.getItemAtPosition(position).toString();
ArrayList<String> list = new ArrayList<String>();
try {
String[] a = shitts.split(", ");
String[] b = a[1].split("=");
String[] sep = a[0].split("=");
String betnumber = sep[1];
String betamount= b[1];
checkBox.setChecked(!checkBox.isChecked());
if(checkBox.isChecked()){
//sort number
final String sorted = betnumber.chars().sorted().mapToObj(c -> Character.valueOf((char)c).toString()).collect(Collectors.joining());
//check if double digit
Boolean checker = doubleChecker(sorted);
if (checker == true){
Toast.makeText(getApplicationContext(),"DOUBLE DIGIT", LENGTH_SHORT).show();
int answer = Integer.parseInt(betamount) / 3;
tv3.setText(String.valueOf(answer));
}else{
Toast.makeText(getApplicationContext(),"NOT DOUBLE DIGIT", LENGTH_SHORT).show();
int answer;
if(yy.equals("")){
answer = Integer.parseInt(betamount) / 6;
tv3.setText(String.valueOf(answer));
}else{
answer = (Integer.parseInt(betamount) - Integer.parseInt(yy)) / 6;
tv3.setText(String.valueOf(answer));
}
}
//TODO save to array to send
}else{
//TODO mistake RETURN tv3 to old value // remove from array
tv3.setText("0");
}
}catch (Exception e){
}
}
});
I think the issue is here
if (betid != null) {
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
holder.tx_number.setText(betnumber);
holder.tx_amount.setText(amountTarget);
holder.tx_counter.setText(amountRamble);
}
You are missing an elsestatement to set other values when betid is null.
If betid is null, other rows can hold values from previous rows.
...
holder.tx_amount.setText(amountTarget);
holder.tx_counter.setText(amountRamble);
} else {
// assuming that if betid is null, then, TextViews should be cleared
// or replace with your own values
holder.tx_number.setText("");
holder.tx_amount.setText("");
holder.tx_counter.setText("");
}
I use SQLITE database to store list items and Baseadapter to display listview in my application.
Each item in the listview have edit text value, By default the value is 1.
When user changes the value from 1 to 2 , then the value has to be updated in database.
This update has to be done inside Adapter.
Below is the Adapter code where I change the edit text value.
public class CustomAdapter_cart extends BaseAdapter {
ArrayList<String> list_name = new ArrayList<String>();
ArrayList<String> list_price = new ArrayList<String>();
ArrayList<String> list_images = new ArrayList<String>();
ArrayList<String> list_model = new ArrayList<String>();
ArrayList<String> list_productid = new ArrayList<String>();
ArrayList<Integer> ids = new ArrayList<Integer>();
CustomAdapter_cart cart_refresh;
Bitmap b;
Context context;
AddToCart cart;
String value,name,price,image_new,model,product,qty;
private static LayoutInflater inflater = null;
Cursor cu;
String quant;
Holder holder = new Holder();
SharedPreferences sharedpreferences;
ArrayList<String>listMessages = new ArrayList<String>(new LinkedHashSet<String>());
ArrayList<String> quant_items = new ArrayList<String>();
Cursor mCursor;
ContentValues data=new ContentValues();
String model_item;
String id;
int id_final;
public CustomAdapter_cart(Context context, ArrayList<String> list_name, ArrayList<String> list_price, ArrayList<String> bitmapArray, ArrayList<String> list_model, ArrayList<String> list_productid,ArrayList<String> qty, ArrayList<Integer>ids ) {
this.context = context;
this.list_name = list_name;
this.list_price = list_price;
this.list_images = bitmapArray;
this.list_model = list_model;
this.list_productid = list_productid;
this.quant_items = qty;
this.cart_refresh = this;
this.ids = ids;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return list_name.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder {
TextView tv_name, tv_price, tv_model,tv_product,tv_id;
ImageView image;
Button delete;
EditText quantity;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View rowView = convertView;
if (convertView == null) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.list_items_cart, null);
holder.tv_name = (TextView) rowView.findViewById(R.id.name_cart);
holder.tv_price = (TextView) rowView.findViewById(R.id.price_cart);
holder.image = (ImageView) rowView.findViewById(R.id.image_cart);
holder.tv_model = (TextView) rowView.findViewById(R.id.model_cart);
holder.tv_product = (TextView) rowView.findViewById(R.id.product_cart);
holder.delete = (Button) rowView.findViewById(R.id.delete);
holder.quantity = (EditText) rowView.findViewById(R.id.quantity);
holder.tv_id = (TextView)rowView.findViewById(R.id.ids);
rowView.setTag(holder);
}
else
holder = (Holder) rowView.getTag();
holder.tv_name.setText(list_name.get(position));
name = holder.tv_name.getText().toString();
holder.tv_price.setText(list_price.get(position));
price = holder.tv_price.getText().toString();
holder.tv_model.setText(list_model.get(position));
model = holder.tv_model.getText().toString();
holder.tv_product.setText(list_productid.get(position));
product = holder.tv_product.getText().toString();
holder.quantity.setText(quant_items.get(position));
quant = holder.quantity.getText().toString();
holder.tv_id.setText(Integer.toString(ids.get(position)));
id = holder.tv_id.getText().toString();
id_final = Integer.parseInt(id);
holder.image.setImageBitmap(loadImageFromStorage(list_images.get(position)));
image_new = holder.image.toString();
final View finalRowView1 = rowView;
holder.quantity.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
value = s.toString();
quant.replace(quant, value);
updateTable();
Toast.makeText(finalRowView1.getContext(), "Updating Table", Toast.LENGTH_SHORT).show();
}
});
final View finalRowView = rowView;
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name_item = ((TextView) finalRowView.findViewById(R.id.name_cart)).getText().toString();
String price_item = ((TextView) finalRowView.findViewById(R.id.price_cart)).getText().toString();
model_item = ((TextView) finalRowView.findViewById(R.id.model_cart)).getText().toString();
Intent in = new Intent(context, AddCart_FullImage.class);
in.putExtra("model", model_item);
in.putExtra("name", name_item);
in.putExtra("price", price_item);
context.startActivity(in);
}
});
return rowView;
}
private Bitmap loadImageFromStorage(String path) {
try {
File f = new File(path, "");
f.canRead();
b = BitmapFactory.decodeStream(new FileInputStream(f));
return b;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
public void updateTable() {
final DatabaseHandler db = new DatabaseHandler(context);
SQLiteDatabase db1 = db.getWritableDatabase();
try {
db.updateContact(new Cart(id_final,name, price, image_new, model, product, value));
Log.v("LOG", "After text change value db " + value);
} catch (Exception e) {
}
}
}
Problem
When I try to update the edit text value, it gets updated in db but again it changes to default value "1".
I am not sure where I am going wrong.
Any help would be really greatfull.
Thanks.
Each time the system wants to redraw your ListView it calls the getView(...) method of your adapter. The following line sets the value of your quantity EditText:
holder.quantity.setText(quant_items.get(position));
When the user changes the value in the EditText you do the following:
quant.replace(quant, value);
updateTable();
As you can see, your adapter's datasource (quant_items) is not updated.
Since you are updating the database from within the adapter, you can just update the quant_items ArrayList and it should do the trick.
You need to notify your adapter if you change its data (and of, you need to update list_name with the new values).
The easiest way to notify your adapter is to use notifyDatasetChanged() after you updated your data.
setting the text view according its position in of the row a list view filled from SimpleCursorAdapter from database on the click of the onlistitemclicked
my custom list view has an image& textview for a name and another invisible text view which will be visible and be setting with a different number on the row clicked only but the problem is that when i clicked any row the text appeared on the view at the first row only whatever the row i clicked
and I tried to use the set and get methods but i found its used for the Base Adapter.
and the textview which will visible is not from data base
can some one tell me how to do it please
here is a part of the code
public class Select_players_two extends ListActivity
{
protected static class RowViewHolder
{
public TextView tvOne;
public TextView tvTwo;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(android.view.Menu menu)
{
// TODO Auto-generated method stub
return super.onCreateOptionsMenu(menu);
}
public class CustConAdpterSelect extends SimpleCursorAdapter
{
int i = 0;
int count;
private int layout;
LayoutInflater inflator;
final SQLiteConnector sqlCon = new SQLiteConnector(mContext);
private ImageButton editBtn;
private ImageButton delBtn;
int id ;
TextView txt_select;
CharSequence txt_char;
static final String KEY_No = "playerNo";
public CustConAdpterSelect(Context context, int layout, Cursor c,
String[] from, int[] to, int flags)
{
super(context, layout, c, from, to,0);
this.layout = layout;
inflator= LayoutInflater.from(context);
}
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.lv_name_photo, parent, false);
RowViewHolder holder = new RowViewHolder();
holder.tvOne = (TextView) retView.findViewById(R.id.name);
holder.tvTwo = (TextView) retView.findViewById(R.id.txt_number);
// holder.tvOne.setOnClickListener(tvOneLapOnClickListener);
retView.setTag(holder);
return retView;
}
#Override
public void bindView(View v, final Context context, Cursor c)
{
editBtn=(ImageButton) v.findViewById(R.id.edit_btn);
if( editBtn.getVisibility() == View.VISIBLE )
editBtn.setVisibility(View.INVISIBLE);
else
editBtn.setVisibility(View.INVISIBLE);
//set delete button invisble
delBtn=(ImageButton) v.findViewById(R.id.del_btn);
if( delBtn.getVisibility() == View.VISIBLE )
delBtn.setVisibility(View.INVISIBLE);
else
delBtn.setVisibility(View.INVISIBLE);
//final int
id = c.getInt(c.getColumnIndex(Contacts.ID));
final String name = c.getString(c.getColumnIndex(Contacts.NAME));
final String phone = c.getString(c.getColumnIndex(Contacts.PHONE));
final String email = c.getString(c.getColumnIndex(Contacts.MAIL));
final String fb = c.getString(c.getColumnIndex(Contacts.FB));
final byte[] image = c.getBlob(c.getColumnIndex(Contacts.IMAGE));
ImageView iv = (ImageView) v.findViewById(R.id.photo);
if (image != null)
{
if (image.length > 3)
{
iv.setImageBitmap(BitmapFactory.decodeByteArray(image, 0,image.length));
}
}
TextView tname = (TextView) v.findViewById(R.id.name);
tname.setText(name);
TextView tphone = (TextView) v.findViewById(R.id.phone);
tphone.setText(phone);
TextView temail = (TextView) v.findViewById(R.id.email);
temail.setText(email);
txt_select=(TextView)v.findViewById(R.id.txt_number);
// final SQLiteConnector sqlCon = new SQLiteConnector(context);
//for( i = 0; i <=4; i++)
/*
v.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//onitem clicked
txt_char = txt_select.getText();
{
if (txt_char != null)
{
int txt_int = Integer.parseInt(txt_char.toString());
int count = txt_int;
Log.d("count1",String.valueOf(count));
count++;
txt_select.setText(String.valueOf(count));
Log.d("count",String.valueOf(count));
if( txt_select.getVisibility() == View.INVISIBLE )
txt_select.setVisibility(View.VISIBLE);
else
txt_select.setVisibility(View.INVISIBLE);
Log.d("number", String.valueOf(i));
}
/* if( txt_select.getVisibility() == View.INVISIBLE )
txt_select.setVisibility(View.VISIBLE);
else
txt_select.setVisibility(View.INVISIBLE);
i++;
Log.d("number", String.valueOf(i));*/
/* }
}
});
*/
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
final View view = super.getView(position, convertView, parent);
final TextView textView = (TextView)view.findViewById(R.id.txt_number);
/* textView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Log.i("Click", "TextView clicked on row " + position);
// textView.setTag(position);
txt_char = txt_select.getText();
Log.d("txt", txt_char.toString());
if (txt_char != null)
{
int txt_int = Integer.parseInt(txt_char.toString());
Log.d("txt2", txt_char.toString());
int count = txt_int;
Log.d("count1",String.valueOf(count));
count++;
txt_select.setText(String.valueOf(count));
CharSequence txt_char2 = txt_select.getText();
Log.d("ttxt", txt_char2.toString());
Log.d("count",String.valueOf(count));
if( txt_select.getVisibility() == View.INVISIBLE )
txt_select.setVisibility(View.VISIBLE);
else
txt_select.setVisibility(View.INVISIBLE);
Log.d("number", String.valueOf(i));
i++;
}
}*/
// }); // TODO Auto-generated method stub
return view;
}
private OnClickListener tvOneLapOnClickListener = new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// get the RowViewHolder
RowViewHolder holder = new RowViewHolder();
// Get the holder for the row
holder = (RowViewHolder) ((View) v.getParent()).getTag();
if (holder.tvOne.getVisibility() == View.INVISIBLE)
holder.tvOne.setVisibility(View.VISIBLE);
else
holder.tvOne.setVisibility(View.INVISIBLE);
}
};
}
}
that is the database class "SQLiteConnector"
public class SQLiteConnector
{
private SQLiteDatabase db;
private SQLiteHelper sqlHp,sqlhpc;
private Cursor cur,curc;
public SQLiteConnector(Context context)
{
sqlHp = new SQLiteHelper(context, Contacts.DB_NAME, null, 1);
sqlhpc = new SQLiteHelper(context, Contacts.DB_NAME, null, 1);
}
// insert new player in the list//
public void insertContact(String name, String phone, String mail,String fb,byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE,blob);
db = sqlHp.getWritableDatabase();
db.insert(Contacts.TABLE, null, cv);
db.close();
}
// insert the score sheet //
public void insertContact_score(String score, String num_call, String num_collection ,String shape_type,
String score_sec, String num_call_sec, String num_collection_sec ,String shape_type_sec,
String score_third, String num_call_third, String num_collection_third ,String shape_type_third,
String score_forth, String num_call_forth, String num_collection_forth ,String shape_type_forth)
{
ContentValues cvscore = new ContentValues();
cvscore.put(Contacts.SCORE_st, score);
cvscore.put(Contacts.NUM_CALL_st, num_call);
cvscore.put(Contacts.NUM_COLLECTION_st, num_collection);
cvscore.put(Contacts.SHAPE_CALL_st, shape_type);
cvscore.put(Contacts.SCORE_sec, score_sec);
cvscore.put(Contacts.NUM_CALL_sec, num_call_sec);
cvscore.put(Contacts.NUM_COLLECTION_sec, num_collection_sec);
cvscore.put(Contacts.SHAPE_CALL_sec, shape_type_sec);
cvscore.put(Contacts.SCORE_third, score_third);
cvscore.put(Contacts.NUM_CALL_third, num_call_third);
cvscore.put(Contacts.NUM_COLLECTION_third, num_collection_third);
cvscore.put(Contacts.SHAPE_CALL_third,shape_type_third);
cvscore.put(Contacts.SCORE_forth, score_forth);
cvscore.put(Contacts.NUM_CALL_forth, num_call_forth);
cvscore.put(Contacts.NUM_COLLECTION_forth, num_collection_forth);
cvscore.put(Contacts.SHAPE_CALL_forth,shape_type_forth);
//cvscore.put(Contacts.IMAGE,blob);
db = sqlhpc.getWritableDatabase();
db.insert(Contacts.TABLESCORE, null, cvscore);
db.close();
}
public void updateContact_score(long id,String score, String num_call, String num_collection ,String shape_type,
String score_sec, String num_call_sec, String num_collection_sec ,String shape_type_sec,
String score_third, String num_call_third, String num_collection_third ,String shape_type_third,
String score_forth, String num_call_forth, String num_collection_forth ,String shape_type_forth)
{
ContentValues cvscore = new ContentValues();
cvscore.put(Contacts.SCORE_st, score);
cvscore.put(Contacts.NUM_CALL_st, num_call);
cvscore.put(Contacts.NUM_COLLECTION_st, num_collection);
cvscore.put(Contacts.SHAPE_CALL_st, shape_type);
cvscore.put(Contacts.SCORE_sec, score_sec);
cvscore.put(Contacts.NUM_CALL_sec, num_call_sec);
cvscore.put(Contacts.NUM_COLLECTION_sec, num_collection_sec);
cvscore.put(Contacts.SHAPE_CALL_sec, shape_type_sec);
cvscore.put(Contacts.SCORE_third, score_third);
cvscore.put(Contacts.NUM_CALL_third, num_call_third);
cvscore.put(Contacts.NUM_COLLECTION_third, num_collection_third);
cvscore.put(Contacts.SHAPE_CALL_third,shape_type_third);
cvscore.put(Contacts.SCORE_forth, score_forth);
cvscore.put(Contacts.NUM_CALL_forth, num_call_forth);
cvscore.put(Contacts.NUM_COLLECTION_forth, num_collection_forth);
cvscore.put(Contacts.SHAPE_CALL_forth,shape_type_forth);
//cvscore.put(Contacts.IMAGE,blob);
db = sqlhpc.getWritableDatabase();
db.update(Contacts.TABLESCORE, cvscore, Contacts.ID+"="+ id, null);
db.close();
}
public void updateContact(long id,String name, String phone, String mail,String fb,byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE,blob);
db = sqlHp.getWritableDatabase();
db.update(Contacts.TABLE, cv, Contacts.ID+"="+ id, null);
db.close();
}
public Cursor getAllContacts() {
db = sqlHp.getReadableDatabase();
cur=db.query(Contacts.TABLE,null, null,null, null, null, "name");
return cur;
}
public Cursor getAllScores() {
db = sqlhpc.getReadableDatabase();
curc=db.query(Contacts.TABLESCORE,null, null,null, null, null, "score_st");
return curc;
}
public void deletescore(long id) {
System.out.println("DELETE ");
db = sqlhpc.getWritableDatabase();
db.delete(Contacts.TABLESCORE, "_id="+id , null);
db.close();
}
public Cursor getOneContact(long id) {
db = sqlHp.getReadableDatabase();
cur=db.query(Contacts.TABLE, null, "_id="+ id, null, null, null,null);
return cur;
}
public void deleteContact(long id) {
System.out.println("DELETE ");
db = sqlHp.getWritableDatabase();
db.delete(Contacts.TABLE, "_id="+id , null);
db.close();
}
}
I believe what you need to do is use the Tag facility of the row view container to identify the textview it contains and then retrieve it in the listener to identify the correct textview. The way I've done it is to use a holder for the row contained views, so you can access any that you need. For example:
protected static class RowViewHolder {
public TextView tvOne;
public TextView tvTwo;
}
Then in your newView method, populate the holder and set the Tag to it:
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.single_row_item, parent, false);
RowViewHolder holder = new RowViewHolder();
holder.tvOne = (TextView) retView.findViewById(R.id.name);
holder.tvTwo = (TextView) retView.findViewById(R.id.txt_number);
retView.setTag(holder);
return retView;
}
In your listener then you can access the correct textview:
public void onClick(View v) {
ListView lv = (ListView) v.getParent();
final int position = lv.getPositionForView((View) v.getParent());
// get the RowViewHolder
RowViewHolder holder = new RowViewHolder();
holder = (RowViewHolder) ((View) v.getParent()).getTag();
if(holder.tvOne.getVisibility() == View.INVISIBLE ) {
holder.tvOne.setVisibility(View.VISIBLE);
}
else
{
holder.tvOne.setVisibility(View.INVISIBLE);
}
}
Apologies, but I've not been able to test this code but I hope it gives you a pointer to the process. You shouldn't need the RowViewHolder but I've included it so you or others can see how to access multiple views within the row.
You may find the this video helpful The World of ListView I think you'll find the relevant discussion at about 4:10 in which describes how the views are res-used and how index, position etc. relate.
I also found one of the answers to this question helpful Android: ListView elements with multiple clickable buttons
There are multiple ways of doing this. The way I was suggesting assumes you have a single code module for the activity containing the CustConAdpterSelect class. So the structure looks something like this.
package com.example.totastest;
// imports
public class Copy_2_of_MainActivity extends Activity {
protected static class RowViewHolder
{
public TextView tvOne;
public TextView tvTwo;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class CustConAdpterSelect extends SimpleCursorAdapter
{
// ...
public CustConAdpterSelect(Context context, int layout, Cursor c, String[] from, int[] to)
{
super(context, layout, c, from, to, 0);
// ...
}
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.lv_name_photo, parent, false);
RowViewHolder holder = new RowViewHolder();
holder.tvOne = (TextView) retView.findViewById(R.id.name);
holder.tvTwo = (TextView) retView.findViewById(R.id.txt_number);
holder.tvOne.setOnClickListener(tvOneLapOnClickListener);
retView.setTag(holder);
return retView;
}
#Override
public void bindView(View v, final Context context, Cursor c)
{
// ...
}
#SuppressWarnings("unchecked")
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
// ...
}
private OnClickListener tvOneLapOnClickListener = new OnClickListener() {
#Override
// When the tvOne button is clicked, execute this code
public void onClick(View v) {
// get the RowViewHolder
RowViewHolder holder = new RowViewHolder();
// Get the holder for the row
holder = (RowViewHolder) ((View) v.getParent()).getTag();
if (holder.tvOne.getVisibility() == View.INVISIBLE)
holder.tvOne.setVisibility(View.VISIBLE);
else
holder.tvOne.setVisibility(View.INVISIBLE);
}
};
}
protected void onListItemClick(ListView l, View v, int position, long id)
{
// ...
}
}
I've written an activity which loads all contacts of the phone and displays it at once in a ListView. The thing is, it takes time to load 400+ contacts and this is not very user friendly. Can anyone point me how can i make this activity run in the background\run faster, I've tried to use AsyncTask but apparently it uses a class rather and not an activity. Any advice is greatly appreciated.
Im adding the code so it will be easier to understand how things work for now:
This is the Contacts class:
public class CustomContact
{
private String contactName;
private String contactPhoneNumber;
private boolean selected = false;
public CustomContact()
{
}
public CustomContact(String contactName, String contactPhoneNumber, boolean selected)
{
super();
this.contactName = contactName;
this.contactPhoneNumber = contactPhoneNumber;
this.selected = selected;
}
public String getContactName()
{
return contactName;
}
public void setContactName(String contactName)
{
this.contactName = contactName;
}
public String getContactPhoneNumber()
{
return contactPhoneNumber;
}
public void setContactPhoneNumber(String contactPhoneNumber)
{
this.contactPhoneNumber = contactPhoneNumber;
}
public boolean isSelected()
{
return selected;
}
public void setSelected(boolean selected)
{
this.selected = selected;
}
#Override
public String toString()
{
return contactPhoneNumber + " " + "\u200e" + contactName;
}
}
Now the code of the activity which uses the CustomContacts class:
public class ContactSelectActivity extends Activity
{
MyCustomAdapter dataAdapter = null;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_select);
//Generate list View from ArrayList
displayListView();
checkButtonClick();
}
private void displayListView()
{
//Array list of countries
ArrayList<CustomContact> contactsList = new ArrayList<CustomContact>();
String[] projection = new String[] {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts.LOOKUP_KEY
};
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME ;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, projection,
ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"+ ("1") + "'",
null, sortOrder
);
if (cursor.getCount() > 0)
{
while (cursor.moveToNext())
{
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
// Query phone here. Covered next
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
while (phones.moveToNext())
{
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
CustomContact customContact = new CustomContact(name, phoneNumber, false);
contactsList.add(customContact);
}
phones.close();
}
}
}
//create an ArrayAdaptar from the String Array
dataAdapter = new MyCustomAdapter(this,R.layout.custom_contact_info, contactsList);
ListView listView = (ListView) findViewById(R.id.listView1);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
CustomContact contact = (CustomContact) parent.getItemAtPosition(position);
}
});
}
private class MyCustomAdapter extends ArrayAdapter<CustomContact>
{
private ArrayList<CustomContact> contactList;
public MyCustomAdapter(Context context, int textViewResourceId,
ArrayList<CustomContact> stateList)
{
super(context, textViewResourceId, stateList);
this.contactList = new ArrayList<CustomContact>();
this.contactList.addAll(stateList);
}
private class ViewHolder
{
TextView code;
CheckBox name;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.custom_contact_info, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.code);
holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
holder.name.setOnClickListener( new View.OnClickListener()
{
public void onClick(View v)
{
CheckBox cb = (CheckBox) v;
CustomContact _contact = (CustomContact) cb.getTag();
_contact.setSelected(cb.isChecked());
}
});
}
else
{
holder = (ViewHolder) convertView.getTag();
}
CustomContact contact = contactList.get(position);
holder.code.setText(" (" + contact.getContactName() + ")");
holder.name.setText(contact.getContactPhoneNumber());
holder.name.setChecked(contact.isSelected());
holder.name.setTag(contact);
return convertView;
}
}
private void checkButtonClick()
{
Button myButton = (Button) findViewById(R.id.findSelected);
myButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
StringBuffer responseText = new StringBuffer();
responseText.append("The following were selected...\n");
ArrayList<CustomContact> contactList = dataAdapter.contactList;
for(int i=0;i<contactList.size();i++)
{
CustomContact contact = contactList.get(i);
if(contact.isSelected())
{
responseText.append("\n" + contact.getContactPhoneNumber());
}
}
}
});
}
}
I had tried to to put checkbox in listview through layout inflator and I got success but the problem is when I select the multiple contacts there is no problem but when I deselect it & when I scroll down & then go back to that deselected checkbox its get automatically selected...
public class Contactlist_selfActivity extends ListActivity {
/** Called when the activity is first created. */
private ArrayList<contact> contact_list = null;
private ProgressDialog mProgressDialog = null;
private contactAdapter mContactAdapter = null;
private Runnable mViewcontacts = null;
private SparseBooleanArray mSelectedContacts = new SparseBooleanArray();
private ArrayList<contact> items;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
contact_list = new ArrayList<contact>();
this.mContactAdapter = new contactAdapter(this, R.layout.listview,
contact_list);
ListView lv = getListView();
setListAdapter(this.mContactAdapter);
lv.setItemsCanFocus(false);
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
// }
mViewcontacts = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
getContacts();
}
};
Thread thread = new Thread(null, mViewcontacts, "ContactReadBackground");
thread.start();
mProgressDialog = ProgressDialog.show(Contactlist_selfActivity.this,
"Please Wait...", "Retriving Contacts...", true);
}
#SuppressWarnings("unused")
private void getContacts() {
// TODO Auto-generated method stub
try {
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts._ID };
Cursor mCursor = managedQuery(
ContactsContract.Contacts.CONTENT_URI, projection,
ContactsContract.Contacts.HAS_PHONE_NUMBER + "=?",
new String[] { "1" },
ContactsContract.Contacts.DISPLAY_NAME);
while (mCursor.moveToNext()) {
contact contact = new contact();
String contactId = mCursor.getString(mCursor
.getColumnIndex(ContactsContract.Contacts._ID));
contact.setContactName(mCursor.getString(mCursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
contact_list.add(contact);
}
mCursor.close();
runOnUiThread(returnRes);
} catch (Exception e) {
// TODO: handle exception
Log.d("getContacts", e.getMessage());
}
}
public class contactAdapter extends ArrayAdapter<contact> {
private int[] isChecked;
public contactAdapter(Context context, int textViewResourceId,
ArrayList<contact> items1) {
super(context, textViewResourceId, items1);
items = items1;
}
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
final int position_clicked = 0;
// Log.i("asd", "getView :" + getItem(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.listview, parent, false);
}
contact contacts = items.get(position);
isChecked = new int[items.size()];
if (contacts != null) {
final CheckBox nameCheckBox = (CheckBox) convertView
.findViewById(R.id.checkBox);
nameCheckBox.setChecked(mSelectedContacts.get(position));
for (int i = 0; i < isChecked.length; i++) {
}
if (nameCheckBox != null) {
nameCheckBox.setText(contacts.getContactName());
}
nameCheckBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
isChecked[position_clicked] = position;
Log.d("position", String.valueOf(position));
}
});
}
return convertView;
}
}
private Runnable returnRes = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if (mProgressDialog.isShowing())
mProgressDialog.dismiss();
mContactAdapter.notifyDataSetChanged();
}
};
}
i found the answer....
i had just taken a new variable in contact class...
public class PlanetsActivity extends Activity {
private ListView mainListView;
private Contact[] contact_read;
private Cursor mCursor;
private ArrayAdapter<Contact> listAdapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Find the ListView resource.
mainListView = (ListView) findViewById(R.id.mainListView);
mainListView
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View item,
int position, long id) {
Contact planet = listAdapter.getItem(position);
planet.toggleChecked();
ContactViewHolder viewHolder = (ContactViewHolder) item
.getTag();
viewHolder.getCheckBox().setChecked(planet.isChecked());
}
});
// Throw Query and fetch the contacts.
String[] projection = new String[] { Contacts.HAS_PHONE_NUMBER,
Contacts._ID, Contacts.DISPLAY_NAME };
mCursor = managedQuery(Contacts.CONTENT_URI, projection,
Contacts.HAS_PHONE_NUMBER + "=?", new String[] { "1" },
Contacts.DISPLAY_NAME);
if (mCursor != null) {
mCursor.moveToFirst();
contact_read = new Contact[mCursor.getCount()];
// Add Contacts to the Array
int j = 0;
do {
contact_read[j] = new Contact(mCursor.getString(mCursor
.getColumnIndex(Contacts.DISPLAY_NAME)));
j++;
} while (mCursor.moveToNext());
} else {
System.out.println("Cursor is NULL");
}
// Add Contact Class to the Arraylist
ArrayList<Contact> planetList = new ArrayList<Contact>();
planetList.addAll(Arrays.asList(contact_read));
// Set our custom array adapter as the ListView's adapter.
listAdapter = new ContactArrayAdapter(this, planetList);
mainListView.setAdapter(listAdapter);
}
/** Holds Contact data. */
#SuppressWarnings("unused")
private static class Contact {
private String name = "";
private boolean checked = false;
public Contact() {
}
public Contact(String name) {
this.name = name;
}
public Contact(String name, boolean checked) {
this.name = name;
this.checked = checked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public String toString() {
return name;
}
public void toggleChecked() {
checked = !checked;
}
}
/** Holds child views for one row. */
#SuppressWarnings("unused")
private static class ContactViewHolder {
private CheckBox checkBox;
private TextView textView;
public ContactViewHolder() {
}
public ContactViewHolder(TextView textView, CheckBox checkBox) {
this.checkBox = checkBox;
this.textView = textView;
}
public CheckBox getCheckBox() {
return checkBox;
}
public void setCheckBox(CheckBox checkBox) {
this.checkBox = checkBox;
}
public TextView getTextView() {
return textView;
}
public void setTextView(TextView textView) {
this.textView = textView;
}
}
/** Custom adapter for displaying an array of Contact objects. */
private static class ContactArrayAdapter extends ArrayAdapter<Contact> {
private LayoutInflater inflater;
public ContactArrayAdapter(Context context, List<Contact> planetList) {
super(context, R.layout.simplerow, R.id.rowTextView, planetList);
// Cache the LayoutInflate to avoid asking for a new one each time.
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Contact to display
Contact planet = (Contact) this.getItem(position);
System.out.println(String.valueOf(position));
// The child views in each row.
CheckBox checkBox;
TextView textView;
// Create a new row view
if (convertView == null) {
convertView = inflater.inflate(R.layout.simplerow, null);
// Find the child views.
textView = (TextView) convertView
.findViewById(R.id.rowTextView);
checkBox = (CheckBox) convertView.findViewById(R.id.CheckBox01);
// Optimization: Tag the row with it's child views, so we don't
// have to
// call findViewById() later when we reuse the row.
convertView.setTag(new ContactViewHolder(textView, checkBox));
// If CheckBox is toggled, update the Contact it is tagged with.
checkBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Contact contact = (Contact) cb.getTag();
contact.setChecked(cb.isChecked());
}
});
}
// Reuse existing row view
else {
// Because we use a ViewHolder, we avoid having to call
// findViewById().
ContactViewHolder viewHolder = (ContactViewHolder) convertView
.getTag();
checkBox = viewHolder.getCheckBox();
textView = viewHolder.getTextView();
}
// Tag the CheckBox with the Contact it is displaying, so that we
// can
// access the Contact in onClick() when the CheckBox is toggled.
checkBox.setTag(planet);
// Display Contact data
checkBox.setChecked(planet.isChecked());
textView.setText(planet.getName());
return convertView;
}
}
public Object onRetainNonConfigurationInstance() {
return contact_read;
}
}
The cause of this is that when you call nameCheckBox.setChecked() in code OnClickListener() awakes and run its code. I had the same problem an solved in just setting OnClickListener(null) before set a checkbox checked or not.
nameCheckBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
isChecked[position_clicked] = position;
Log.d("position", String.valueOf(position));
}
});
this code in add more one arre list in stores all position and add or remove both said
fast add ,second remove.
and used to list in position your other method