Android filter listview custom adapter

2020-02-02 03:00发布

Hello everybody I'm doing an app which has an edittext to search for items on the listview. If the user types a letter. The data come from my json string (database) and then display on my listview. So far this is what I've tried:

 ListViewAdapter adapter2;
 ArrayList<HashMap<String, String>> arraylist;
 ArrayList<String> list = new ArrayList<String>();

 wsSearch.addTextChangedListener(new TextWatcher (){

        public void afterTextChanged(Editable cs) {
            // TODO Auto-generated method stub



        }

        public void beforeTextChanged(CharSequence arg0, int arg1,
                int arg2, int arg3) {
            // TODO Auto-generated method stub

        }

        public void onTextChanged(CharSequence cs, int arg1, int arg2,
                int arg3) {
            // TODO Auto-generated method stub
            //BAPTISMAL_SONG.this.adapter2.getFilter().filter(cs); 


            String searchString = cs.toString();
            if(searchString.length() != 2) {
                adapter2 = new ListViewAdapterBaptismal(BAPTISMAL_SONG.this, arraylist);
                listview.setAdapter(adapter2);
                return;
            }
            ArrayList<HashMap<String, String>> arrayTemplist = new ArrayList<HashMap<String,String>>();
            for (int i = 0; i < arraylist.size(); i++)
                {
                String currentString = arraylist.get(i).get(BAPTISMAL_SONG.TAG_TITLE);
                if (searchString.equalsIgnoreCase(currentString))
                    {
                        arrayTemplist.add(arraylist.get(i));
                    }
                }
            adapter2 = new ListViewAdapterBaptismal(BAPTISMAL_SONG.this, arrayTemplist);
            listview.setAdapter(adapter2);

        }

    });

@Override
protected void onPostExecute(Void args) {
        // Locate the listview in listview_main.xml

        // Pass the results into ListViewAdapter.java
        adapter2 = new ListViewAdapter(Activity2.this, arraylist);
        // Binds the Adapter to the ListView
        listview.setAdapter(adapter2);


        // Close the progressdialog
        mProgressDialog.dismiss();
    }
}

What I want to achieve, if the user types a letter like B, all the items that start with the said letter should be filtered. But using the code I posted above, it does not do exactly what I want. It just filters whenever I typed the whole item name. Any ideas? Your help will be greatly appreciated. Thanks.

6条回答
ゆ 、 Hurt°
2楼-- · 2020-02-02 03:26

I got complete solution, i put filter method in custom adapter for multiple fields search functionality.

Note: for image loading i took lazy loading so you need ImageLoader.java, FileCache.java, Utils.java and MemoryCache.java.

Check bellow code.....

list_layout.xml ( layout folder )

<?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="match_parent"
    android:padding="10dp"
    android:background="#ffffff" >

    <EditText 
         android:id="@+id/et_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="search...."
        android:paddingLeft="5dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" 

        />
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_marginTop="5dp"
        android:layout_height="match_parent"
       android:layout_below="@+id/et_search">
    </ListView>

</RelativeLayout>

custom_row.xml ( layout folder )

<?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="match_parent"
    android:background="#33B5E5" >

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginBottom="23dp"
        android:layout_marginLeft="23dp"
        android:layout_marginTop="23dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/txt_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/image_view"
        android:layout_marginLeft="15dp"
        android:layout_toRightOf="@+id/image_view"
        android:text="id"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/txt_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/txt_id"
        android:layout_below="@+id/txt_id"
        android:text="name"
        android:textColor="#ffffff" />

</RelativeLayout>

put sample.json file in assets folder

sample.json

