2016-01-22 51 views
1

我正在做一個應用程序,我顯示從設備到ListView(名稱,編號,圖像)的所有聯繫人。我想使用工具欄搜索從ListView中搜索聯繫人。我添加了搜索工具欄,但我不知道如何從列表中篩選聯繫人。請任何人幫助我。我使用了this example來在ListView中顯示聯繫人。Listview聯繫人從工具欄搜索過濾

+0

它會hlp你:http://www.androidbegin.com/tutorial/android-search-listview-using-filter/ –

+0

我放了一個編輯文本,我試過了,但它沒有爲我工作...我想從工具欄搜索搜索.. – Yamuna

+0

你可以分享你的代碼你試試! –

回答

2

試試下面的代碼它做工精細:

創建MainActivity.class:

package app.personal.sampleapp; 

import android.content.ContentResolver; 
import android.database.Cursor; 
import android.graphics.Bitmap; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.provider.ContactsContract; 
import android.provider.MediaStore; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.SearchView; 
import android.support.v7.widget.Toolbar; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.ListView; 
import android.widget.ProgressBar; 
import java.io.ByteArrayOutputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, SearchView.OnQueryTextListener { 

protected Toolbar toolbar; 
private String id, name, phone, image_uri; 
private byte[] contactImage = null; 
private Bitmap bitmap; 
private int queryLength; 
private List<ContactItem> contactItems; 
private ListView listView; 
private ProgressBar progressBar; 
private ContactAdapter adapter; 
private SearchView searchView; 
private MenuItem searchMenuItem; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    init(); 
    new ContactInfo().execute(); 

} 

private void init() { 
    toolbar = (Toolbar) findViewById(R.id.tool_bar); 
    setSupportActionBar(toolbar); 
    listView = (ListView) findViewById(R.id.contact_list); 
    progressBar = (ProgressBar) findViewById(R.id.progress_bar); 
} 


private void readContacts() { 
    contactItems = new ArrayList<>(); 
    ContentResolver cr = getApplicationContext().getContentResolver(); 
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, 
      null, null, null); 
    if (cur.getCount() > 0) { 
     while (cur.moveToNext()) { 
      ContactItem item = new ContactItem(); 
      id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); 
      name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
      name = Character.toUpperCase(name.charAt(0)) + name.substring(1); 
      image_uri = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI)); 
      if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) { 
       Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
         ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); 
       while (pCur.moveToNext()) { 
        phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
        phone = phone.replaceAll("\\s+", ""); 
        phone = phone.replaceAll("[^0-9]", ""); 
       } 
       pCur.close(); 
      } 
      if (image_uri != null) { 
       try { 
        bitmap = MediaStore.Images.Media 
          .getBitmap(getApplicationContext().getContentResolver(), 
            Uri.parse(image_uri)); 
        contactImage = getImageBytes(bitmap); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } else { 
       contactImage = null; 
      } 
      item.setId(id); 
      item.setName(name); 
      item.setContactImage(contactImage); 
      item.setPhone(phone); 
      contactItems.add(item); 
     } 
    } 
} 

private byte[] getImageBytes(Bitmap bitmap) { 
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 
    return outputStream.toByteArray(); 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu_search, menu); 
    searchView = (SearchView) menu.findItem(R.id.search).getActionView(); 
    searchMenuItem = menu.findItem(R.id.search); 
    searchView.setQueryHint(getResources().getString(R.string.type_here)); 
    searchView.setOnQueryTextFocusChangeListener(this); 
    searchView.setOnQueryTextListener(this); 
    return super.onCreateOptionsMenu(menu); 

} 

@Override 
public void onClick(View v) { 

} 

@Override 
public void onFocusChange(View v, boolean hasFocus) { 
    if (!hasFocus) { 
     searchMenuItem.collapseActionView(); 
     searchView.setQuery("", false); 
    } 
} 

@Override 
public boolean onQueryTextSubmit(String query) { 
    return false; 
} 

