Reputation: 21
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.
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
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
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