getting error notifydatasetchanged() when search data from searchview - android

I have fragment like below image with searchview in actionbar
I search on it and got some link also and try it but its not work
I want to search data from below listview.
I have done code for it but it give error like this
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131558596, class android.widget.ListView) with Adapter
I have write notifydatasetchanged() that in getview still get this error don`t know where i did mistake please help me.
Thank you in advance
My CustomAdapter code is below
public class CustomListAdapter extends BaseAdapter implements Filterable {
ArrayList<D> dList;
LayoutInflater inflater;
Context context;
private int lastPosition = 0;
ArrayList<D> tempList;
ArrayList<D> reloadList;
private DFilter dFilter;
D dModel;
public CustomListAdapter(Context context, ArrayList<D> myList, ArrayList<D> allDList) {
this.dList = myList;
this.context = context;
inflater = LayoutInflater.from(this.context);
this.tempList = new ArrayList<D>();
this.tempList.addAll(allDList);
getFilter();
}
#Override
public int getCount() {
return dList.size();
}
#Override
public Object getItem(int position) {
return dList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.custom_d_list, parent, false);
mViewHolder = new MyViewHolder(convertView);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
try {
dModel = dList.get(position);
mViewHolder.tvName.setText(dModel.getDName());
mViewHolder.tvDegree.setText(dModel.getDEducation());
mViewHolder.ivImage.setImageResource(dModel.getDImageNumber());
notifyDataSetChanged();
Animation animation = AnimationUtils.loadAnimation(context, (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
convertView.startAnimation(animation);
lastPosition = position;
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
private class MyViewHolder {
TextView tvName, tvDegree;
ImageView ivImage;
public MyViewHolder(View item) {
tvName = (TextView) item.findViewById(R.id.custom_d_list_tv_name);
tvDegree = (TextView) item.findViewById(R.id.custom_d_list_tv_degree);
ivImage = (ImageView) item.findViewById(R.id.custom_d_list_iv);
}
}
#Override
public Filter getFilter() {
if (dFilter == null) {
dFilter = new DFilter();
}
return dFilter;
}
private class DFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final String searchString = constraint.toString().toLowerCase();
Log.i("TAG", "Query=>" + constraint);
final FilterResults filterResults = new FilterResults();
if (constraint != null && constraint.toString()!="") {
dList.clear();
for (D d : tempList) {
if (d.getDName().toLowerCase().contains(searchString)) {
dList.add(d);
Log.i("TAG", "SEARCH DATA=>" + tempList);
}
}
filterResults.count = dList.size();
Log.i("TAG", "FilterResultCount=>" + filterResults.count);
filterResults.values = dList;
Log.i("TAG", "FilterResultValues=>" + filterResults.values);
} else {
filterResults.count = dList.size();
filterResults.values = dList;
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
dList = (ArrayList<D>) results.values;
notifyDataSetChanged();
Log.i("TAG", "SearchResult" + dList);
}
} }

I solved it thanks to all for response.
I change below Logic in my fragment and its solve
private void loadA() {
for (D tempD : arrayA) {
dList.add(tempD);
}
setAdapter(dList,allDList);
}
private void loadB() {
for (D tempD : arrayB) {
dList.add(tempD);
}
setAdapter(dList,allDList);
Log.i("ListSize", "" + dList.size());}
private void setAdapter(ArrayList<D> dList,ArrayList<D> allDList)
{
adapter=new CustomDoctorsListAdapter(getActivity().getApplicationContext(),dList,allDList);
adapter.notifyDataSetChanged();
lvDoctors.setAdapter(adapter);
lvDoctors.setTextFilterEnabled(true);
}
#Override
public boolean onQueryTextChange(String newText) {
if (newText.equals("")) {
if (A.isChecked() == true) {
// lv.clearTextFilter();
adapter.dList.clear();
loadA();
} else {
//lv.clearTextFilter();
adapter.dList.clear();
loadB();
}
}else {
adapter.getFilter().filter(newText);
}
return true;
}

Related

Custom Filter for AutoCompleteTextView returns wrong string on click

I wrote a custom ArrayAdapter with a custom Filter for my AutoCompleteTextView. It shows everything correctly, but when I filter the suggestions and click on an item, it takes the string of the item that was at this position in the suggestion list when ALL items were shown. I made screenshot to clarify what I mean:
And this is my code:
public class AutoCompleteCountryAdapter extends ArrayAdapter<CountryItem> {
private List<CountryItem> countryList;
private List<CountryItem> filteredCountryList = new ArrayList<>();
public AutoCompleteCountryAdapter(#NonNull Context context, #NonNull List<CountryItem> countryList) {
super(context, 0, countryList);
this.countryList = countryList;
}
#Override
public int getCount() {
return filteredCountryList.size();
}
#NonNull
#Override
public Filter getFilter() {
return countryFilter;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
CountryItem countryItem = filteredCountryList.get(position);
LayoutInflater inflater = LayoutInflater.from(getContext());
if (convertView == null) {
convertView = inflater.inflate(
R.layout.country_autocomplete_row, parent, false
);
}
TextView textViewName = convertView.findViewById(R.id.text_view_name);
ImageView imageViewFlag = convertView.findViewById(R.id.image_view_flag);
textViewName.setText(countryItem.getCountryName());
imageViewFlag.setImageResource(countryItem.getFlagImage());
return convertView;
}
private Filter countryFilter = new Filter() {
private List<CountryItem> suggestions = new ArrayList<>();
#Override
protected FilterResults performFiltering(CharSequence constraint) {
suggestions.clear();
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
suggestions.addAll(countryList);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (CountryItem item : countryList) {
if (item.getCountryName().toLowerCase().contains(filterPattern)) {
suggestions.add(item);
}
}
}
results.values = suggestions;
results.count = suggestions.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredCountryList.clear();
filteredCountryList.addAll((List) results.values);
notifyDataSetChanged();
}
#Override
public CharSequence convertResultToString(Object resultValue) {
return ((CountryItem) resultValue).getCountryName();
}
};
}
I solved it.
I have no idea why this did not appear in any tutorial I found (including the Materialdoc one), but you also have to override getItem in the adapter, to pick it's item from the filtered List, not the original List:
public CountryItem getItem(int position) {
return filteredCountryList.get(position);
}
i provide one adapter class that used recylerview adapter for user contact adapter that filter user contact. you can make changes your requirement according into code..
public class InviteContactAdapter extends RecyclerView.Adapter<InviteContactAdapter.ItemViewHolder> implements Filterable {
private List<UserContact> mContactList = new ArrayList<>();
private List<UserContact> mContectFilter = new ArrayList<>();
private Context mContext;
private CustomFilter mFilter;
public List<String> mEmailList = new ArrayList<>();
public InviteContactAdapter(Context context, List<UserContact> mContactList) {
mContext = context;
this.mContactList = mContactList;
this.mContectFilter = mContactList;
mFilter = new CustomFilter();
}
public onItemClickListener onItemClickListener;
public void setOnItemClickListener(InviteContactAdapter.onItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.invite_contact_row_layout, viewGroup, false);
return new ItemViewHolder(view);
}
public interface onItemClickListener {
void onClick(UserContact contact);
}
#Override
public Filter getFilter() {
return mFilter;
}
#Override
public void onBindViewHolder(final ItemViewHolder itemViewHolder, int i) {
final UserContact contact = mContectFilter.get(i);
itemViewHolder.mTvUserNane.setText(contact.getUserName().trim());
itemViewHolder.mTvUserEmail.setText(contact.getUserEmail().trim());
if (contact.isSelect())
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
else
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (contact.isSelect()) {
contact.setSelect(false);
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
} else {
contact.setSelect(true);
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
}
}
});
}
#Override
public int getItemCount() {
return mContectFilter.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView mTvUserNane, mTvUserEmail;
private ImageView mIvSelect;
public ItemViewHolder(View itemView) {
super(itemView);
mTvUserEmail = itemView.findViewById(R.id.icrlTvUserEmail);
mTvUserNane = itemView.findViewById(R.id.icrlTvUserName);
mIvSelect = itemView.findViewById(R.id.icrlIvSelect);
}
}
public List<String> getEmail() {
mEmailList.clear();
for (UserContact contact : mContectFilter) {
if (contact.isSelect()) {
mEmailList.add(contact.getUserEmail());
}
}
return mEmailList;
}
/**
* this class for filter data.
*/
class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence != null && charSequence.length() > 0) {
ArrayList<UserContact> filters = new ArrayList<>();
charSequence = charSequence.toString().toUpperCase();
for (int i = 0; i < mContactList.size(); i++) {
if (mContactList.get(i).getUserName().toUpperCase().contains(charSequence) || mContactList.get(i).getUserEmail().toUpperCase().contains(charSequence)) {
UserContact contact = new UserContact();
contact.setUserName(mContactList.get(i).getUserName());
contact.setUserEmail(mContactList.get(i).getUserEmail());
filters.add(contact);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count = mContactList.size();
results.values = mContactList;
}
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mContectFilter = (ArrayList<UserContact>) filterResults.values;
notifyDataSetChanged();
}
}
}
ArrayList<YourModel> arrayList = new ArrayList<>();
arrayList.addAll(yourList);
AutoCompleteAdapter autoCompleteAdapter = new AutoCompleteAdapter(context, arrayList);
autoCompleteTextView.setAdapter(brandAdapter);
autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
YourModel model = (YourModel) autoCompleteAdapter.getItem(position);
autoCompleteTextView.setText(model.getText());
autoCompleteTextView.setSelection(model.getText().length());
}
});
AutoCompleteAdapter.java
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<YourModel> originalList;
private ArrayList<YourModel> suggestions = new ArrayList<>();
private Filter filter = new CustomFilter();
public AutoCompleteAdapter(Context context, ArrayList<YourModel> originalList) {
this.context = context;
this.originalList = originalList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_filter, parent, false);
}
YourModel model = suggestions.get(position);
AppCompatTextView tvTitle = convertView.findViewById(R.id.tvTitle);
tvTitle.setText(model.getText());
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
#Override
public Object getItem(int position) {
return suggestions.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public int getCount() {
return suggestions.size();
}
#Override
public Filter getFilter() {
return filter;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
suggestions.clear();
if (originalList != null && constraint != null) {
for (int i = 0; i < originalList.size(); i++) {
if (originalList.get(i).getText().toLowerCase().contains(constraint.toString().toLowerCase().trim())) {
suggestions.add(originalList.get(i));
}
}
}
FilterResults results = new FilterResults();
results.values = suggestions;
results.count = suggestions.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}

MultiAutoCompleteTextView show wrong result

I have some problem with MultiAutoCompleteTextView, all seems to work correctly, writing on textedit I get the correct filtered values, the problem when I select a value, after click I get on textedit the wrong value, seems to be the first or second value of users instead filteredUser...where is the mistake?
public class AutocompleteUserAdapter extends ArrayAdapter {
private FriendOption selectedUser;
private final List<FriendOption> users;
private List<FriendOption> filteredUser = new ArrayList<>();
public AutocompleteUserAdapter(Context context, List<FriendOption> users) {
super(context, 0, users);
this.users = users;
}
#Override
public int getCount() {
return filteredUser.size();
}
public FriendOption getFilteredItemAtPosition(int pos){
return this.filteredUser.get(pos);
}
#Override
public Filter getFilter() {
return new UsersFilter(this, users);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
FriendOption user = filteredUser.get(position);
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_user_simple, parent, false);
TextView textViewName = (TextView) convertView.findViewById(R.id.user_name);
textViewName.setText(user.getFriend().getName() + " " + user.getFriend().getSurname());
return convertView;
}
class UsersFilter extends Filter {
AutocompleteUserAdapter adapter;
List<FriendOption> originalList;
List<FriendOption> filteredList;
public UsersFilter(AutocompleteUserAdapter adapter, List<FriendOption> originalList) {
super();
this.adapter = adapter;
this.originalList = originalList;
this.filteredList = new ArrayList<>();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
filteredList.clear();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(originalList);
}
else {
final String filterPattern = constraint.toString().toLowerCase().trim();
for (final FriendOption user: originalList) {
String name = user.getFriend().getName().toLowerCase();
if (name.contains(filterPattern)) {
filteredList.add(user);
}
}
}
final FilterResults results = new FilterResults();
results.values = filteredList;
results.count = filteredList.size();
return results;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.values != null){
adapter.filteredUser.clear();
adapter.filteredUser.addAll((List) results.values);
for (FriendOption u:adapter.filteredUser){
System.out.println("user: " + u.getFriend().getName() + " " + u.getFriend().getSurname());
}
adapter.notifyDataSetChanged();
}
}
#Override
public String convertResultToString(Object resultValue) {
String result = ((FriendOption) resultValue).getFriend().getName() + " "+ ((FriendOption) resultValue).getFriend().getSurname();
return result;
}
}
find the problem, forgot
#Override
public Object getItem(int position) {
return filteredUser.get(position);
}

Android : Filterable not working on text clear

I have custom listview and I have implemented SearchView to filter data. When we type something for search listview get filter correctly, but when I clear some characters from search text listview doesn't filter data. It remain constant at last search position.
Let me explain with screenshots.
Here, List is not yet filtered. all item are present.
I am searching in two fields of each item(name and description).
In this screen I have searched from cam it shows me correct result.
I have clear text till c and I am expecting resut should be two item i.e. camera and LED TV.
Here is my code.
RateListAdapter.java
public class RateListAdapter extends BaseAdapter implements Filterable {
Context context;
private SparseBooleanArray mSelectedItemsIds;
public ArrayList<RateList> itemRateList;
public LayoutInflater inflater = null;
public ArrayList<RateList> tempList;
CustomFilter filter;
public RateListAdapter(Context context, ArrayList<RateList> itemRateList) {
this.context = context;
this.itemRateList = itemRateList;
mSelectedItemsIds = new SparseBooleanArray();
this.tempList = itemRateList;
}
#Override
public int getCount() {
return itemRateList.size();
}
#Override
public RateList getItem(int i) {
return itemRateList.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
class Holder {
TextView tv_name, tv_description, tv_amount;
ImageView iv_itemImage;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
Holder h = new Holder();
RateList rateList = itemRateList.get(i);
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.rate_list_item, viewGroup, false);
}
h.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
h.tv_description = (TextView) convertView.findViewById(R.id.tv_description);
h.tv_amount = (TextView) convertView.findViewById(R.id.tv_amount);
h.iv_itemImage = (ImageView) convertView.findViewById(R.id.iv_itemImage);
h.tv_name.setText(rateList.Name);
h.tv_description.setText(rateList.description);
h.tv_amount.setText("₹ "+rateList.amount);
Picasso.with(context).load(rateList.image).resize(92,92).into(h.iv_itemImage);
return convertView;
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
public void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
notifyDataSetChanged();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}
#Override
public Filter getFilter() {
if(filter == null)
{
filter=new CustomFilter();
}
return filter;
}
private class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if(constraint != null && constraint.length()>0) {
constraint=constraint.toString().toLowerCase();
ArrayList<RateList> filters=new ArrayList<RateList>();
for(int i=0;i<itemRateList.size();i++) {
if (itemRateList.get(i).Name.toLowerCase().contains(constraint) ||
itemRateList.get(i).description.toLowerCase().contains(constraint)) {
RateList r = new RateList();
r.Name = itemRateList.get(i).Name;
r.description= itemRateList.get(i).description;
r.id = itemRateList.get(i).id;
r.image = itemRateList.get(i).image;
r.amount = itemRateList.get(i).amount;
filters.add(r);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count=itemRateList.size();
results.values=itemRateList;
}
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
itemRateList=(ArrayList<RateList>) results.values;
notifyDataSetChanged();
}
}
}
searchview code of
BookingFrament.java
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String searchQuery) {
rateListAdapter.getFilter().filter(searchQuery);
return false;
}
});
Please help.
This is because you are modifying the itemRateList
Check this method:
#Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
itemRateList=(ArrayList<RateList>) results.values;
notifyDataSetChanged();
}
I will suggest to store the result in a separate arrayList and use it in for you adapter class.
Due to the above result being updated in the original itemRateList, so next time when the performFiltering method is invoked. You are iterating just the previous result and NOT the original list.
Hope this helps.

android SimpleSectionAdapter from adapter displaying empty list

i really need help debugging this android app i am building. I have a custom adapter. when i dont use it with simpleSectionAdapter it displays list items correctly, but when i use SimpleSectionAdapter from adapter kit, it displays blank list. I want to have sections in my list according to names. Thanks in advance.
Heres's my adapter
public class CustomContriAdapter extends BaseAdapter implements Filterable{
List<Contributions> contributions;
LayoutInflater inflater;
Context context;
public List<Contributions> orig;
public CustomContriAdapter(Context context, List<Contributions> contributions) {
this.contributions = contributions;
this.context = context;
inflater = LayoutInflater.from(this.context);
}
#Override
public int getCount() {
return contributions.size();
}
#Override
public Object getItem(int position) {
return contributions.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final List<Contributions> results = new ArrayList<Contributions>();
if (orig == null)
orig = contributions;
if (constraint != null) {
if (orig != null && orig.size() > 0) {
for (final Contributions g : orig) {
if (g.getContributor_name().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
Filter.FilterResults results) {
contributions = (ArrayList<Contributions>) results.values;
notifyDataSetChanged();
}
};
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyViewHolder mViewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.contri_list_item_layout, parent, false);
mViewHolder = new MyViewHolder(convertView);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
}
Contributions currentListData = (Contributions) getItem(position);
mViewHolder.tvTitleName.setText(currentListData.getContributor_name());
//date created at
Date createdAt = currentListData.getCreated();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String createdDate = df.format(createdAt);
mViewHolder.tvDescDate.setText(createdDate);
return convertView;
}
private class MyViewHolder {
TextView tvTitleName, tvDescDate;
public MyViewHolder(View item) {
tvTitleName = (TextView) item.findViewById(R.id.name_view);
tvDescDate = (TextView) item.findViewById(R.id.contri_created_date);
}
}
}
here's how am calling it in the onCreate()
Collections.sort(allContributions, new Comparator<Contributions>() {
#Override
public int compare(Contributions lhs, Contributions rhs) {
return lhs.getContributor_name().compareTo(rhs.getContributor_name());
}
});
InstantAdapter<Contributions> contribu = new InstantAdapter<Contributions>(
this,R.layout.contri_list_item_layout, Contributions.class, allContributions);
//wrap adapter to simple section adapter
SimpleSectionAdapter<Contributions> sectionAdapter = new SimpleSectionAdapter<Contributions>(
this, contribu, R.layout.section_header, R.id.section_text , new ContributionsSectionizer());
listView.setAdapter(sectionAdapter);
here's the sectionizer,
public class ContributionsSectionizer implements Sectionizer<Contributions> {
#Override
public String getSectionTitleForItem(Contributions contributions) {
return contributions.getContributor_name();
}
}
and the items
protected List<Contributions> allContributions = new ArrayList<>();

Filtered custom adapter gets wrong item position

My problem is that filtered custom adapter returns wrong item position. The listfragment is filtered good but when I click on the thumbnail it shows the video corresponding to the unfiltered list.
public static final class PageAdapter extends BaseAdapter implements
Filterable {
private List<VideoEntry> entries;
private List<VideoEntry> filteredData;
private final List<View> entryViews;
private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap;
private final LayoutInflater inflater;
private final ThumbnailListener thumbnailListener;
private boolean labelsVisible;
public PageAdapter(Context context, List<VideoEntry> entries) {
this.entries = entries;
filteredData = entries;
entryViews = new ArrayList<View>();
thumbnailViewToLoaderMap = new HashMap<YouTubeThumbnailView, YouTubeThumbnailLoader>();
inflater = LayoutInflater.from(context);
thumbnailListener = new ThumbnailListener();
labelsVisible = true;
}
public void releaseLoaders() {
for (YouTubeThumbnailLoader loader : thumbnailViewToLoaderMap
.values()) {
loader.release();
}
}
public void setLabelVisibility(boolean visible) {
labelsVisible = visible;
for (View view : entryViews) {
view.findViewById(R.id.text).setVisibility(
visible ? View.VISIBLE : View.GONE);
}
}
#Override
public int getCount() {
return entries.size();
}
#Override
public VideoEntry getItem(int position) {
return entries.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
try {
VideoEntry entry = entries.get(position);
/*
* int REFRESH_THRESHOLD; if(getCount() - position <=
* REFRESH_THRESHOLD){ //If there are more items to fetch, and a
* network request isn't already underway if(loading == false &&
* has_remaining_items == true){ new JSONParse().execute(); }
*/
// There are three cases here
if (view == null) {
// 1) The view has not yet been created - we need to
// initialize
// the YouTubeThumbnailView.
view = inflater.inflate(R.layout.video_list_item, parent,
false);
YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view
.findViewById(R.id.thumbnail);
thumbnail.setTag(entry.videoId);
thumbnail.initialize(DeveloperKey.DEVELOPER_KEY,
thumbnailListener);
} else {
YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view
.findViewById(R.id.thumbnail);
YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap
.get(thumbnail);
if (loader == null) {
// 2) The view is already created, and is currently
// being
// initialized. We store the
// current videoId in the tag.
thumbnail.setTag(entry.videoId);
} else {
// 3) The view is already created and already
// initialized.
// Simply set the right videoId
// on the loader.
thumbnail.setImageResource(R.drawable.loading_thumbnail);
loader.setVideo(entry.videoId);
}
}
TextView label = ((TextView) view.findViewById(R.id.text));
label.setText(entry.text);
label.setVisibility(labelsVisible ? View.VISIBLE : View.GONE);
} catch (IndexOutOfBoundsException e) {
}
return view;
}
private final class ThumbnailListener implements
YouTubeThumbnailView.OnInitializedListener,
YouTubeThumbnailLoader.OnThumbnailLoadedListener {
#Override
public void onInitializationSuccess(YouTubeThumbnailView view,
YouTubeThumbnailLoader loader) {
loader.setOnThumbnailLoadedListener(this);
thumbnailViewToLoaderMap.put(view, loader);
view.setImageResource(R.drawable.loading_thumbnail);
String videoId = (String) view.getTag();
loader.setVideo(videoId);
}
#Override
public void onInitializationFailure(YouTubeThumbnailView view,
YouTubeInitializationResult loader) {
view.setImageResource(R.drawable.no_thumbnail);
}
#Override
public void onThumbnailLoaded(YouTubeThumbnailView view,
String videoId) {
}
#Override
public void onThumbnailError(YouTubeThumbnailView view,
ErrorReason errorReason) {
view.setImageResource(R.drawable.no_thumbnail);
}
}
public Filter getFilter() {
// TODO Auto-generated method stub
return new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults result) {
if (result.count == 0)
notifyDataSetInvalidated();
else {
entries = (List<VideoEntry>) result.values;
notifyDataSetChanged();
}
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
final FilterResults result = new FilterResults();
if (constraint == null || constraint.length() == 0) {
result.values = filteredData;
result.count = filteredData.size();
} else {
List<VideoEntry> myList = new ArrayList<VideoEntry>();
for (int i = 0; i < filteredData.size(); i++) {
VideoEntry m = filteredData.get(i);
String data = m.text;
if (data.toLowerCase().contains(constraint))
myList.add(m);
}
result.count = myList.size();
result.values = myList;
}
return result;
}
};
}
}
SOLVED! Thank you for your precious help!
I pchange two rows onListItemClick :
VideoEntry currentEntry = adapter.getItem(position);
String videoId = currentEntry.videoId;
I've a listfragment with onlistitemclick
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
String videoId = VIDEO_LIST.get(position).videoId;
String mdbtitle = VIDEO_LIST.get(position).text;
ClassString gs = (ClassString) getActivity().getApplication();
gs.setTitle(mdbtitle);
Intent i = new Intent(getActivity(), MovieDb.class);
getActivity().startService(i);
Log.d("MyfActivity", "E' stata chiamata la classe MovieDb");
VideoFragment videoFragment = (VideoFragment) getFragmentManager()
.findFragmentById(R.id.video_fragment_container);
videoFragment.setVideoId(videoId);
Log.d("MyLog", mdbtitle);
// The videoBox is INVISIBLE if no video was previously selected, so
// we need to show it now.
if (videoBox.getVisibility() != View.VISIBLE) {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Initially translate off the screen so that it can be
// animated in from below.
videoBox.setTranslationY(videoBox.getHeight());
}
videoBox.setVisibility(View.VISIBLE);
}
// If the fragment is off the screen, we animate it in.
if (videoBox.getTranslationY() > 0) {
videoBox.animate().translationY(0)
.setDuration(ANIMATION_DURATION_MILLIS);
}
}
What helped me with a similar problem was to take a look at the android source, so you don't have to reinvent the wheel.
#Override
public Filter getFilter() {
if (mFilter == null)
mFilter = new MyFilter();
return mFilter;
}
public class MyFilter extends Filter {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults result) {
entries = (List<VideoEntry>) result.values;
if (result.count > 0)
notifyDataSetChanged();
else {
notifyDataSetInvalidated();
}
}
#Override
public FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
synchronized (mLock) {
mOriginalValues = new ArrayList<VideoEntry>(entries);
}
}
if (prefix == null || prefix.length() == 0) {
ArrayList<VideoEntry> list;
synchronized (mLock) {
list = new ArrayList<VideoEntry>(mOriginalValues);
}
results.values = list;
results.count = list.size();
} else {
String prefixString = prefix.toString().toLowerCase(Locale.ENGLISH);
ArrayList<VideoEntry> values;
synchronized (mLock) {
values = new ArrayList<VideoEntry>(mOriginalValues);
}
final int count = values.size();
final ArrayList<VideoEntry> filteredData = new ArrayList<VideoEntry>();
for (int i = 0; i < count; i++) {
final VideoEntry value = values.get(i);
final String valueText = value.text.toLowerCase(Locale.ENGLISH);
if (valueText.contains(prefixString)) {
filteredData.add(value);
}
}
results.values = filteredData;
results.count = filteredData.size();
}
return results;
}
};
and on top declare also the fields:
private List<VideoEntry> entries;
private ArrayList<VideoEntry> mOriginalValues;
private final Object mLock = new Object();
private Filter mFilter;
but remove:
private List<VideoEntry> filteredData;
and remember to get a reference from the filtered list in your OnItemClickListener or whatever click listener you have:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// in order to refer to the filtered item
VideoEntry currentEntry = customAdapter.getItem(position);
//...
}

Categories

Resources