@Override 
public boolean onQueryTextChange(String newText) { 
    queryLength = newText.length(); 
    adapter.getFilter().filter(newText); 
    return false; 
} 

public class ContactInfo extends AsyncTask<Void, Void, Void> { 


    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     progressBar.setVisibility(View.VISIBLE); 
     listView.setVisibility(View.GONE); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     readContacts(); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     progressBar.setVisibility(View.GONE); 
     listView.setVisibility(View.VISIBLE); 
     setListAdapter(); 
    } 
} 

private void setListAdapter() { 
    adapter = new ContactAdapter(getApplicationContext(), contactItems); 
    listView.setAdapter(adapter); 
} 
} 

創建customAdapter類:

import android.widget.Filter; 
import android.widget.Filterable; 
import android.widget.ImageView; 
import android.widget.TextView; 
import java.util.ArrayList; 
import java.util.List; 

public class ContactAdapter extends ArrayAdapter<ContactItem> implements Filterable { 

private Context context; 
private List<ContactItem> contacts, filterList; 
private LayoutInflater inflater; 
private ContactFilter filter; 

public ContactAdapter(Context context, List<ContactItem> contacts) { 
    super(context, R.layout.contact_row, contacts); 
    this.contacts = contacts; 
    this.context = context; 
    filterList = new ArrayList<>(); 
    this.filterList.addAll(contacts); 
} 


@Override 
public Filter getFilter() { 
    if (filter == null) 
     filter = new ContactFilter(); 
    return filter; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View view; 
    ViewHolder viewHolder = new ViewHolder(); 
    if (convertView == null) { 
     inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = inflater.inflate(R.layout.contact_row, parent, false); 
    } else { 
     view = convertView; 
    } 
    viewHolder.name = (TextView) view.findViewById(R.id.name); 
    viewHolder.photo = (ImageView) view.findViewById(R.id.photo); 
    viewHolder.number = (TextView) view.findViewById(R.id.phone); 
    viewHolder.name.setText(contacts.get(position).getName()); 
    viewHolder.number.setText(contacts.get(position).getPhone()); 
    if ((contacts.get(position).getContactImage()) != null) { 
     Bitmap contactImage = getContactImage(contacts.get(position).getContactImage()); 
     viewHolder.photo.setImageBitmap(contactImage); 
    }else { 
     viewHolder.photo.setImageResource(R.drawable.dummy_icon); 
    } 
    return view; 
} 

private Bitmap getContactImage(byte[] photo) { 
    int targetW = 50, targetH = 50; 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    BitmapFactory.decodeByteArray(photo, 0, photo.length, options); 
    options.inJustDecodeBounds = true; 
    int imageW = options.outWidth; 
    int imageH = options.outHeight; 
    int scaleFactor = 1; 
    if ((targetW > 0) || (targetH > 0)) { 
     scaleFactor = Math.min(imageW/targetW, imageH/targetH); 
    } 
    options.inJustDecodeBounds = false; 
    options.inSampleSize = scaleFactor; 
    options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
    return BitmapFactory.decodeByteArray(photo, 0, photo.length, options); 
} 


public class ViewHolder { 
    ImageView photo; 
    TextView name, number; 
} 

private class ContactFilter extends Filter { 

    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
     String data = constraint.toString().toLowerCase(); 
     FilterResults results = new FilterResults(); 
     if (data.length() > 0) { 
      List<ContactItem> filteredList = new ArrayList<>(filterList); 
      List<ContactItem> nList = new ArrayList<>(); 
      int count = filteredList.size(); 
      for (int i = 0; i < count; i++) { 
       ContactItem item = filteredList.get(i); 
       String name = item.getName().toLowerCase(); 
       String phone = item.getPhone().toLowerCase(); 
       if (name.startsWith(data) || phone.startsWith(data)) 
        nList.add(item); 
      } 
      results.count = nList.size(); 
      results.values = nList; 
     } else { 
      List<ContactItem> list = new ArrayList<>(filterList); 
      results.count = list.size(); 
      results.values = list; 
     } 
     return results; 
    } 

    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     contacts = (ArrayList<ContactItem>) results.values; 
     clear(); 
     for (int i = 0; i < contacts.size(); i++) { 
      ContactItem item = (ContactItem) contacts.get(i); 
      add(item); 
      notifyDataSetChanged(); 
     } 
    } 
} 