{
   "sample":[
      {
         "id":"1",
         "name":"nirav kalola",
         "image":"http://www.wallpaperfunda.com/wp-content/uploads/2014/03/images-2.jpg",
         "description":"def"
      },
      {
         "id":"2",
         "name":"abc",
         "image":"http://www.wallpaperfunda.com/wp-content/uploads/2014/03/images-2.jpg",
         "description":"abc"
      },
      {
         "id":"3",
         "name":"def",
         "image":"http://www.wallpaperfunda.com/wp-content/uploads/2014/03/images-2.jpg",
         "description":"ghi"
      },
      {
         "id":"55",
         "name":"ghi",
         "image":"http://www.wallpaperfunda.com/wp-content/uploads/2014/03/images-2.jpg",
         "description":"jkl"
      },
      {
         "id":"5",
         "name":"jkl",
         "image":"http://www.wallpaperfunda.com/wp-content/uploads/2014/03/images-2.jpg",
         "description":"mno"
      },
      {
         "id":"11",
         "name":"mno",
         "image":"http://www.wallpaperfunda.com/wp-content/uploads/2014/03/images-2.jpg",
         "description":"pqr"
      },
      {
         "id":"10",
         "name":"nirav007",
         "image":"http://www.wallpaperfunda.com/wp-content/uploads/2014/03/images-2.jpg",
         "description":"stu"
      }
   ]
}

ListActivity.java ( src folder )

public class ListActivity extends Activity {

    private ListView listView;
    private ProgressDialog progressDialog;
    private List<SampleData> sampleData;
    private ArrayList<SampleData> sampleList;
    private SampleAdapter sampleAdapter;
    private EditText etSearch;

