Thursday 7 May 2015

Applying Filters in Listview using Custom Model with BaseAdapter

This Demo provides a filterable list which is been filter according to the custom model. here we are using a Student model which can be replace as per need .

1. MainActivity.java


public class MainActivity extends ActionBarActivity {



    EditText mEditText;

    ListAdapter mAdapter;

    private ListView mListView;

    @Override    
   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        showAlertDialog();
        mListView = (ListView) findViewById(R.id.listview);
        mEditText = (EditText) findViewById(R.id.editText);
        int student_name = 0;
        String[] names = {"Nishant", "Umang", "Vikrant", "Danish", "Sunil", "Kamal", "Nitesh", "Amit", "Sarthak", "Aman", "Naresh", "Yoginder"};
        //arrayList of Students      

      ArrayList<Student> array_list = new ArrayList<Student>();

        for (int x = 1; x <= 5000; x++) {

            if (student_name > 11) {
                student_name = 0;
            }

            Student student = new Student(x, names[student_name]);
            array_list.add(student);
            student_name++;
        }

        mAdapter = new ListAdapter(this, array_list);

        mListView.setAdapter(mAdapter);

        //on Text change in Search EditText.       

       mEditText.addTextChangedListener(new TextWatcher() {

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

            }

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

                // Filter arrayList on TextChanged in EditText                
            MainActivity.this.mAdapter.getFilter().filter(s);
            }

            @Override            
          public void afterTextChanged(Editable s) {

            }

        });


        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override           
       public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                // get current clicked Item data.                Student student = (Student) parent.getItemAtPosition(position);

                Toast.makeText(getApplicationContext(), student.getName() + " " + student.getStudentId(), Toast.LENGTH_SHORT).show();

            }

        });

    }


    @Override    
public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);

        return true;

    }


    @Override    
public boolean onOptionsItemSelected(MenuItem item) {

        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();

        //noinspection SimplifiableIfStatement        if (id == R.id.action_info) {


            showAlertDialog();

            return true;

        }


        return true;

    }

    void showAlertDialog() {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        // set title     
 alertDialogBuilder.setTitle(getResources().getString(R.string.alert_dialog_title));
        // set dialog message     
alertDialogBuilder.setMessage(getResources().getString(R.string.alert_dialog_desc))
                .setCancelable(true)
                .setPositiveButton(getResources().getString(R.string.alert_dialog_button_text), new DialogInterface.OnClickListener() {

                  

public void onClick(DialogInterface dialog, int id) {

                        // if this button is clicked, close dialog                                        dialog.cancel();
                    }
                });
        // create alert dialog        AlertDialog alertDialog = alertDialogBuilder.create();
        // show the alert dialog        alertDialog.show();
    }
}
2. Student.java

public class Student {

    private int studentId;

    private String name;

    /*

    * constructor of the Student class which accepting two parameters.

    * @parameters id : Student Id.

    * @parameters name : Name of the Student

    */

    public Student(int id, String name) {

        this.studentId = id;

        this.name = name;

    }

    public String getName() {

        return name;

    }

    public int getStudentId() {

        return studentId;

    }


}


3. ListAdapter.java

public class ListAdapter extends BaseAdapter implements Filterable {



    private final Object mLock = new Object();

    private List<Student> mArrayList;

    private Context mContext;

    // A copy of the original mObjects array, initialized from and then used instead as soon as

    // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values.

    private ArrayList<Student> mOriginalValues;

    private ArrayFilter mFilter;


    public ListAdapter(Context context, ArrayList<Student> arrayList) {

        mContext = context;

        mArrayList = arrayList;

    }

    @Override

    public int getCount() {

        return mArrayList.size();

    }

    @Override

    public Object getItem(int position) {

        return mArrayList.get(position);

    }

    @Override

    public long getItemId(int position) {

        return 0;

    }

    @Override

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

        ViewHolder viewHolder;