@Override 
public void notifyDataSetChanged() { 
    super.notifyDataSetChanged(); 
} 
} 

創建POJO類

public class ContactItem { 
private String id, name, phone; 
private byte[] contactImage = null; 

public String getId() { 
    return id; 
} 

public void setId(String id) { 
    this.id = id; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public String getPhone() { 
    return phone; 
} 

public void setPhone(String phone) { 
    this.phone = phone; 
} 

public byte[] getContactImage() { 
    return contactImage; 
} 

public void setContactImage(byte[] contactImage) { 
    this.contactImage = contactImage; 
} 
} 

創建MainActivity.xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" 
tools:context=".MainActivity"> 

<FrameLayout 
    android:id="@+id/frame_toolbar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="true"> 

    <include 
     android:id="@+id/tool_bar" 
     layout="@layout/toolbar" /> 
</FrameLayout> 

<ListView 
    android:id="@+id/contact_list" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_below="@+id/frame_toolbar" 
    android:cacheColorHint="@android:color/transparent" 
    android:clipToPadding="false" 
    android:divider="@null" 
    android:dividerHeight="1dp" 
    android:listSelector="@android:color/transparent" /> 

<ProgressBar 
    android:id="@+id/progress_bar" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerInParent="true" /> 

</RelativeLayout> 

創建行項目佈局文件:

<?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:layout_gravity="center" 
android:background="#FFF" 
android:orientation="horizontal"> 

<ImageView 
    android:id="@+id/photo" 
    android:layout_width="50dp" 
    android:layout_height="50dp" /> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center_vertical" 
    android:orientation="horizontal" 
    android:weightSum="1"> 

    <LinearLayout 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical" 
     android:layout_weight="1" 
     android:orientation="vertical"> 

     <TextView 
      android:id="@+id/name" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center_vertical" 
      android:layout_marginLeft="15dp" 
      android:textColor="#000000" 
      android:textSize="16sp" 
      android:textStyle="bold" /> 

     <TextView 
      android:id="@+id/phone" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center_vertical" 
      android:layout_marginLeft="15dp" 
      android:layout_marginTop="5dp" 
      android:textColor="#000000" 
      android:textSize="14sp" /> 
    </LinearLayout> 
</LinearLayout> 
</LinearLayout> 

創建佈局文件夾toolbar.xml:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:layout_width="match_parent" 
android:layout_height="50dp" 
android:background="#f57c00" 
app:theme="@style/ThemeOverlay.AppCompat.Dark" /> 

創建菜單文件夾menu_search.xml:

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto"> 
<item 
    android:id="@+id/search" 
    android:icon="@drawable/search" 
    android:title="@string/search_view" 
    app:actionViewClass="android.support.v7.widget.SearchView" 
    app:showAsAction="collapseActionView|always" /> 
</menu> 

添加以下代碼style.xml文件:

<style name="NoActionBar" parent="Theme.AppCompat.Light.NoActionBar"> 
    <item name="actionOverflowMenuStyle">@style/PopupMenu</item> 
</style> 
<style name="PopupMenu" parent="Widget.AppCompat.PopupMenu.Overflow"> 
    <item name="android:textColor">#FFF</item> 
</style> 

添加以下代碼在AndroidManifest.xml:

android:theme="@style/NoActionBar" // add in application theme 

<uses-permission android:name="android.permission.READ_CONTACTS" /> 
<uses-permission android:name="android.permission.WRITE_CONTACTS" />