Ian La Flair
Ian La Flair

Reputation: 21

Search an data listview using edittext

I'm creating a Movie Catalog app using themoviedb API. How can I implement search using EditText?

I have a list view that contains the movie info.

App screenshot:

Now I want to use the EditText to find another movie, and the list view updated. How do I do that?

My loader:

public class MyAsyncTaskLoader extends AsyncTaskLoader<ArrayList<MovieItem>> {

    public ArrayList<MovieItem> mData;
    public boolean hasResult = false;

    public MyAsyncTaskLoader(final Context context) {
        super(context);
        onContentChanged();
        Log.d("INIT ASYNCLOADER","1");
    }

    @Override
    protected void onStartLoading() {
        Log.d("Content Changed","1");
        if (takeContentChanged())
            forceLoad();
        else if (hasResult)
            deliverResult(mData);
    }

    @Override
    public void deliverResult(final ArrayList<MovieItem> data) {
        mData = data;
        hasResult = true;
        super.deliverResult(data);
    }

    @Override
    protected void onReset() {
        super.onReset();
        onStopLoading();
        if (hasResult) {
            onReleaseResources(mData);
            mData = null;
            hasResult = false;
        }
    }

    public static String Search = "Avengers";
    public static String API_KEY = "f00e74c69ff0512cf9e5bf128569f6b5";

    @Override
    public ArrayList<MovieItem> loadInBackground() {
        Log.d("LOAD BG","1");
        SyncHttpClient client = new SyncHttpClient();
        final ArrayList<MovieItem> movieItemses = new ArrayList<>();
        final String url = "https://api.themoviedb.org/3/search/movie?api_key="+API_KEY+"&language=en-US&query="+Search;
                client.get(url, new AsyncHttpResponseHandler() {
            @Override
            public void onStart() {
                super.onStart();
                setUseSynchronousMode(true);
            }

            @Override
            public void onSuccess(int statusCode, Header[] headers,
                                  byte[] responseBody) {
                try {
                    String result = new String(responseBody);
                    JSONObject responseObject = new JSONObject(result);
                    JSONArray list = responseObject.getJSONArray("results");

                    for (int i = 0 ; i < list.length() ; i++){
                        JSONObject movie = list.getJSONObject(i);
                        MovieItem movieItems = new MovieItem(movie);
                        movieItemses.add(movieItems);
                    }
                    Log.d("REQUEST SUCCESS","1");
                }catch (Exception e){
                    e.printStackTrace();
                    Log.d("REQUEST FAILED","1");
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers,
                                  byte[] responseBody, Throwable error) {
            }
        });

        for (int i = 0 ; i< movieItemses.size() ; i++){
            Log.d("Title",movieItemses.get(i).getTitle());
        }
        Log.d("BEFORE RETURN","1");

        return movieItemses;
    }

    protected void onReleaseResources(ArrayList<MovieItem> data) {
        //nothing to do.
    }
    public ArrayList<MovieItem> getResult() {
        return mData;
    }
}

My adapter:

public class MovieAdapter extends BaseAdapter {

    private ArrayList<MovieItem> mData = new ArrayList<>();
    private LayoutInflater mInflater;
    private Context context;
    Activity activity;

    private String urlConfig ;
    public MovieAdapter(Context context) {
        this.context = context;
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void setData(ArrayList<MovieItem> items){
        mData = items;
        notifyDataSetChanged();
    }

    public void clearData(){
        mData.clear();
    }

    @Override
    public int getItemViewType(int position) {
        return 0;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public MovieItem getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            holder = new ViewHolder();

            convertView = mInflater.inflate(R.layout.item_row_film, null);

            holder.textViewuJudul= (TextView)convertView.findViewById(R.id.tv_judul);

            holder.textViewDescription = (TextView)convertView.findViewById(R.id.tv_deskripsi);
            holder.textViewRate = (TextView)convertView.findViewById(R.id.tv_rate);
            holder.imgPoster = (ImageView) convertView.findViewById(R.id.img_poster);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.textViewuJudul.setText(mData.get(position).getTitle());
        holder.textViewDescription.setText(mData.get(position).getDescription());
        holder.textViewRate .setText(mData.get(position).getRate());
        Picasso.with(context).load(mData.get(position).getImgurl()).into(holder.imgPoster);
        return convertView;
    }

    private class ViewHolder {
        public TextView textViewuJudul;
        public TextView textViewDescription;
        public TextView textViewRate;
        public ImageView imgPoster;
    }}

The item:

public class MovieItem  {

    public static String POSTER_BASE_URL = "http://image.tmdb.org/t/p/";
    private int id;
    private String title;
    private String description;
    private String rate;
    private String imgurl;

    public  MovieItem(JSONObject object){

        try {
            String title = object.getString("title");
            String description = object.getString("overview");
            double movieRatet = object.getDouble("vote_average");
            String movieRate = new DecimalFormat("#.#").format(movieRatet);
            String releaseDate = object.getString("release_date");
            String posterUrl = object.getString("poster_path");
            posterUrl = POSTER_BASE_URL + "w185" + posterUrl;
            description = description.length() > 64 ? description.substring(0,64)+"...":description;

            Log.d("movie poster", posterUrl);
            Log.d("movie title ", title);
            Log.d("movie description ", description);
            Log.d("movie release ", releaseDate);



            this.title = title;
            this.description = description;
            this.rate = releaseDate;
            this.imgurl = posterUrl;


        }catch (Exception e){

            e.printStackTrace();
        }
    }

My MainActivity:

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<ArrayList<MovieItem>>
        ,View.OnClickListener{

    ListView listView;
    MovieAdapter adapter;
    MyAsyncTaskLoader myAsyncTaskLoader;
    private TextView edt_cari;

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

        edt_cari = (TextView) findViewById(R.id.edt_cari);


        adapter = new MovieAdapter(this);
        adapter.notifyDataSetChanged();
        listView = (ListView) findViewById(R.id.listView);

        listView.setAdapter(adapter);
        getLoaderManager().initLoader(0, null, this);

    }

