Question

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;
        }
    };
}
}
Was it helpful?

Solution

SOLVED! Thank you for your precious help! I pchange two rows onListItemClick : VideoEntry currentEntry = adapter.getItem(position); String videoId = currentEntry.videoId;

OTHER TIPS

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);

    //...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top