Searching in Listview are not working properly. If i enter string that is in my array list it shows all the records but if i enter any other string in my edit text field it shows an empty list.
public class GetCustomList extends ListActivity {
TweetListAdaptor myAdaptor;
ListView lv;
EditText searchTxt;
public ArrayList<Contact> tweets = new ArrayList<Contact>();
DatabaseHandler db = new DatabaseHandler(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.customer_info);
tweets = db.getAllContacts();
lv = (ListView) findViewById(android.R.id.list);
lv.setTextFilterEnabled(true);
searchTxt = (EditText) findViewById(R.id.editTextSearchNameField);
searchTxt.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
myAdaptor.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
Button btnSearch = (Button) findViewById(R.id.buttonSearch);
btnSearch.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
onPostExecute(null);
}
});
/**
* CRUD Operations
* */
// Inserting Contacts
Log.d("Insert: ", "Inserting ..");
db.addContact(new Contact("786","zahid", "bilaltown", '0'));
db.addContact(new Contact("123","Shahid", "bilaltown", '0'));
db.addContact(new Contact("123","waqas", "bilaltown", '0'));
// Reading all contacts
Log.d("Reading: ", "Reading all contacts..");
for (Contact cn : tweets) {
String log = "Id: "+cn.get_id()+ ",Code:"+ cn.get_code() +" ,Name: " + cn.get_name() + " ,Address: " + cn.get_address() + " ,Phone: " + cn.get_limit();
// Writing Contacts to log
Log.d("Name: ", log);
}
}
protected void onPostExecute(Void result) {
myAdaptor = new TweetListAdaptor(GetCustomList.this, tweets);
myAdaptor.notifyDataSetChanged();
setListAdapter(myAdaptor);
}
public class TweetListAdaptor extends ArrayAdapter<Contact> implements Filterable {
private ArrayList<Contact> mOriginalValues = new ArrayList<Contact>(); // Original Values
private ArrayList<Contact> mDisplayedValues = new ArrayList<Contact>(); // Values to be displayed
LayoutInflater inflater;
Context context;
public TweetListAdaptor(Context context,ArrayList<Contact> items) {
super(context, R.layout.custom_list_info, items);
this.mOriginalValues = items;
this.mDisplayedValues = items;
this.context = context;
// inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return mDisplayedValues.size();
}
#Override
public long getItemId(int position) {
return position;
}
public class ViewHolder {
private TextView CustomerId;
private TextView CustomerShop;
private TextView date;
private TextView phoneNumber;
public ViewHolder(View v) {
this.CustomerId = (TextView) v.findViewById(R.id.textViewCustomerID);
this.CustomerShop = (TextView) v.findViewById(R.id.textViewShopName);
// this.date = (TextView) v.findViewById(R.id.date);
// this.status = (TextView) v.findViewById(R.id.staus);
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.custom_list_info, null);
holder = new ViewHolder(v);
v.setTag(holder);
}else {
holder = (ViewHolder) v.getTag();
}
final Contact o = getItem(position);
if (o != null) {
holder.CustomerId.setText(""+o._id);
holder.CustomerShop.setText(o._name);
//holder.date.setText(o.date);
//holder.status.setText(o.status_txt);
/*if(o.status.equals("1")){
RelativeLayout llr = (RelativeLayout) v.findViewById(R.id.testRes);
llr.setBackgroundResource(R.drawable.decline);
}else if(o.status.equals("2")){
RelativeLayout llr = (RelativeLayout) v.findViewById(R.id.testRes);
llr.setBackgroundResource(R.drawable.acceptence);
}
}*/
ImageButton btnSearchCustomer = (ImageButton) v.findViewById(R.id.btnSearchCustomer);
btnSearchCustomer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(GetCustomList.this, CustomerDetailedInfo.class);
intent.putExtra("ccode", o._code);
intent.putExtra("cname", o._name);
intent.putExtra("caddress", o._address);
intent.putExtra("climit", o._limit);
startActivity(intent);
}
});
}
return v;
}
///////////////////////////////
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
mDisplayedValues = (ArrayList<Contact>) results.values; // has the filtered values
notifyDataSetChanged(); // notifies the data with new filtered values
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values
ArrayList<Contact> FilteredArrList = new ArrayList<Contact>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<Contact>(mDisplayedValues); // saves the original data in mOriginalValues
}
/********
*
* If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
* else does the Filtering and returns FilteredArrList(Filtered)
*
********/
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = mOriginalValues.size();
results.values = mOriginalValues;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mOriginalValues.size(); i++) {
String data = mOriginalValues.get(i)._name;
if (data.toLowerCase().startsWith(constraint.toString())) {
FilteredArrList.add(new Contact(mOriginalValues.get(i)._name,mOriginalValues.get(i)._code,mOriginalValues.get(i)._address,mOriginalValues.get(i)._limit));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
///////////////////
}
Contact class
public class Contact {
//private variables
int _id;
String _code;
String _name;
String _address;
int _limit;
// Empty constructor
public Contact(){
}
// constructor
public Contact(int id, String _code,String name,String address, int _limit){
this._id = id;
this._code = _code;
this._name = name;
this._address = address;
this._limit = _limit;
}
// constructor
public Contact(String _code,String name, String address,int _limit){
this._code = _code;
this._name = name;
this._address = address;
this._limit = _limit;
}
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String get_code() {
return _code;
}
public void set_code(String _code) {
this._code = _code;
}
public String get_name() {
return _name;
}
public void set_name(String _name) {
this._name = _name;
}
public String get_address() {
return _address;
}
public void set_address(String _address) {
this._address = _address;
}
public int get_limit() {
return _limit;
}
public void set_limit(int _limit) {
this._limit = _limit;
}
}
There are a couple of minor mistakes in the code. First, you need to override the getItem() method in TweetListAdaptor:
#Override
public Contact getItem(int position)
{
return mDisplayedValues.get(position);
}
Then, in the Filter's performFiltering() method, the code and name parameters are switched for the Contact constructor in the following line:
FilteredArrList.add(new Contact(mOriginalValues.get(i)._code, mOriginalValues.get(i)._name, mOriginalValues.get(i)._address, mOriginalValues.get(i)._limit));
I ran a test with 20 names, and I believe that those corrections should fix the problem.
Related
Here i am using using BaseAdapter to filter my listview items.when without using search option if i click on my listview item the listView.setOnItemClickListener works well, I mean the item at the clicked position is passed to next activity.But on the filtered result if i click on the item,some other data is passed to next activity..what might be the issue.?can anyone please help me to solve this issue..?
Activity
public class BindTenGPS extends Activity {
private MenuItem menuItem;
DbaAdapter db;
private ProgressDialog progressDialog;
ListView listView ;
EditText inputSearch;
private BindTenDeviceBaseAdapter adapter;
List<RowTenDevice> rowTenDevice;
ArrayList<String> DeviceName = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list1_main);
inputSearch = (EditText)findViewById(R.id.inputSearch);
db=new DbaAdapter(getApplicationContext());
new LoadTrackNumbers().execute();
}
private class LoadTrackNumbers extends AsyncTask<Void, Integer, Void> {
int myProgress;
#Override
protected void onPreExecute()
{
//Create a new progress dialog
progressDialog = new ProgressDialog(BindTenGPS.this);
//Set the progress dialog to display a horizontal progress bar
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//Set the dialog title to 'Loading...'
progressDialog.setTitle("Loading...");
//Set the dialog message to 'Loading application View, please wait...'
progressDialog.setMessage("Loading application View, please wait...");
//This dialog can't be canceled by pressing the back key
progressDialog.setCancelable(true);
//This dialog isn't indeterminate
progressDialog.setIndeterminate(false);
//The maximum number of items is 100
progressDialog.setMax(100);
//Set the current progress to zero
progressDialog.setProgress(0);
//Display the progress dialog
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try
{
//Get the current thread's token
synchronized (this)
{
DeviceName.clear();
publishProgress(10);
this.wait(500);
Connection conn = null;
try {
Log.w("Error connection","shyam1");
String driver = "net.sourceforge.jtds.jdbc.Driver";
Log.w("Error connection","shyam2");
Log.i("Android"," MySQL Connect Example0.");
Class.forName(driver).newInstance();
Log.w("Error connection","shyam3");
String connString = "jdbc:jtds:sqlserver://ip address;instance=SQLEXPRESS;DatabaseName=AAUMConnect;";
String username = "username";
String password = "password";
Log.w("Error connection","shyam4");
publishProgress(20);
this.wait(500);
publishProgress(30);
this.wait(500);
publishProgress(40);
this.wait(500);
publishProgress(50);
this.wait(500);
conn = DriverManager.getConnection(connString,username,password);
publishProgress(80);
Log.w("Error connection","shyam5");
Statement stmt = conn.createStatement();
ResultSet reset;
db.open();
int superuser = db.GetISSuperUser();
db.close();
db.open();
int clientid = db.GetClientID();
db.close();
if(superuser == 0)
{
db.open();
String branch = db.GetBranch();
db.close();
reset = stmt.executeQuery("SELECT dbo.fn_AddEveryNthItem(LEFT(AssignVehicleToTrackTable, LEN(AssignVehicleToTrackTable) - 1), ',','#', 1) AS DeviceName FROM (SELECT DeviceName + ',' FROM AssignVehicleToTrack where ClientID = " + clientid + " and BranchName = '" + branch.trim() + "' and VirtualNo = 'GPS' order by DeviceName FOR XML PATH ('')) T1 (AssignVehicleToTrackTable)");
}
else
{
reset = stmt.executeQuery("SELECT dbo.fn_AddEveryNthItem(LEFT(AssignVehicleToTrackTable, LEN(AssignVehicleToTrackTable) - 1), ',','#', 1) AS DeviceName FROM (SELECT DeviceName + ',' FROM AssignVehicleToTrack where ClientID = " + clientid + " and VirtualNo = 'GPS' order by DeviceName FOR XML PATH ('')) T1 (AssignVehicleToTrackTable)");
}
//Print the data to the console
Log.w("Error connection","shyam6");
int i1 = 0, c = 0;
try
{
while(reset.next()){
publishProgress(c);
String[] tokens = new String[100];
tokens = reset.getString(1).split("#");
for(int i=0;i<tokens.length;i++)
{
DeviceName.add(tokens[i].substring(1));
}
i1++;
c+=10;
}
}
catch(Exception ex)
{
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "GPS Device not available", Toast.LENGTH_LONG).show();
}
});
}
reset.close();
conn.close();
rowTenDevice = new ArrayList<RowTenDevice>();
for (int j = 0; j < DeviceName.size(); j++) {
RowTenDevice item = new RowTenDevice(DeviceName.get(j));
Log.w("Data:","D"+j+" : "+DeviceName.get(j));
rowTenDevice.add(item);
}
runOnUiThread(new Runnable() {
#Override
public void run() {
listView = (ListView) findViewById(R.id.list);
Log.w("Data:","E1");
adapter = new BindTenDeviceBaseAdapter(BindTenGPS.this, rowTenDevice);
Log.w("Data:","E2");
listView.setAdapter(adapter);
Log.w("Data:","E3");
inputSearch.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
BindTenGPS.this.adapter.getFilter().filter(cs);
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(
AdapterView<?> arg0, View arg1,
int position, long arg3) {
// TODO Auto-generated method stub
Intent intent = new Intent(BindTenGPS.this, ShowGPS.class);
intent.putExtra("DeviceList", rowTenDevice.get(position).getDeviceName());
startActivity(intent);
}
});
Log.w("Data:","E4");
}
});
} catch (Exception e)
{
Log.w("Error connection","shyam" + e.getMessage());
e.printStackTrace();
}
this.wait(500);
publishProgress(100);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values)
{
//set the current progress of the progress dialog
progressDialog.setProgress(values[0]);
}
//after executing the code in the thread
#Override
protected void onPostExecute(Void result)
{
//close the progress dialog
progressDialog.dismiss();
//initialize the View
//setContentView(R.layout.list1_main);
}
}
}
BaseAdapter
public class BindTenDeviceBaseAdapter extends BaseAdapter implements Filterable {
Context context;
List<RowTenDevice> rowTenDevice;
List<RowTenDevice> arrayList; //temporary list to store filtered values.
LayoutInflater inflater;
public BindTenDeviceBaseAdapter(Context context, List<RowTenDevice> items) {
this.context = context;
this.rowTenDevice = items;
this.arrayList = items;
inflater = LayoutInflater.from(context);
}
private class ViewHolder {
TextView txtTenDevice;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return arrayList.indexOf(getItem(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_tendevice, null);
holder = new ViewHolder();
holder.txtTenDevice = (TextView) convertView.findViewById(R.id.tvTenDevice);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
RowTenDevice rowItem = (RowTenDevice) getItem(position);
holder.txtTenDevice.setText(rowItem.getDeviceName());
return convertView;
}
#Override
public Filter getFilter() {
// TODO Auto-generated method stub
Filter filter = new Filter() {
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// TODO Auto-generated method stub
arrayList = (List<RowTenDevice>) results.values; // has the filtered values
notifyDataSetChanged();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
// TODO Auto-generated method stub
FilterResults results = new FilterResults();
List<RowTenDevice> FilteredArrList = new ArrayList<RowTenDevice>();
if (rowTenDevice == null) {
rowTenDevice = new ArrayList<RowTenDevice>(arrayList); // saves the original data in rowTenDevice
}
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = rowTenDevice.size();
results.values = rowTenDevice;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < rowTenDevice.size(); i++) {
RowTenDevice data = rowTenDevice.get(i);
if(data.getDeviceName().toLowerCase().contains(constraint.toString())) {
FilteredArrList.add(data);
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
RowTenDevice
public class RowTenDevice {
private String devicename;
public RowTenDevice(String devicename) {
this.devicename = devicename;
}
public String getDeviceName() {
return devicename;
}
public void setDeviceName(String devicename) {
this.devicename = devicename;
}
}
In onItemClick you are using rowTenDevice.get(position).getDeviceName(). This causes the problem. You need filtered item so create a public method in adapter to get arrayList.get(position).getDeviceName(). As arrayList is filtered list, it will give you required result.
Use following code:-
Replace line :- intent.putExtra("DeviceList", rowTenDevice.get(position).getDeviceName());
With
intent.putExtra("DeviceList", ((RowTenDevice)adapter.getItem(position)).getDeviceName());
i have a list view which has check box on each row and i`ve implemented a serch view to search in the list view. the problem is that when i search the list view and select item at postion X from the modifided list, delete the text from the search view i see the original list with the item checked in position X.
Example - list of a,b,c....z .
i can see 5 items on the list:
A
B
C
D
E
then search for z so i see only Z and check it. then i delete Z and see A-E again and A is checked.
this is my main:
public class AddRoomatesScreen extends Activity implements AdapterView.OnItemClickListener,SearchView.OnQueryTextListener {
SharedPreferences preferences;
List<String> nameList = new ArrayList<String>();
List<String> phoneList = new ArrayList<String>();
MyAdapter adapter;
Button btnSelect;
String apartmentnumber;
SearchView searchView;
ArrayList<Contact> contactList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_roomate);
preferences = getSharedPreferences("appData", 0);
int apartmentNumber = preferences.getInt("apartmentNumber", 0);
apartmentnumber = Integer.toString(apartmentNumber);
getAllContacts(this.getContentResolver());
ListView lv = (ListView) findViewById(R.id.lv);
adapter = new MyAdapter(nameList,contactList);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
lv.setItemsCanFocus(false);
lv.setTextFilterEnabled(true);
searchView = (SearchView) findViewById(R.id.search_view);
searchView.setOnQueryTextListener(this);
// adding
btnSelect = (Button) findViewById(R.id.addSelectedContacts);
btnSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 0; i<adapter.mCheckStates.size(); i++){
Contact contact = (adapter.contactsListCopy.get(adapter.mCheckStates.keyAt(i)));
new addRoommate().execute(apartmentnumber, contact.getPhoneNumber());
}
preferences = getSharedPreferences("appData", 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("roomatesLoadedFromDB", false);
editor.apply();
}
});
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
adapter.toggle(arg2);
}
public void getAllContacts(ContentResolver cr) {
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
nameList.add(name);
phoneList.add(phoneNumber);
contactList.add(new Contact(name,phoneNumber));
}
phones.close();
}
this is my adapter:
class MyAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener,Filterable {
private SparseBooleanArray mCheckStates;
LayoutInflater mInflater;
TextView tv;
CheckBox cb;
ValueFilter filter;
ArrayList<Contact> contactsList;
ArrayList<Contact> contactsListCopy;
MyAdapter(List<String> nameList , ArrayList<Contact> contactsList) {
mCheckStates = new SparseBooleanArray(contactsList.size());
mInflater = (LayoutInflater) AddRoomatesScreen.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.contactsList = contactsList;
this.contactsListCopy = this.contactsList;
getFilter();
}
#Override
public int getCount() {
return contactsListCopy.size();
}
#Override
public Object getItem(int position) {
return contactsListCopy.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi = convertView;
if (convertView == null)
vi = mInflater.inflate(R.layout.contact_list_item, null);
TextView tv = (TextView) vi.findViewById(R.id.textView3);
cb = (CheckBox) vi.findViewById(R.id.checkBox);
Contact contact = contactsListCopy.get(position);
tv.setText(contact.getName());
cb.setTag(position);
cb.setChecked(mCheckStates.get(position, false));
cb.setOnCheckedChangeListener(this);
return vi;
}
public boolean isChecked(int position) {
return mCheckStates.get(position, false);
}
public void setChecked(int position, boolean isChecked) {
mCheckStates.put(position, isChecked);
notifyDataSetChanged();
}
public void toggle(int position) {
setChecked(position, !isChecked(position));
}
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mCheckStates.put((Integer) buttonView.getTag(), isChecked);
}
#Override
public Filter getFilter() {
if (filter == null){
filter = new ValueFilter();
}
return filter;
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Contact> temp = new ArrayList<Contact>();
for (int i = 0; i < contactList.size(); i++) {
Contact c = contactList.get(i);
if ((c.getName().toString())
.contains(constraint.toString())) {
temp.add(c);
}
}
results.count = temp.size();
results.values = temp;
} else {
results.count = contactList.size();
results.values = contactList;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
contactsListCopy = (ArrayList<Contact>) results.values;
notifyDataSetChanged();
}
}
}
this is my model:
public class Contact{
private String phoneNumber;
private String name;
public Contact(String name , String phoneNumber){
this.phoneNumber = phoneNumber;
this.name = name;
}
public String getName() {
return name;
}
public String getPhoneNumber() {
return phoneNumber;
}
}
EDIT:
You can use the ID from the cursor as your unique id.
This code would go with the code originally posted below.
Add id to your Contact class:
public class Contact{
private long id;
private String phoneNumber;
private String name;
public Contact(long id, String name , String phoneNumber) {
this.id = id;
this.phoneNumber = phoneNumber;
this.name = name;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getPhoneNumber() {
return phoneNumber;
}
}
This is how you get the ID from the cursor:
public void getAllContacts(ContentResolver cr) {
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phones.moveToNext()) {
long id = phones.getLong(phones.getColumnIndex(ContactsContract.Data._ID));
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
nameList.add(name);
phoneList.add(phoneNumber);
contactList.add(new Contact(id, name, phoneNumber));
}
phones.close();
}
Your mCheckStates in the adapter changes to:
private LongSparseArray<Boolean> mCheckStates;
Some of the original answer below has been changed to match the long type used for id.
The problem is that your mCheckStates boolean map isn't kept in sync with contactsListCopy as it is filtered.
You filtered on Z so Z is now item 0,
You checked Z which sets position 0 as checked,
You redisplay the whole list. Now A is position 0 so it shows as checked.
Instead of tracking checked positions, you need to track checked contacts. To do that, you need to use the unique ID from the contact record.
Here's the changes you need to make:
Make your adapter use the unique id:
#Override
public long getItemId(int position) {
return contactsListCopy.get(position).getId();
}
Now your activity has to use the unique id instead of position:
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
adapter.toggle(arg3);
}
In your adapter getView(), you have to use the ID for the check box now
cb.setTag(contact.getId());
cb.setChecked(mCheckStates.get(contact.getId(), false));
I would change some other methods just to avoid confusion:
public boolean isChecked(long id) {
return mCheckStates.get(id, false);
}
public void setChecked(long id, boolean isChecked) {
mCheckStates.put(id, isChecked);
notifyDataSetChanged();
}
public void toggle(long id) {
setChecked(id, !isChecked(id));
}
I am trying to apply filter on my custom adapter which extends BaseAdapter, in which I am facing some problems, after I filter input based on the text in EditText and check the CheckBox to select one value and if I erase the text in the EditText to search for some other thing the position of the checked checkbox changes.
MainActivty
public class MainActivity extends Activity implements OnItemClickListener {
EditText searchText;
ArrayList<String> phno0 = new ArrayList<String>();
List<String> arrayListNames;
// private ListView listview;
// private EditText edittext;
public List<ProfileBean> list;
public SearchableAdapter adapter;
ProfileBean bean;
String[] cellArray = null;
String contacts;
ListView lv;
String phoneNumber, name;
// StringBuilder b = new StringBuilder();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
ColorDrawable colorDrawable = new ColorDrawable(
Color.parseColor("#00aef0"));
actionBar.setBackgroundDrawable(colorDrawable);
setContentView(R.layout.get);
// mStatusView = (TextView) findViewById(R.id.text1);
searchText = (AutoCompleteTextView) findViewById(R.id.autocomplete);
lv = (ListView) findViewById(R.id.listview);
list = new ArrayList<ProfileBean>();
getAllCallLogs(this.getContentResolver());
adapter = new SearchableAdapter(getApplicationContext(), list);
lv.setAdapter(adapter);
lv.setItemsCanFocus(false);
lv.setOnItemClickListener(this);
lv.setTextFilterEnabled(true);
contacts = SmsSend.contacts;
if (SmsSend.contacts != null) {
cellArray = contacts.split(";");
//contacts=null;
// Toast.makeText(getApplication(), contacts.toString(),
// Toast.LENGTH_LONG).show();
for (int i = 0; i < cellArray.length; i++) {
for (int j = 0; j < list.size(); j++) {
if (cellArray[i].equals(list.get(j).getNumber())) {
adapter.setChecked(j, true);
// break;
}
}
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
getMenuInflater().inflate(R.menu.contact_main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case android.R.id.home:
//StringBuilder checkedcontacts = new StringBuilder();
// System.out.println(".............." +
// adapter.mCheckStates.size());
for (int i = 0; i < list.size(); i++)
{
if (adapter.mCheckStates.get(i) == true) {
phno0.add(list.get(i).getNumber());
//checkedcontacts.append(list.get(i).toString());
// checkedcontacts.append("\n");
// Toast.makeText(getApplicationContext(),
// list.get(i).getNumber().toString(),
// Toast.LENGTH_LONG).show();
} else {
System.out.println("..Not Checked......"
+ list.get(i).getNumber().toString());
}
}
Intent returnIntent = new Intent();
returnIntent.putStringArrayListExtra("name", phno0);
setResult(RESULT_OK, returnIntent);
finish();
break;
case R.id.addPage:
break;
case R.id.action_search:
searchText.setVisibility(View.VISIBLE);
searchText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s.toString());
}
});
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
phno0.clear();
//StringBuilder checkedcontacts = new StringBuilder();
// System.out.println(".............." + adapter.mCheckStates.size());
for (int i = 0; i < list.size(); i++)
{
if (adapter.mCheckStates.get(i) == true) {
phno0.add(list.get(i).getNumber());
} else {
System.out.println("..Not Checked......"
+ list.get(i).getNumber().toString());
}
}
Intent returnIntent = new Intent();
returnIntent.putStringArrayListExtra("name", phno0);
setResult(RESULT_OK, returnIntent);
finish();
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long id) {
// TODO Auto-generated method stub
adapter.toggle(position);
}
public void getAllCallLogs(ContentResolver cr) {
Cursor phones = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
+ " ASC");
while (phones.moveToNext()) {
phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
list.add(new ProfileBean(name, phoneNumber));
}
phones.close();
}
}
SearchableAdapter
public class SearchableAdapter extends BaseAdapter implements Filterable, OnCheckedChangeListener {
public SparseBooleanArray mCheckStates;
private List<ProfileBean>originalData = null;
private List<ProfileBean>filteredData = null;
private LayoutInflater mInflater;
private ItemFilter mFilter = new ItemFilter();
public SearchableAdapter(Context context, List<ProfileBean> data) {
//mCheckStates = new SparseBooleanArray(filteredData.size());
mCheckStates = new SparseBooleanArray(data.size());
this.filteredData = data ;
this.originalData = data ;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return filteredData.size();
}
public Object getItem(int position) {
return filteredData.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.textView1);
holder.number = (TextView) convertView.findViewById(R.id.textView2);
holder.chk = (CheckBox) convertView.findViewById(R.id.checkBox1);
holder.chk.setTag(position);
convertView.setTag(R.layout.row,holder);
} else {
holder = (ViewHolder) convertView.getTag(R.layout.row);
}
holder.chk.setOnCheckedChangeListener(null);
holder.chk.setOnCheckedChangeListener(this);
ProfileBean bean = filteredData.get(position);
holder.name.setText(bean.getName());
holder.number.setText(bean.getNumber());
convertView.setTag(bean);
return convertView;
}
static class ViewHolder {
TextView name;
TextView number;
CheckBox chk;
}
public boolean isChecked(int position) {
return mCheckStates.get(position, false);
}
public void setChecked(int position, boolean isChecked) {
mCheckStates.put(position, isChecked);
}
public void toggle(int position) {
setChecked(position, !isChecked(position));
}
public Filter getFilter() {
return mFilter;
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<ProfileBean> list = originalData;
int count = list.size();
final ArrayList<ProfileBean> nlist = new ArrayList<ProfileBean>(count);
String filterableString ;
for (int i = 0; i < count; i++) {
ProfileBean bean = list.get(i);
filterableString = bean.getName();
if (filterableString.toLowerCase().contains(filterString.toString().toLowerCase())) {
nlist.add(bean);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredData = (ArrayList<ProfileBean>) results.values;
notifyDataSetChanged();
}
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
mCheckStates.put((Integer) buttonView.getTag(), isChecked);
}
}
ProfileBean Class
public class ProfileBean {
private String name;
private String number;
//private boolean checked = false ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public ProfileBean(String name, String number) {
super();
this.name = name;
this.number = number;
}
}
Change your Adapter like this..
public class SearchableAdapter extends BaseAdapter implements Filterable,
OnCheckedChangeListener {
public SparseBooleanArray mCheckStates;
private List<ProfileBean> originalData = null;
private List<ProfileBean> filteredData = null;
private LayoutInflater mInflater;
private ItemFilter mFilter = new ItemFilter();
public SearchableAdapter(Context context, List<ProfileBean> data) {
// mCheckStates = new SparseBooleanArray(filteredData.size());
mCheckStates = new SparseBooleanArray(data.size());
this.filteredData = data;
this.originalData = data;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return filteredData.size();
}
public Object getItem(int position) {
return filteredData.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.textView1);
holder.number = (TextView) convertView.findViewById(R.id.textView2);
holder.chk = (CheckBox) convertView.findViewById(R.id.checkBox1);
holder.chk.setTag(position);
convertView.setTag(R.layout.row, holder);
} else {
holder = (ViewHolder) convertView.getTag(R.layout.row);
}
ProfileBean bean = filteredData.get(position);
holder.name.setText(bean.getName());
holder.number.setText(bean.getNumber());
holder.chk.setOnCheckedChangeListener(null);
holder.chk.setChecked(bean.isChecked);
holder.chk.setOnCheckedChangeListener(this);
convertView.setTag(bean);
return convertView;
}
static class ViewHolder {
TextView name;
TextView number;
CheckBox chk;
}
public void toggle(int position) {
ProfileBean bean = filteredData.get(position);
bean.isChecked = !bean.isChecked;
}
public android.widget.Filter getFilter() {
return mFilter;
}
private class ItemFilter extends android.widget.Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<ProfileBean> list = originalData;
int count = list.size();
final ArrayList<ProfileBean> nlist = new ArrayList<ProfileBean>(
count);
String filterableString;
for (int i = 0; i < count; i++) {
ProfileBean bean = list.get(i);
filterableString = bean.getName();
if (filterableString.toLowerCase().contains(
filterString.toString().toLowerCase())) {
nlist.add(bean);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
filteredData = (ArrayList<ProfileBean>) results.values;
notifyDataSetChanged();
}
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
int position = (Integer) buttonView.getTag();
ProfileBean profileBean = filteredData.get(position);
profileBean.isChecked = isChecked;
// mCheckStates.put((Integer) buttonView.getTag(), isChecked);
}
}
and your bean class like..
public class ProfileBean {
private String name;
private String number;
public boolean isChecked;
// private boolean checked = false ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public ProfileBean(String name, String number) {
super();
this.name = name;
this.number = number;
}
}
And keep remaining same..try like this and let know if any problem..
Change your onBkpress method like this..
#Override
public void onBackPressed() {
phno0.clear();
for (ProfileBean bean : list) {
if (bean.isChecked) {
phno0.add(bean.getNumber());
} else {
System.out.println("..Not Checked......"
+ list.get(i).getNumber().toString());
}
}
Intent returnIntent = new Intent();
returnIntent.putStringArrayListExtra("name", phno0);
setResult(RESULT_OK, returnIntent);
finish();
}
i want to get the contact numbers in a string when user checked the contact,after which onBackpress the selected values can be stored in database.user can select multiple contacts at a time and when user returns back on the activity,the check box remains checked, so that he can see his selected contacts.
MainActivity
public class MainActivity extends Activity {
String[] cellArray = null;
String contacts;
String phoneNumber, name;
ArrayList<String> phno0 = new ArrayList<String>();
StringBuilder b = new StringBuilder();
//private ArrayAdapter<String> adapter;
List<String> arrayListNames;
private ListView listview;
private EditText edittext;
private List<ProfileBean> list;
private SearchableAdapter adapter ;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listview);
edittext = (EditText) findViewById(R.id.edittext);
list = new ArrayList<ProfileBean>();
getAllCallLogs(this.getContentResolver());
adapter = new SearchableAdapter(getApplicationContext(), list);
listview.setAdapter(adapter);
edittext.addTextChangedListener(new TextWatcher(){
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
});
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
ProfileBean bean = (ProfileBean) arg1.getTag();
Toast.makeText(getApplicationContext(), bean.getName(), Toast.LENGTH_LONG).show();
}
});
}
public void getAllCallLogs(ContentResolver cr) {
Cursor phones = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
+ " ASC");
while (phones.moveToNext()) {
phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
list.add(new ProfileBean(name, phoneNumber));
}
}
}
Adapterclass
public class SearchableAdapter extends BaseAdapter implements Filterable, OnCheckedChangeListener {
private List<ProfileBean>originalData = null;
private List<ProfileBean>filteredData = null;
private LayoutInflater mInflater;
private ItemFilter mFilter = new ItemFilter();
public SearchableAdapter(Context context, List<ProfileBean> data) {
//mCheckStates = new SparseBooleanArray(filteredData.size());
this.filteredData = data ;
this.originalData = data ;
mInflater = LayoutInflater.from(context);
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.lname = (TextView) convertView.findViewById(R.id.lname);
holder.no = (CheckBox) convertView.findViewById(R.id.no);
holder.no.setTag(position);
holder.no.setOnCheckedChangeListener(this);
convertView.setTag(R.layout.list_item,holder);
} else {
holder = (ViewHolder) convertView.getTag(R.layout.list_item);
}
ProfileBean bean = filteredData.get(position);
holder.name.setText(bean.getName());
holder.lname.setText(bean.getLname());
convertView.setTag(bean);
return convertView;
}
static class ViewHolder {
TextView name;
TextView lname;
CheckBox no;
}
public Filter getFilter() {
return mFilter;
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<ProfileBean> list = originalData;
int count = list.size();
final ArrayList<ProfileBean> nlist = new ArrayList<ProfileBean>(count);
String filterableString ;
for (int i = 0; i < count; i++) {
ProfileBean bean = list.get(i);
filterableString = bean.getName();
if (filterableString.toLowerCase().contains(filterString)) {
nlist.add(bean);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
BeanClass
package com.example.mylistviewtest;
public class ProfileBean {
private String name;
private String lname;
private boolean checked = false ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public ProfileBean(String name, String lname) {
super();
this.name = name;
this.lname = lname;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public void toggleChecked() {
checked = !checked ;
}
}
I have a problem in making suggestion in AutoCompleteTextView in this pattern
[action actionFromContact] (these are 2 adapter) ex call michael (where "call" comes from action adapter , "michael" from actionFromContact adapter these following code does first it set adapter in AutoCompleteTextView to item and when text changes to call it reset to contact db from name so its like call michael ,
Problem item array is too big so I can't use replace thing , second replacing remove the first entry when second entry i.e name is been selected from drop down menu as its been replaced by space
private AutoCompleteTextView mEditText;
private TextWatcher mTextWatcher;
private ContactPickerAdapter contactPickerAdapter;
String item[] = { "Call", "Call back"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = (WithSomeOneAutoCompleteTextView) findViewById(R.id.editTextTest);
contactPickerAdapter = new ContactPickerAdapter(this,
android.R.layout.simple_dropdown_item_1line,
ContactQuery.getContacts(this, false));
mEditText.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, item));
mTextWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
String t = s.toString().replace("call ",");
contactPickerAdapter.getFilter().filter(t);
if (s.toString().equalsIgnoreCase("call ")) {
Toast.makeText(MainActivity.this, "CALL",
Toast.LENGTH_SHORT).show();
mEditText.setAdapter(contactPickerAdapter);
}
if (s.toString().equalsIgnoreCase("Call back")) {
// t.replace("call back ", "");
// System.out.println("t is: " + t);
// contactPickerAdapter.getFilter().filter(t);
Toast.makeText(MainActivity.this, "Launch",
Toast.LENGTH_SHORT).show();
}
}
};
}
This is ContactPickerAdapter
public class ContactPickerAdapter extends ArrayAdapter<Contact> implements
Filterable {
private ArrayList<Contact> contactList, cloneContactList;
private LayoutInflater layoutInflater;
private Context mContext;
public ContactPickerAdapter(Context context, int textViewResourceId,
ArrayList<Contact> contactList) {
super(context, textViewResourceId);
this.contactList = contactList;
this.cloneContactList = (ArrayList<Contact>) this.contactList.clone();
layoutInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return contactList.size();
}
#Override
public Contact getItem(int position) {
return contactList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(
R.layout.withsomeone_contact_list_item, null);
holder = new Holder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.phone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Contact contact = getItem(position);
holder.name.setText(contact.contactName);
holder.phone.setText(contact.num);
return convertView;
}
#Override
public Filter getFilter() {
Filter contactFilter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results.values != null) {
contactList = (ArrayList<Contact>) results.values;
notifyDataSetChanged();
}
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
// CharSequence t = "";
System.out.println("contraints is equal: " + constraint);
// if (constraint.toString().contains("call ")) {
// // constraint = "";
// System.out.println("contraints now: "
// + constraint.toString().replace("call ", ""));
// t = constraint.toString().replace("call ", "");
// }
// } else if
// (constraint.toString().equalsIgnoreCase("call back ")) {
// // constraint = "";
// System.out.println("contraints now: " + constraint);
// t = constraint.toString().replace("call back ", "");
//
// }
// System.out.println("clone is equal: " + t);
String sortValue = constraint == null ? "" : constraint
.toString().toLowerCase();
FilterResults filterResults = new FilterResults();
if (!TextUtils.isEmpty(sortValue.trim())) {
ArrayList<Contact> sortedContactList = new ArrayList<Contact>();
for (Contact contact : cloneContactList) {
if (contact.contactName.toLowerCase().contains(
sortValue)
|| contact.num.toLowerCase()
.contains(sortValue))
sortedContactList.add(contact);
}
filterResults.values = sortedContactList;
filterResults.count = sortedContactList.size();
}
return filterResults;
}
#Override
public CharSequence convertResultToString(Object resultValue) {
// need to save this to saved contact
return ((Contact) resultValue).contactName;
}
};
return contactFilter;
}
#SuppressWarnings("unchecked")
public void setContactList(ArrayList<Contact> contactList) {
// this isn't the efficient method
// need to improvise on this
this.contactList = contactList;
this.cloneContactList = (ArrayList<Contact>) this.contactList.clone();
notifyDataSetChanged();
}
public static class Holder {
public TextView phone, name;
}
Still a bit unclear what are you trying to achieve.
Anyway.
Well as a first step I would attach the TextWatcher to the mEditText
mEditText.addTextChangedListener(mTextWatcher);
Then I would remove
contactPickerAdapter.getFilter().filter(t);
see how it goes.
I suggest that you post the code of your contactPickerAdapter as well.