【问题标题】:Wrong Position after Filtering and on Click in Recyclerview在 Recyclerview 中过滤和点击后位置错误
【发布时间】:2017-12-05 04:49:16
【问题描述】:

我已经在我的应用中实现了 SearchView。但我面临的问题是回收器视图在过滤后返回错误的位置。过滤后如何获得确切位置。

这是我的适配器代码:-

public class UserListAdapter extends Adapter<UserListAdapter.DataObjectHolder> implements Filterable {
private static MyClickListener myClickListener;
public Activity activity;
Bitmap bitmap;
ImageView imgUserBig;
TextView txtUserName;
RelativeLayout userProfileView;
private ArrayList<DataObject> mArrayList;
private ArrayList<DataObject> mFilteredList;    

public UserListAdapter(Activity a, ArrayList<DataObject> d, ImageView mImgUserBig, RelativeLayout viewLinear, TextView txtUsername) {

    this.activity = a;
    this.mArrayList = d;
    this.mFilteredList = d;
    this.imgUserBig = mImgUserBig;
    this.userProfileView = viewLinear;
    this.txtUserName = txtUsername;
}

public DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new DataObjectHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.raw_user_list, parent, false));
}

public void onBindViewHolder(final DataObjectHolder holder, final int position) {
    holder.txtName.setText((mFilteredList.get(position)).getmName());
    holder.txtUserName.setText((mFilteredList.get(position)).getmUsername());
    Glide.with(activity.getApplicationContext()).load((mFilteredList.get(position)).getmImage()).into(holder.imgUser);
    Glide.with(activity).load((mFilteredList.get(position)).getmImage()).asBitmap().into(new SimpleTarget<Bitmap>(Integer.MIN_VALUE, Integer.MIN_VALUE) {
        public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
            bitmap = resource;
            (mFilteredList.get(position)).setBitmap(bitmap);
        }
    });
    holder.imgUser.setOnClickListener(new OnClickListener() {
        public void onClick(View view) {
            if ((mFilteredList.get(position)).getBitmap() != null && imgUserBig != null) {
                zoomImageFromThumb(holder.imgUser, (mFilteredList.get(position)).getBitmap(), (mFilteredList.get(position)).getmImage(), (mFilteredList.get(position)).getmUsername());
            }
        }
    });
}

public int getItemCount() {
    return mFilteredList.size();
}

public void setOnItemClickListener(MyClickListener myClickListener) {
    UserListAdapter.myClickListener = myClickListener;
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            String charString = charSequence.toString();
            if (charString.isEmpty()) {
                mFilteredList = mArrayList;
            }else {
                ArrayList<DataObject> filteredList = new ArrayList<>();
                for (DataObject userData : mArrayList) {
                    if (userData.getmUsername().toLowerCase().contains(charString) || userData.getmName().toLowerCase().contains(charString)) {
                        filteredList.add(userData);
                    }
                }
                mFilteredList = filteredList;
            }
            FilterResults filterResults = new FilterResults();
            filterResults.values = mFilteredList;
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mFilteredList = (ArrayList<DataObject>) results.values;
            notifyDataSetChanged();
        }
    };
}

public interface MyClickListener {
    void onItemClick(int i, View view);
}

public Object getItem(int position) {
    return mFilteredList.get(position);
}



public class DataObjectHolder extends ViewHolder implements OnClickListener {
    ImageView imgUser;
    TextView txtName;
    TextView txtUserName;

    public DataObjectHolder(View itemView) {
        super(itemView);
        txtName = (TextView) itemView.findViewById(R.id.txtname);
        txtUserName = (TextView) itemView.findViewById(R.id.txtusername);
        imgUser = (ImageView) itemView.findViewById(R.id.img_user);
        itemView.setOnClickListener(this);
    }

    public void onClick(View v) {
        UserListAdapter.myClickListener.onItemClick(getPosition(), v);
    }
}}

我正在调用 getPosition() 方法来获取项目的位置,但它返回的是旧位置,而不是过滤后的位置。任何帮助将不胜感激。

【问题讨论】:

    标签: java android android-recyclerview


    【解决方案1】:

    在recyclerview 到达终点之前,使用这个类来实现滚动监听。当有 5 个项目需要滚动时,它会通知。请参阅下面的代码。

    把它作为一个单独的类放在你的项目中

    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.StaggeredGridLayoutManager;
    
    
    public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener
    {
        public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
    private int previousTotal = 0; // The total number of items in the dataset after the last load
    private boolean loading = true; // True if we are still waiting for the last set of data to load.
    private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
    int firstVisibleItem, visibleItemCount, totalItemCount;
    
    private int current_page = 0;
    
    private StaggeredGridLayoutManager mLinearLayoutManager;
    private LinearLayoutManager mLinearLayoutManagerG;
    
    public EndlessRecyclerOnScrollListener(StaggeredGridLayoutManager linearLayoutManager)
    {
        this.mLinearLayoutManager = linearLayoutManager;
    }
    
    
    public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager)
    {
        this.mLinearLayoutManagerG = linearLayoutManager;
        mLinearLayoutManager = null;
    }
    
    
    public void reset()
    {
        current_page = 0;
        previousTotal = 0;
        loading = true;
    }
    
    public void setThresHold(int threshold)
    {
        visibleThreshold = threshold;
    }
    
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy)
    {
        super.onScrolled(recyclerView, dx, dy);
    
        if (mLinearLayoutManager != null)
        {
            visibleItemCount = recyclerView.getChildCount();
            totalItemCount = mLinearLayoutManager.getItemCount();
            firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPositions(null)[0];
    
            if (loading)
            {
                if (totalItemCount > previousTotal)
                {
                    loading = false;
                    previousTotal = totalItemCount;
                }
            }
            if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold))
            {
                // End has been reached
    
                // Do something
                current_page++;
    
                onLoadMore(current_page);
    
                loading = true;
            }
        }
        else
        {
            visibleItemCount = recyclerView.getChildCount();
            totalItemCount = mLinearLayoutManagerG.getItemCount();
            firstVisibleItem = mLinearLayoutManagerG.findFirstVisibleItemPosition();
    
            if (loading)
            {
                if (totalItemCount > previousTotal)
                {
                    loading = false;
                    previousTotal = totalItemCount;
                }
            }
            if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold))
            {
                // End has been reached
    
                // Do something
                current_page++;
    
                onLoadMore(current_page);
    
                loading = true;
            }
    
        }
    
        countChange(firstVisibleItem);
    }
    
    public abstract void onLoadMore(int current_page);
    
    public abstract void countChange(int currentVisibleCount);
    }
    

    这样使用

    endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(pass your layout manager here)
        {
            @Override
            public void onLoadMore(int current_page) {
                pageNumber++;
                // Hit your api for more records 
            }
    
            @Override
            public void countChange(int currentVisibleCount) {
    
            }
        };
    
        recyclerView.setOnScrollListener(endlessRecyclerOnScrollListener);
    

    有一个名为current_page的变量,默认从0开始,你可以根据你的api更改。 visibleThreshold 表示在你的 onLoadMore 方法应该被调用多少项之前。

    示例:如果visibleThreshold 为 5 且列表中的总数据为 20,则当您的 recyclerview 滚动到第 15 位时将调用onLoadMore

    如果您有更多疑问,请告诉我。

    【讨论】:

      【解决方案2】:

      在您的 onClick 方法中使用 getAdapterPosition() 因为在单击时您想知道项目的位置。如果您在创建时进行检查,它将(大多数情况下)不准确

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-19
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        • 2022-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多