问题
have an ArrayAdapter with two TextView.
when set it to ListView it is working correctly but when I sort it,
it sorts according to name but TextView which holds number doesn't change their position accordingly.
and if I don't apply sort and try to filter name with number then show only initial contacts rather show the contact which I want.
This is my custom adapter:-
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class CustomListAdapter extends ArrayAdapter<String>{
private final Activity context;
private final String[] name;
private final String[] number;
public CustomListAdapter(Activity context, String[] name, String[] number) {
super(context, R.layout.name_num_list, name);
this.context=context;
this.name=name;
this.number=number;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.name_num_list, null, true);
TextView txt_name = (TextView) rowView.findViewById(R.id.txt_name);
txt_name.setText(name[position]);
TextView txt_num= (TextView) rowView.findViewById(R.id.txt_number);
txt_num.setText(number[position]);
return rowView;
}
}
this is my list activity....
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.hardware.Camera;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
public class ContactListActivity extends Activity implements OnItemClickListener{
String phoneNumber;
String name;
String[] namePerson;
String[] phoneNumberP;
ListView lv;
EditText searchContact;
CustomListAdapter customAdapter;
ArrayList <String> aa= new ArrayList<String>();
ArrayList <String> aa1= new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_list);
searchContact=(EditText) findViewById(R.id.EditText_contact_search);
lv= (ListView) findViewById(R.id.lv);
getNumber(this.getContentResolver());
lv.setOnItemClickListener(this);
searchContact();
}
public void getNumber(ContentResolver cr)
{
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
aa.add(name);
aa1.add(phoneNumber);
}
phones.close();// close cursor
phoneNumberP=aa1.toArray(new String[aa1.size()]);
namePerson=aa.toArray(new String[aa.size()]);
customAdapter= new CustomListAdapter(ContactListActivity.this, namePerson, phoneNumberP);
customAdapter.sort(new Comparator<String>() {
@Override
public int compare(String arg1, String arg0) {
return arg1.compareTo(arg0);
}
});
customAdapter.notifyDataSetChanged();
lv.setAdapter(customAdapter);
}
@Override
public void onItemClick(AdapterView<?> av, View v, int pos, long arg3) {
}
private void searchContact() {
lv.setTextFilterEnabled(true);
searchContact.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
{
}
@Override
public void beforeTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
{
}
@Override
public void afterTextChanged( Editable name)
{
ContactListActivity.this.customAdapter.getFilter().filter(name);
customAdapter.notifyDataSetChanged();
}
});
}
}
my xmls are...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/txt_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
<TextView
android:id="@+id/txt_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
</LinearLayout>
and for list
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/preview6" >
<LinearLayout
android:id="@+id/main_ll_contactlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/bg_black">
<EditText
android:id="@+id/EditText_contact_search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:drawableLeft="@android:drawable/ic_menu_search"
android:hint="Search"
android:textColor="@android:color/white"
android:typeface="serif"
android:textSize="20sp"
android:focusableInTouchMode="true"
android:background="@android:color/transparent" >
</EditText>
<ListView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/lv"
android:background="@android:color/transparent"
/>
</LinearLayout>
</FrameLayout>
I take FrameLayout for my other works.
if any other idea then suggest me.
回答1:
Here is the problem :
you try to maintain two arrays in your custom adapter : name[] and number[], however ArrayAdapter is designed to keep track of single array / list.
When you sort items with customAdapter.sort
it will sort name array only and your number array will remain intact, thus numbers will be displayed at original positions, no matter how you sort names.
What you need is to maintain mapping between your name and number variables. You could use a HashMap for that. Another simple solution to bind them is to have your item as
class Item {
String name;
String number;
}
initialize your adapter with array Item[]; and sort this array by supplying custom comparator :
customAdapter.sort(new Comparator<Item>() {
@Override
public int compare(Item arg1, Item arg0) {
return arg1.name.compareTo(arg0.name);
}
});
来源:https://stackoverflow.com/questions/23262445/sorting-and-filtering-listview-with-custom-array-adapter-with-two-textview