        if (convertView == null) {

            LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();

            convertView = inflater.inflate(R.layout.list_item, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.tvStudentName = (TextView) convertView.findViewById(R.id.tv_listitem);

            viewHolder.tvStudentId=(TextView)convertView.findViewById(R.id.tv_student_id);

            convertView.setTag(viewHolder);

        } else {

            viewHolder = (ViewHolder) convertView.getTag();

        }

        if (mArrayList.get(position) != null) {

            viewHolder.tvStudentName.setText(mArrayList.get(position).getName());

            viewHolder.tvStudentId.setText(""+mArrayList.get(position).getStudentId());

            viewHolder.tvStudentName.setTag(mArrayList.get(position));

        }

        return convertView;

    }

    /**

     * <p>Returns a filter that can be used to constrain data with a filtering

     * pattern.</p>

     * <p/>

     * <p>This method is usually implemented by {@link android.widget.Adapter}

     * classes.</p>

     *

     * @return a filter used to constrain data

     */
    @Override
    public Filter getFilter() {
        if (mFilter == null) {

            mFilter = new ArrayFilter();

        }

        return mFilter;

    }
    private class ViewHolder {

        TextView tvStudentName,tvStudentId;

    }

    private class ArrayFilter extends Filter {

        @Override

        protected FilterResults performFiltering(CharSequence prefix) {

            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {

                synchronized (mLock) {

                    mOriginalValues = new ArrayList<Student>(mArrayList);

                }

            }

            if (prefix == null || prefix.length() == 0) {

                ArrayList<Student> list;

                synchronized (mLock) {

                    list = new ArrayList<Student>(mOriginalValues);

                }

                results.values = list;

                results.count = list.size();

            } else {

                String prefixString = prefix.toString().toLowerCase();

                ArrayList<Student> values;

                synchronized (mLock) {

                    values = new ArrayList<Student>(mOriginalValues);

                }

                final int count = values.size();

                final ArrayList<Student> newValues = new ArrayList<Student>();

                for (int i = 0; i < count; i++) {

                    final Student value = values.get(i);

                    final String valueText = value.getName().toLowerCase();

                    final String valueTextId = String.valueOf(value.getStudentId()).toLowerCase();

                    // First match against the whole, non-splitted value

                       if (valueText.contains(prefixString) || valueTextId.contains(prefixString)) {

                        newValues.add(value);

                    } else {

                        final String[] words = valueText.split(" ");

                        final int wordCount = words.length;

                        // Start at index 0, in case valueText starts with space(s)

                        for (int k = 0; k < wordCount; k++) {

                            if (words[k].startsWith(prefixString)) {

                                newValues.add(value);

                                break;

                            }

                        }

                    }

                }

                results.values = newValues;

                results.count = newValues.size();

            }

            return results;

        }

        @Override

        protected void publishResults(CharSequence constraint, FilterResults results) {

            mArrayList = (List<Student>) results.values;

            if (results.count > 0) {

                notifyDataSetChanged();

            } else {

                notifyDataSetInvalidated();

            }

        }

    }

}
XML Layouts :

 1. activity_main.xml
<LinearLayout 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">

    <EditText

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:id="@+id/editText"

        android:hint="Enter Text"

        android:layout_above="@+id/listview"

        android:layout_centerHorizontal="true"

       />

    <ListView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:id="@+id/listview"

        android:choiceMode="singleChoice" />

</LinearLayout>


2. list_item.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="match_parent">

    <TextView

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="New Text"

        android:id="@+id/tv_listitem"

        android:layout_centerVertical="true"

        android:paddingBottom="10dp"

        android:paddingTop="10dp"

        android:layout_centerHorizontal="true" />



    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="New Text"

        android:id="@+id/tv_student_id"

        android:layout_centerInParent="true" />

</RelativeLayout>



3. menu_main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">

    <item android:id="@+id/action_info" android:title="@string/action_info"

        android:orderInCategory="100" app:showAsAction="never" />

</menu>


4. strings.xml

<resources>

    <string name="app_name">Filterable List</string>
    <string name="action_info">Info</string>

    <string name="alert_dialog_desc">This is demo about Offline Filtering from ListView. You can filter with any parameters of list like (Student name or student Id).</string>

    <string name="alert_dialog_title">List with Filter Option</string>

    <string name="alert_dialog_button_text">OK</string>

</resources>

Output :





No comments:

Post a Comment