    @Override
    public Loader<ArrayList<MovieItem>> onCreateLoader(int id, Bundle args) {
        Log.d("Create Loader", "1");
        return new MyAsyncTaskLoader(this);
    }

    @Override
    public void onLoadFinished(Loader<ArrayList<MovieItem>> loader, ArrayList<MovieItem> data) {
        Log.d("Load Finish","1");
        adapter.setData(data);
    }

    @Override
    public void onLoaderReset(Loader<ArrayList<MovieItem>> loader) {
        Log.d("Load Reset","1");
        adapter.setData(null);
    }

    @Override
    public void onClick(View v) {

        if (v.getId() == R.id.btn_cari){
            SearchMovieTask searchMovie = new SearchMovieTask();
            searchMovie.execute(edt_cari.getText().toString().trim());

        }
    }

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

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

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

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
        }
    }}

Upvotes: 0

Views: 112

Answers (2)

Sanjay Chauhan
Sanjay Chauhan

Reputation: 913

Replace your MovieAdapter to this ...!

 public class MovieAdapter extends BaseAdapter implements Filterable {

        private ArrayList<MovieItem> mData = new ArrayList<>();
        private ArrayList<MovieItem> mSearchData = new ArrayList<>();
        private ArrayList<MovieItem> categoryListOne = new ArrayList<>();
        private LayoutInflater mInflater;
        private Context context;
        Activity activity;
        ItemFilter mFilter = new ItemFilter();

        private String urlConfig;

        public MovieAdapter(Context context) {
            this.context = context;
            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        public void setData(ArrayList<MovieItem> items) {
            mData = items;
            mSearchData = items;
            notifyDataSetChanged();
        }

        public void clearData() {
            mData.clear();
        }

        @Override
        public int getItemViewType(int position) {
            return 0;
        }

        @Override
        public int getViewTypeCount() {
            return 1;
        }

        @Override
        public int getCount() {
            return mData.size();
        }

        @Override
        public MovieItem getItem(int position) {
            return mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();

                convertView = mInflater.inflate(R.layout.item_row_film, null);

                holder.textViewuJudul = (TextView) convertView.findViewById(R.id.tv_judul);

                holder.textViewDescription = (TextView) convertView.findViewById(R.id.tv_deskripsi);
                holder.textViewRate = (TextView) convertView.findViewById(R.id.tv_rate);
                holder.imgPoster = (ImageView) convertView.findViewById(R.id.img_poster);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.textViewuJudul.setText(mData.get(position).getTitle());
            holder.textViewDescription.setText(mData.get(position).getDescription());
            holder.textViewRate.setText(mData.get(position).getRate());
            Picasso.with(context).load(mData.get(position).getImgurl()).into(holder.imgPoster);
            return convertView;
        }

        @Override
        public Filter getFilter() {
            return mFilter;
        }

        public class ItemFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                constraint = constraint.toString().toLowerCase().replace(" ", "");
                Log.v("DataAdapter", "constratinst : " + constraint);
                FilterResults result = new FilterResults();
                if (constraint.toString().length() > 0) {
                    ArrayList<Sticker> filteredItems =
                            new ArrayList<>();
                    for (int i = 0, l = mData.size(); i < l; i++) {
                        // ArrayList<HashMap<String, String>> p =
                        // originalList.get(i);
                        String p = mData.get(i).getName().toLowerCase().replace(" ", "");
                        if (p.toLowerCase().startsWith(String.valueOf(constraint)))
                            filteredItems.add(mData.get(i));

    //                    if (p.toLowerCase().contains(constraint))
    //                        filteredItems.add(categoryListSearch.get(i));
                    }
                    Log.v("DataAdapter", "not blank");
                    result.count = filteredItems.size();
                    result.values = filteredItems;

                } else {
                    synchronized (this) {
                        result.count = categoryListOne.size();
                        result.values = categoryListOne;
    //                    result.values = dataList;
    //                    result.count = dataList.size();
                    }
                }
                return result;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                // users = (List<GraphUser>) results.values;
                //filteredData = (ArrayList<String>) results.values;
                mData = (ArrayList<MovieItem>) results.values;
                notifyDataSetChanged();

    //            for (int i = 0, l = mData.size(); i < l; i++)
    //                mSearchData.get(i);
                //add(productList.get(i));

                notifyDataSetInvalidated();
            }
        }


        private class ViewHolder {

            public TextView textViewuJudul;
            public TextView textViewDescription;
            public TextView textViewRate;
            public ImageView imgPoster;


        }

    }

And your activity set EditText Listener to this..!

editText.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

                }

                @Override
                public void afterTextChanged(Editable editable) {
                     adapter.getFilter().filter(charSequence.toString());
                }
            });

i hope it's helpful to you ..!

Upvotes: 2

Altaf Shaikh
Altaf Shaikh

Reputation: 779

Implement addTextChangedListener() on your search EditText and as the text changes filter your list data and update MovieAdapter with filtered data.

check this post on how to update custom list adapter

Upvotes: 0

Related Questions