RecyclerView过滤的奇怪行为

时间:2017-04-10 17:29:49

标签: java android android-recyclerview

根据this说明,我已在我的应用中创建了RecyclerView过滤功能。几乎一切都很好,但有两件奇怪的事情。

当我在搜索视图中输入文字时,只有一个符合要求的项目,直到我隐藏键盘,我才能看到这个项目。

第二个问题更复杂,因为它经常发生。我在RecyclerView中的项目在背景中有一个图像,并不总是正确加载过滤图像。

因为我现在的描述可能不清楚这里是一个显示问题的gif: Gif with problem

这是我的适配器类:

package com.ostojan.x360.view;

import android.support.v7.util.SortedList;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.ostojan.x360.R;
import com.ostojan.x360.model.Game;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class GameAdapter extends RecyclerView.Adapter<GameViewHolder> {

    private SortedList<Game> games;
    private ArrayList<Game> allGames;
    private View.OnClickListener onClickListener;

    public GameAdapter(View.OnClickListener onClickListener, List<Game> games) {
        this(onClickListener);
        this.games.addAll(games);
        this.allGames.addAll(games);
    }

    public GameAdapter(View.OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
        this.games = new SortedList<Game>(Game.class, new GamesSortedListCallback(this));
        this.allGames = new ArrayList<>();
    }

    @Override
    public GameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_game, parent, false);
        view.setOnClickListener(onClickListener);
        return new GameViewHolder(view);
    }

    @Override
    public void onBindViewHolder(GameViewHolder holder, int position) {
        Game game = games.get(position);
        holder.title.setText(game.getTitle());
        Picasso.with(holder.itemView.getContext())
                .load(game.getCoverLink().toString())
                .placeholder(R.drawable.ic_loading)
                .fit()
                .centerCrop()
                .error(R.drawable.ic_error)
                .into(holder.coverImage);
    }

    @Override
    public int getItemCount() {
        return games.size();
    }

    public void add(Game game) {
        this.games.add(game);
        this.allGames.add(game);
        notifyDataSetChanged();
    }

    public void addAll(Collection<Game> games) {
        this.games.addAll(games);
        this.allGames.addAll(games);
        notifyDataSetChanged();
    }

    public void remove(Game game) {
        games.beginBatchedUpdates();
        games.remove(game);
        allGames.remove(game);
        games.endBatchedUpdates();
    }

    public void replaceAll(Collection<Game> games) {
        this.games.beginBatchedUpdates();
        List<Game> gamesToRemove = new ArrayList<>();
        for (int i = 0; i < this.games.size(); i++) {
            Game game = this.games.get(i);
            if (!games.contains(game)) {
                gamesToRemove.add(game);
            }
        }
        for (Game game : gamesToRemove) {
            this.games.remove(game);
        }
        this.games.addAll(games);
        this.games.endBatchedUpdates();
    }

    public Game get(int index) {
        return this.games.get(index);
    }

    public Collection<Game> getGames() {
        return allGames;
    }

    public void clear() {
        this.games.clear();
        notifyDataSetChanged();
    }

    public void search(String query) {
        replaceAll(filterGames(query));
    }

    private Collection<Game> filterGames(String query) {
        query = query.toLowerCase();
        List<Game> filteredGames = new ArrayList<>();
        for (Game game : allGames) {
            String gameTitle = game.getTitle().toLowerCase();
            if (gameTitle.contains(query)) {
                filteredGames.add(game);
            }
        }
        return filteredGames;
    }
}

查看持有人:

package com.ostojan.x360.view;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.ostojan.x360.R;

import butterknife.BindView;
import butterknife.ButterKnife;

public class GameViewHolder extends RecyclerView.ViewHolder {

    @BindView(R.id.text_title)
    TextView title;
    @BindView(R.id.image_cover)
    ImageView coverImage;

    public GameViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}

SortedList回调:

package com.ostojan.x360.view;

import android.support.v7.util.SortedList;
import android.support.v7.widget.RecyclerView;

import com.ostojan.x360.model.Game;

import java.util.Comparator;

public class GamesSortedListCallback extends SortedList.Callback<Game> {
    private static final Comparator<Game> GAMES_COMPARATOR = new Comparator<Game>() {
        @Override
        public int compare(Game o1, Game o2) {
            return o1.getId().compareTo(o2.getId());
        }
    };
    private RecyclerView.Adapter<GameViewHolder> adapter;

    public GamesSortedListCallback(RecyclerView.Adapter<GameViewHolder> adapter) {
        this.adapter = adapter;
    }
    @Override
    public int compare(Game o1, Game o2) {
        return GAMES_COMPARATOR.compare(o1, o2);
    }

    @Override
    public void onChanged(int position, int count) {
        adapter.notifyItemRangeChanged(position, count);
    }

    @Override
    public boolean areContentsTheSame(Game oldItem, Game newItem) {
        return oldItem.equals(newItem);
    }

    @Override
    public boolean areItemsTheSame(Game item1, Game item2) {
        return item1.getId() == item1.getId();
    }

    @Override
    public void onInserted(int position, int count) {
        adapter.notifyItemRangeInserted(position, count);
    }

    @Override
    public void onRemoved(int position, int count) {
        adapter.notifyItemRangeRemoved(position, count);
    }

    @Override
    public void onMoved(int fromPosition, int toPosition) {
        adapter.notifyItemMoved(fromPosition, toPosition);
    }
}

在这里我如何调用活动过滤:

RecyclerView gamesList;
GameAdapter gamesAdapter;

@Override
public boolean onQueryTextSubmit(String query) {
    onQueryTextChange(query);
    return true;
}

@Override
public boolean onQueryTextChange(String newText) {
    gamesAdapter.search(newText);
    gamesList.scrollToPosition(0);
    return true;
}

0 个答案:

没有答案