Multiple Choice Searchable ListView

前端 未结 2 1923
清歌不尽
清歌不尽 2020-12-18 23:50

OK I have a multiple choice ListView that works fine. I check the boxes for the contacts (held in a String[]) and can return the values fine. Because some people have a bu

相关标签:
2条回答
  • 2020-12-19 00:02

    I never ended up finding a better method than the one I am going to list below. I do not use this code much anymore, and if there is a better solution, I hope someone has it posted somewhere.

    What I ended up doing was creating an ArrayList to hold the selected names. If the name is selected, the name is pushed into the ArrayList, and if it is unchecked, it is popped from the list. When afterTextChanged is selected, the list is iterated through and the names are checked if they are currently listed in the adapter. When you finish with the selection process and want to continue, I clear the EditText to clear the filter, therefore populating the complete list in the ListView and setting all of the contacts to selected if they exist in the ArrayList.

    Note, I use a custom adapter for a list of contacts that only list names, so this solution may get more confusing if you use other types of data, and I look at this method as a hacked solution:

    /** Used for filter **/
    private TextWatcher filterTextWatcher = new TextWatcher() {
    
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
            ListView listview = getListView();
    
            SparseBooleanArray checked = listview.getCheckedItemPositions();
            for (int i = 0; i < ContactsList.length; i++) {
                if (checked.get(i) == true) {
                    Object o = getListAdapter().getItem(i);
                    String name = o.toString();
                    // if the arraylist does not contain the name, add it
                    if (selected.contains(name)){ 
                        // Do Nothing
                    } else {
                        selected.add(name);
                    }
                }
            }           
        } //<-- End of beforeTextChanged
    
        public void onTextChanged(CharSequence s, int start, int before, int count) {           
            adapter.getFilter().filter(s);              
        } //<-- End of onTextChanged
    
        public void afterTextChanged(Editable s) {
            ListView listview = getListView();
            // Uncheck everything:
            for (int i = 0; i < listview.getCount(); i++){
                listview.setItemChecked(i, false);                  
            }
    
            adapter.getFilter().filter(s, new Filter.FilterListener() {
                public void onFilterComplete(int count) {
                    adapter.notifyDataSetChanged();
                    ListView listview = getListView();
                    for (int i = 0; i < adapter.getCount(); i ++) {
                        // if the current (filtered) 
                        // listview you are viewing has the name included in the list,
                        // check the box
                        Object o = getListAdapter().getItem(i);
                        String name = o.toString();
                        if (selected.contains(name)) {
                            listview.setItemChecked(i, true);
                        } else {
                            listview.setItemChecked(i, false);
                        }
                    }
    
                }
            });         
        } //<-- End of afterTextChanged
    
    }; //<-- End of TextWatcher
    

    You don't want to use Indexes when using the filters because index 1 might be something in one ListView, and it might be another ListView item when you change the filter.

    0 讨论(0)
  • 2020-12-19 00:05

    You can create android project and add these files:

    res/layout->list_row.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#3c3c3c"
        android:orientation="horizontal"
        android:padding="8dp" >
        <ImageView
            android:id="@+id/contactimage"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_marginRight="8dp"
            android:background="@drawable/ic_launcher"
            android:contentDescription="@string/app_name"
            android:scaleType="centerInside" />
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_toLeftOf="@+id/contactcheck"
            android:layout_toRightOf="@+id/contactimage" >
            <TextView
                android:id="@+id/contactname"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:text="Contact Name"
                android:textColor="#000"
                android:textIsSelectable="false"
                android:textSize="18dp"
                android:textStyle="bold" />
            <TextView
                android:id="@+id/contactno"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/contactname"
                android:singleLine="true"
                android:text="09876543210"
                android:textColor="#2689e0"
                android:textIsSelectable="false"
                android:textSize="14dp" />
        </RelativeLayout>
        <CheckBox
            android:id="@+id/contactcheck"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerInParent="true"
            android:layout_marginLeft="8dp" />
    </RelativeLayout>
    

    res/layout->activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <EditText
            android:id="@+id/input_search"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerInParent="true"
            android:hint="Search Contacts"
            android:textSize="18dp" />
        <LinearLayout
            android:id="@+id/data_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/ok_button"
            android:layout_below="@+id/input_search"
            android:gravity="center|top"
            android:orientation="vertical" />
        <Button
            android:id="@+id/ok_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerInParent="true"
            android:text=" OK "
            android:textSize="18dp" />
        <RelativeLayout
            android:id="@+id/pbcontainer"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#55000000"
            android:clickable="true"
            android:visibility="gone" >
            <ProgressBar
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true" />
        </RelativeLayout>
    </RelativeLayout>
    

    ContactObject.java

    package com.multiselectlistexample;
    public class ContactObject {
    
        private String contactName;
        private String contactNo;
        private String image;
        private boolean selected;
        public String getName() {
            return contactName;
        }
        public void setName(String contactName) {
            this.contactName = contactName;
        }
        public String getNumber() {
            return contactNo;
        }
        public void setNumber(String contactNo) {
            this.contactNo = contactNo;
        }
        public String getImage() {
            return image;
        }
        public void setImage(String image) {
            this.image = image;
        }
        public boolean isSelected() {
            return selected;
        }
        public void setSelected(boolean selected) {
            this.selected = selected;
        }
    }
    

    ContactsListClass.java

    package com.multiselectlistexample;
    import java.util.ArrayList;
    public class ContactsListClass {
        public static final ArrayList<ContactObject> phoneList = new ArrayList<ContactObject>();
    }
    

    ContactsAdapter.java

    package com.multiselectlistexample;
    import java.io.ByteArrayInputStream;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Locale;
    import android.content.ContentUris;
    import android.content.Context;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.provider.ContactsContract.Contacts;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.CheckBox;
    import android.widget.CompoundButton;
    import android.widget.ImageView;
    import android.widget.TextView;
    public class ContactsAdapter extends BaseAdapter {
        Context mContext;
        LayoutInflater inflater;
        private List<ContactObject> mainDataList = null;
        private ArrayList<ContactObject> arraylist;
        public ContactsAdapter(Context context, List<ContactObject> mainDataList) {
    
            mContext = context;
            this.mainDataList = mainDataList;
            inflater = LayoutInflater.from(mContext);
            this.arraylist = new ArrayList<ContactObject>();
            this.arraylist.addAll(mainDataList);
    
    
        }
        static class ViewHolder {
            protected TextView name;
            protected TextView number;
            protected CheckBox check;
            protected ImageView image;
        }
        @Override
        public int getCount() {
            return mainDataList.size();
        }
        @Override
        public ContactObject getItem(int position) {
            return mainDataList.get(position);
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        public View getView(final int position, View view, ViewGroup parent) {
            final ViewHolder holder;
            if (view == null) {
                holder = new ViewHolder();
                view = inflater.inflate(R.layout.list_row, null);
                holder.name = (TextView) view.findViewById(R.id.contactname);
                holder.number = (TextView) view.findViewById(R.id.contactno);
                holder.check = (CheckBox) view.findViewById(R.id.contactcheck);
                holder.image = (ImageView) view.findViewById(R.id.contactimage);
                view.setTag(holder);
                view.setTag(R.id.contactname, holder.name);
                view.setTag(R.id.contactno, holder.number);
                view.setTag(R.id.contactcheck, holder.check);
                holder.check
                        .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                            @Override
                            public void onCheckedChanged(CompoundButton vw,
                                    boolean isChecked) {
                                int getPosition = (Integer) vw.getTag();
                                mainDataList.get(getPosition).setSelected(
                                        vw.isChecked());
                            }
                        });
            } else {
                holder = (ViewHolder) view.getTag();
            }
            holder.check.setTag(position);
    
            holder.name.setText(mainDataList.get(position).getName());
            holder.number.setText(mainDataList.get(position).getNumber());
    
            if(getByteContactPhoto(mainDataList.get(position).getImage())==null){
                holder.image.setImageResource(R.drawable.ic_launcher);
            }else{
                holder.image.setImageBitmap(getByteContactPhoto(mainDataList.get(position).getImage()));
            }
    
    
    
            holder.check.setChecked(mainDataList.get(position).isSelected());
            return view;
        }
        public void filter(String charText) {
            charText = charText.toLowerCase(Locale.getDefault());
            mainDataList.clear();
            if (charText.length() == 0) {
                mainDataList.addAll(arraylist);
            } else {
                for (ContactObject wp : arraylist) {
                    if (wp.getName().toLowerCase(Locale.getDefault())
                            .contains(charText)) {
                        mainDataList.add(wp);
                    }
                }
            }
            notifyDataSetChanged();
        }
        public Bitmap getByteContactPhoto(String contactId) {
            Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(contactId));
            Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
            Cursor cursor = mContext.getContentResolver().query(photoUri,
                            new String[] {Contacts.Photo.DATA15}, null, null, null);
            if (cursor == null) {
                return null;
            }
            try {
                if (cursor.moveToFirst()) {
                    byte[] data = cursor.getBlob(0);
                    if (data != null) {
                        return BitmapFactory.decodeStream( new ByteArrayInputStream(data));
                    }
                }
            } finally {
                cursor.close();
            }
            return null;
            }
    
    }
    

    MainActivity.java

    package com.multiselectlistexample;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Locale;
    import android.app.Activity;
    import android.content.Context;
    import android.database.Cursor;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.text.Editable;
    import android.text.TextUtils;
    import android.text.TextWatcher;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.Button;
    import android.widget.CheckBox;
    import android.widget.EditText;
    import android.widget.LinearLayout;
    import android.widget.LinearLayout.LayoutParams;
    import android.widget.ListView;
    import android.widget.RelativeLayout;
    import android.widget.Toast;
    public class MainActivity extends Activity {
        Context context = null;
        ContactsAdapter objAdapter;
        ListView lv = null;
        EditText edtSearch = null;
        LinearLayout llContainer = null;
        Button btnOK = null;
        RelativeLayout rlPBContainer = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            context = this;
            setContentView(R.layout.activity_main);
            rlPBContainer = (RelativeLayout) findViewById(R.id.pbcontainer);
            edtSearch = (EditText) findViewById(R.id.input_search);
            llContainer = (LinearLayout) findViewById(R.id.data_container);
            btnOK = (Button) findViewById(R.id.ok_button);
            btnOK.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    // TODO Auto-generated method stub
                    getSelectedContacts();
                }
            });
            edtSearch.addTextChangedListener(new TextWatcher() {
                @Override
                public void onTextChanged(CharSequence cs, int arg1, int arg2,
                        int arg3) {
                    // When user changed the Text
                    String text = edtSearch.getText().toString()
                            .toLowerCase(Locale.getDefault());
                    objAdapter.filter(text);
                }
                @Override
                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
                }
            });
            addContactsInList();
        }
        private void getSelectedContacts() {
            // TODO Auto-generated method stub
            StringBuffer sb = new StringBuffer();
            for (ContactObject bean : ContactsListClass.phoneList) {
                if (bean.isSelected()) {
                    sb.append(bean.getName());
                    sb.append(",");
                }
            }
            String s = sb.toString().trim();
            if (TextUtils.isEmpty(s)) {
                Toast.makeText(context, "Select atleast one Contact",
                        Toast.LENGTH_SHORT).show();
            } else {
                s = s.substring(0, s.length() - 1);
                Toast.makeText(context, "Selected Contacts : " + s,
                        Toast.LENGTH_SHORT).show();
            }
        }
        private void addContactsInList() {
            // TODO Auto-generated method stub
            Thread thread = new Thread() {
                @Override
                public void run() {
                    showPB();
                    try {
                        Cursor phones = getContentResolver().query(
                                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null, null, null, null);
                        try {
                            ContactsListClass.phoneList.clear();
                        } catch (Exception e) {
                        }
                        while (phones.moveToNext()) {
                            String phoneName = phones
                                    .getString(phones
                                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                            String phoneNumber = phones
                                    .getString(phones
                                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                            String phoneImage = phones
                                    .getString(phones
                                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
    
                            ContactObject cp = new ContactObject();
    
    
                            cp.setName(phoneName);
                            cp.setNumber(phoneNumber);
                            cp.setImage(phoneImage);
                            ContactsListClass.phoneList.add(cp);
                        }
                        phones.close();
                        lv = new ListView(context);
                        lv.setLayoutParams(new LayoutParams(
                                LayoutParams.MATCH_PARENT,
                                LayoutParams.MATCH_PARENT));
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                // TODO Auto-generated method stub
                                llContainer.addView(lv);
                            }
                        });
                        Collections.sort(ContactsListClass.phoneList,
                                new Comparator<ContactObject>() {
                                    @Override
                                    public int compare(ContactObject lhs,
                                            ContactObject rhs) {
                                        return lhs.getName().compareTo(
                                                rhs.getName());
                                    }
                                });
                        objAdapter = new ContactsAdapter(MainActivity.this,
                                ContactsListClass.phoneList);
                        lv.setAdapter(objAdapter);
                        lv.setOnItemClickListener(new OnItemClickListener() {
                            @Override
                            public void onItemClick(AdapterView<?> parent,
                                    View view, int position, long id) {
                                CheckBox chk = (CheckBox) view
                                        .findViewById(R.id.contactcheck);
                                ContactObject bean = ContactsListClass.phoneList
                                        .get(position);
                                if (bean.isSelected()) {
                                    bean.setSelected(false);
                                    chk.setChecked(false);
                                } else {
                                    bean.setSelected(true);
                                    chk.setChecked(true);
                                }
                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    hidePB();
                }
            };
            thread.start();
        }
        void showPB() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    rlPBContainer.setVisibility(View.VISIBLE);
                    edtSearch.setVisibility(View.GONE);
                    btnOK.setVisibility(View.GONE);
                }
            });
        }
        void hidePB() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    rlPBContainer.setVisibility(View.GONE);
                    edtSearch.setVisibility(View.VISIBLE);
                    btnOK.setVisibility(View.VISIBLE);
                }
            });
        }
    }
    

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.multiselectlistexample"
        android:versionCode="1"
        android:versionName="1.0" >
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
        <uses-permission android:name="android.permission.READ_CONTACTS" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    
    0 讨论(0)
提交回复
热议问题