    ArrayList<SampleData> arraylist = new ArrayList<SampleData>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_layout);
        listView=(ListView) findViewById(R.id.list_view);

        BackGroundTask bt = new BackGroundTask();
        bt.execute();
        etSearch=(EditText) findViewById(R.id.et_search);
        etSearch.setSingleLine(true);


        etSearch.addTextChangedListener(new TextWatcher() {

            public void afterTextChanged(Editable s) {
                String text = etSearch.getText().toString().toLowerCase(Locale.getDefault()); 
                sampleAdapter.filter(text);

            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {

            }

            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {

            }   
        });
    }

    private class BackGroundTask extends AsyncTask<Void, Void, String> {


        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            progressDialog = new ProgressDialog(ListActivity.this);
            progressDialog.setCancelable(false);
            progressDialog.setMessage("Loading...");
            progressDialog.show();   
        }

        @Override
        protected String doInBackground(Void... arg0) {
            try {
                JSONObject jsonObject = new JSONObject(loadJSONFromAsset());
                JSONArray jsonArray = jsonObject.getJSONArray("sample");
                sampleData=new ArrayList<SampleData>();

                for (int i = 0; i < jsonArray.length(); i++) 
                {
                    JSONObject jsonObjectInside = jsonArray.getJSONObject(i);

                    String id = jsonObjectInside.getString("id");
                    String name = jsonObjectInside.getString("name");
                    String imagePath = jsonObjectInside.getString("image");
                    String description = jsonObjectInside.getString("description");
                    sampleData.add(new SampleData(id, name, imagePath, description));           
                    Log.e("id",id+"");
                    Log.e("name",name+"");
                    Log.e("imagPath",imagePath+"");
                    Log.e("description",description+"");

                }

                handlePostsList(sampleData);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 

            return null;
        }


        @Override
        protected void onPostExecute(String result){
            super.onPostExecute(result);
            progressDialog.dismiss();
        }  
    }// End of Background AsyncTask


    private void handlePostsList(final List<SampleData> sampleData) {
        this.sampleData = sampleData;
        runOnUiThread(new Runnable() {
            public void run() {
                try {
                    // logic for retrieve data first time in list view.
                    sampleList = new ArrayList<SampleData>();

                    for (int i = 0; i < sampleData.size(); i++) {

                        sampleList.add(new SampleData(sampleData.get(i).getId().toString(),sampleData.get(i).getName().toString(),sampleData.get(i).getImage().toString(),sampleData.get(i).getDescription().toString()));
                    }

                    sampleAdapter= new SampleAdapter(ListActivity.this, sampleList);
                    listView.setAdapter(sampleAdapter);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }


    public class SampleAdapter extends BaseAdapter
    {
        Context context;
        List<SampleData> sampleData=null;
        ArrayList<SampleData> arraylist;
        LayoutInflater inflater;
        ImageLoader imageLoader; 


        public SampleAdapter(Context context, List<SampleData> sampleData) {
            this.context = context;
            this.sampleData = sampleData;
            this.arraylist = new ArrayList<SampleData>();
            this.arraylist.addAll(sampleData);
            imageLoader=new ImageLoader(ListActivity.this);
        }


        public class ViewHolder {
            TextView txtID,txtName,txtDescription;
            ImageView image;

        }

        public int getCount() {

            return sampleData.size();
        }

        public Object getItem(int position) {
            return sampleData.get(position);
        }

        public long getItemId(int position) {
            return sampleData.indexOf(getItem(position));
        }

        public View getView(final int position, View convertView, ViewGroup parent)
        {

            final ViewHolder holder;
            LayoutInflater mInflater = (LayoutInflater)
                    context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.custom_row, null);
                holder = new ViewHolder();
                holder.txtID = (TextView) convertView.findViewById(R.id.txt_id);
                holder.txtName = (TextView) convertView.findViewById(R.id.txt_name);
                holder.image = (ImageView) convertView.findViewById(R.id.image_view);
                convertView.setTag(holder);
            }
            else
            {
                holder = (ViewHolder) convertView.getTag();
            }


            holder.txtID.setText(sampleData.get(position).getId());
            holder.txtName.setText(sampleData.get(position).getName());

            imageLoader.DisplayImage(sampleData.get(position).getImage(), holder.image);

//          convertView.setOnClickListener(new OnClickListener() {
//              Intent intent=null;
//              @Override
//              public void onClick(View v) {
//                  Log.e("description....",sampleData.get(position).getDescription()+"");
//                  intent=new Intent(ListActivity.this, DetailActivity.class);
//                  intent.putExtra("description", sampleData.get(position).getDescription());
//                  startActivity(intent);
//                  finish();
//              }
//          });
            return convertView;
        }

        // Filter Class
        public void filter(String charText) {
            charText = charText.toLowerCase(Locale.getDefault());
            sampleData.clear();
            if (charText.length() == 0) {
                sampleData.addAll(arraylist);

            } else {
                for (SampleData st : arraylist) {
                    if (st.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
                        sampleData.add(st);
                    }else if (st.getId().toLowerCase(Locale.getDefault()).contains(charText)) {
                        sampleData.add(st);
                    }
                    else if (st.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
                        sampleData.add(st);
                    }
                }
            }
            notifyDataSetChanged();
        }

    }


    public String loadJSONFromAsset() {
        String json = null;
        try {

            InputStream is = getAssets().open("sample.json");

            int size = is.available();

            byte[] buffer = new byte[size];

            is.read(buffer);

            is.close();

            json = new String(buffer, "UTF-8");


        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
        return json;

    }


}

SampleData.java ( src folder )

public class SampleData 
{

    private String id;
    private String name;
    private String image;
    private String description;


    public SampleData(String id, String name, String image, String description) {
        super();
        this.id = id;
        this.name = name;
        this.image = image;
        this.description = description;
    }


    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 getImage() {
        return image;
    }
    public void setImage(String image) {
        this.image = image;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }


}

add following permissions in AndroidManifest.xml file

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

thats it..

enjoy coding

查看更多
ら.Afraid
3楼-- · 2020-02-02 03:27
arrayTemplist.clear();

for (int i = 0; i < mainArray.size(); i++) {
    if (searchString.length()<= mainArray.get(i).length()) {
        if (editText
            .getText()
            .toString()
            .equalsIgnoreCase(
                (String) mainArray.get(i).subSequence(0,
                    searchString.length()))) {
                        arrayTemplist.add(mainArray.get(i));
                    }
        }
}
adapter = new ListViewAdapterBaptismal(BAPTISMAL_SONG.this, arrayTemplist);
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();

use this `onTextChanged() method, might be it will help you.

查看更多
该账号已被封号
4楼-- · 2020-02-02 03:31

//Main Activity

Intent intent = new Intent(getApplicationContext(),
ListActivity.class);
intent.putExtra("name", name);
intent.putExtra("number", number);
startActivity(intent);

Then ListActivity.class

EditText search;
ListView lvDetail;
Contact data;
MyBaseAdapter adapter;
ArrayList<Contact> myList = new ArrayList<Contact>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list);
    lvDetail = (ListView) findViewById(R.id.lvCustomList);
    search = (EditText) findViewById(R.id.inputSearch);
    String[] name = getIntent().getStringArrayExtra("name");
    String[] number = getIntent().getStringArrayExtra("number");
    // System.out.println((1>2?1:(1==2?1:(2>3?2:3))));
    for (int i = 0; i < name.length; i++) {
        data = new Contact();
        data.setName(name[i]);
        data.setPhonenum(number[i]);
        data.setImgResId(img[i]);
        myList.add(data);
    }
    adapter = new MyBaseAdapter(getApplicationContext(), myList);
    lvDetail.setAdapter(adapter);
    lvDetail.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

        }
    });
    search.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int start, int before,
                int count) {
                   String text = search.getText().toString().toLowerCase(Locale.getDefault());
                   adapter.filter(text);


        }
        @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

        }
    });
}

//Custom Adapter

 public class MyBaseAdapter extends BaseAdapter {
 ArrayList<Contact> myList = new ArrayList<Contact>();
 LayoutInflater inflater;
 Context context;
 private ArrayList<Contact> privatearray;
 public MyBaseAdapter(Context context,ArrayList<Contact> myList) {
     this.myList = myList;
     this.context = context;
     inflater = LayoutInflater.from(this.context);
     privatearray=new ArrayList<Contact>();
     privatearray.addAll(myList);
}


@Override
public int getCount() {
    // TODO Auto-generated method stub
    return myList.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return myList.get(position);
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public View getView(int position, View view, ViewGroup arg2) {
    //LayoutInflater inflater = getLayoutInflater();

    View row;
    row = inflater.inflate(R.layout.layout_list_item, arg2, false);
    TextView title, detail;
    ImageView i1;
    i1=(ImageView)row.findViewById(R.id.ivIcon);
    title = (TextView) row.findViewById(R.id.name);
    detail = (TextView) row.findViewById(R.id.phonenumber);
    i1=(ImageView)row.findViewById(R.id.ivIcon);
    //ListActivity activity=(ListActivity)Arrays.asList(myList)[0];
    //ListData data=myList.get(0);

   // Log.d("list", String.valueOf(myList.size())+" "+String.valueOf(data.getDescription()));
    i1.setImageResource(myList.get(position).getImgResId());
    title.setText(myList.get(position).getName());
    detail.setText(myList.get(position).getPhonenum());
    return (row);
}
// Filter Class
public void filter(String charText) {

    charText = charText.toLowerCase(Locale.getDefault());
    myList.clear();
    if(charText.length()==0){
        myList.addAll(privatearray);
    }
    else{
        for (Contact c : privatearray) {
            if (c.getName().toLowerCase(Locale.getDefault())
                    .contains(charText)) {
                myList.add(c);
            }
        }
    }
    notifyDataSetChanged();


}

}

//and Model

public class Contact {
String phonenum;
String name;
int imgResId;
public String getPhonenum() {
    return phonenum;
}
public void setPhonenum(String phonenum) {
    this.phonenum = phonenum;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getImgResId() {
    return imgResId;
}
public void setImgResId(int imgResId) {
    this.imgResId = imgResId;
}

}

查看更多
趁早两清
5楼-- · 2020-02-02 03:31

You could give this a try:

    public class MyAdapter extends ArrayAdapter<Model> {

          public MyAdapter(Context context, int textViewResourceId,
                 List<model> objects) {
               super(context, textViewResourceId, objects);
          }

          @Override
          public View getView(int position, View convertView, ViewGroup parent) {
               TextView tx = (TextView)convertView;
               SpannableString text = getItem(position);
               for(char:typedChar)
               if(tx.getText().contains(char)){

                    // make "text" (characters pos-1 to pos) red  

                    text.setSpan(new ForegroundColorSpan(Color.RED), 

tx.getText().indexOf(char) - 1, tx.getText().indexOf(char), 0);  

                    textView.setText(text, BufferType.SPANNABLE);
               }
          }
     }

Then Finally Register Editext here:

 edit.addTextChangedListener(new TextWatcher(){
        public void afterTextChanged(Editable s) {

           //Modify letter here by simple parsing
        }
        public void beforeTextChanged(CharSequence s, int start, int count, int after){}
        public void onTextChanged(CharSequence s, int start, int before, int count){}
    });

Hope this could help you ...

查看更多
时光不老,我们不散
6楼-- · 2020-02-02 03:35

Update your own code only:

searchString = searchString.trim().toLowerCase();
for (int i = 0; i < arraylist.size(); i++)
{
    String currentString = arraylist.get(i).get(BAPTISMAL_SONG.TAG_TITLE).trim().toLowerCase();
    if (currentString.startsWith(searchString))
    {
        arrayTemplist.add(arraylist.get(i));
    }
}

The code below maybe help you.

private ArrayList<HashMap<String, String>> arrayDatalist = new ArrayList<HashMap<String,String>>();
...

@Override
protected void onCreate(Bundle savedInstanceState) {

    ....

    arrayDatalist.addAll(arraylist);
    adapter2 = new ListViewAdapterBaptismal(BAPTISMAL_SONG.this, arrayDatalist);
    listview.setAdapter(adapter2);

    searchInput.addTextChangedListener(new TextWatcher(){
        public void afterTextChanged(Editable s) {}
        public void beforeTextChanged(CharSequence s, int start, int count, int after){}
        public void onTextChanged(CharSequence s, int start, int before, int count){
            if (searchInput.isEnabled()){
                searchString = searchInput.getText().toString().trim().toLowerCase();
                if (searchLocationOperation!=null && searchLocationOperation.getStatus().equals(Status.RUNNING)){
                    searchLocationOperation.cancel(true);
                }
                searchLocationOperation = new SearchLocationOperation(searchString);
                searchLocationOperation.execute();
            }
        }
    });
}

private class SearchLocationOperation extends AsyncTask<Void, Void, String> {   
    private ArrayList<HashMap<String, String>> searchResult = new ArrayList<HashMap<String,String>>();
    private String searchString;

    public SearchLocationOperation(String str){
        searchString = str;
    }

    @Override
    protected String doInBackground(Void... params) {                       
        if (searchString.length() <= 2) {
            searchResult.addAll(arraylist);                
        }else{
            for (HashMap<String, String> rowItem: arraylist)
            {

                //if (rowItem.get(BAPTISMAL_SONG.TAG_TITLE).toLowerCase().contains(searchString))  //If get filter with any part of the name
                if (rowItem.get(BAPTISMAL_SONG.TAG_TITLE).toLowerCase().startWiths(searchString))
                {
                    searchResult.add(rowItem);
                }
                if (isCancelled()) return null;
            }
        }
        return null;
    }

    @Override
    protected void onPreExecute() {         
        //Show progress if needed
        super.onPreExecute();
    }       

    @Override
    protected void onPostExecute(String result) {           
        //Hide progress if showed

        if (!isCancelled() && arrayDatalist!=null && adapter2!=null){           
            arrayDatalist.clear();
            arrayDatalist.addAll(searchResult);
            adapter2.notifyDataSetChanged();
        }

        super.onPostExecute(result);
    }
}
查看更多
够拽才男人
7楼-- · 2020-02-02 03:47

As far as I can see you are only checking if the two Strings match exactly. You might want to use boolean startsWith(String prefix)

Which would make something like

if (currentString.trim().toLowerCase().startsWith(searchString.trim().toLowerCase()))
{
     arrayTemplist.add(arraylist.get(i));
} 
查看更多
登录 后发表回答