Android每次上下滚动时RecyclerView显示的项目都变了

Android RecyclerView displayed item changed when I scrolled up and down everytime

我正在使用解析服务器开发使用 RecyclerView 显示图像项的应用程序。

但问题是每次上下滚动时,视图中显示的项目都会发生变化。

我想知道我的代码有什么问题。

如果你看到下面的图片,你会发现物品正在改变它们的位置。

我试图在再次调用持有人之前让持有人图像变为空。但它不工作。估计是调用item时更改了item的位置号again.but找不到原因

enter image description here enter image description here

RecyclerParseAdapter.java

public class MyTimelineAdapter extends RecyclerParseAdapter {

private interface OnQueryLoadListener<ParseObject> {

    public void onLoading();
    public void onLoaded(List<ParseObject> objects, Exception e);

}

private static ParseQueryAdapter.QueryFactory<ParseObject> queryFactory;
private static List<OnQueryLoadListener<ParseObject>> onQueryLoadListeners;
private static List<List<ParseObject>> objectPages;
private static ArrayList<ParseObject> items;
private static int currentPage;


private static RequestManager requestManager;


public MyTimelineAdapter(Context context, RequestManager requestManager) {

    super(context);
    this.requestManager = requestManager;

    this.onQueryLoadListeners = new ArrayList<>();
    this.currentPage = 0;
    this.objectPages = new ArrayList<>();
    this.items = new ArrayList<>();



    this.queryFactory = new ParseQueryAdapter.QueryFactory<ParseObject>() {
        @Override
        public ParseQuery<ParseObject> create() {

            ParseQuery<ParseObject> query = ParseQuery.getQuery("ImageClassName");
            query.setCachePolicy(ParseQuery.CachePolicy.CACHE_THEN_NETWORK);
            query.whereEqualTo("status", true);
            query.orderByDescending("createdAt");

            return query;
        }
    };

    loadObjects(currentPage);

}



@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View timelineView;

    timelineView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_timeline_item2, parent, false);

    TimelineItemViewHolder timelineItemViewHolder = new TimelineItemViewHolder(timelineView);

    return timelineItemViewHolder;

}



@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    final ParseObject timelineOb = getItem(position);

    FunctionPost functionPost = new FunctionPost(context);
    functionPost.TimelineArtistPostAdapterBuilder( timelineOb, holder, requestManager);

    //기능 추가

}



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

@Override
public ParseObject getItem(int position) {
    return items.get(position);
}

@Override
public void loadObjects(final int page) {

    final ParseQuery<ParseObject> query = this.queryFactory.create();

    if (this.objectsPerPage > 0 && this.paginationEnabled) {

        this.setPageOnQuery(page, query);

    }

    this.notifyOnLoadingListeners();


    if (page >= objectPages.size()) {

        objectPages.add(page, new ArrayList<ParseObject>());

    }


    query.findInBackground(new FindCallback<ParseObject>() {
        @Override
        public void done(List<ParseObject> foundObjects, ParseException e) {

            if ((e != null) && ((e.getCode() == ParseException.CONNECTION_FAILED) || (e.getCode() != ParseException.CACHE_MISS))) {

                hasNextPage = true;

            } else if (foundObjects != null) {

                // Only advance the page, this prevents second call back from CACHE_THEN_NETWORK to
                // reset the page.
                if (page >= currentPage) {
                    currentPage = page;

                    // since we set limit == objectsPerPage + 1
                    hasNextPage = (foundObjects.size() > objectsPerPage);
                }

                if (paginationEnabled && foundObjects.size() > objectsPerPage) {
                    // Remove the last object, fetched in order to tell us whether there was a "next page"
                    foundObjects.remove(objectsPerPage);
                }

                List<ParseObject> currentPage = objectPages.get(page);
                currentPage.clear();
                currentPage.addAll(foundObjects);
                syncObjectsWithPages(items, objectPages);

                // executes on the UI thread
                notifyDataSetChanged();

            }

            notifyOnLoadedListeners(foundObjects, e);


        }
    });
}


public void loadNextPage() {

    if (items.size() == 0) {

        loadObjects(0);

    } else {

        loadObjects(currentPage + 1);

    }
}



public void syncObjectsWithPages(ArrayList<ParseObject> items, List<List<ParseObject>> objectPages) {

    items.clear();

    for (List<ParseObject> pageOfObjects : objectPages) {

        items.addAll(pageOfObjects);

    }
}

protected void setPageOnQuery(int page, ParseQuery<ParseObject> query) {

    query.setLimit(this.objectsPerPage + 1);

    query.setSkip(page * this.objectsPerPage);

}

public void addOnQueryLoadListener(OnQueryLoadListener<ParseObject> listener) {

    this.onQueryLoadListeners.add(listener);

}

public void removeOnQueryLoadListener(OnQueryLoadListener<ParseObject> listener) {

    this.onQueryLoadListeners.remove(listener);

}

public void notifyOnLoadingListeners() {

    for (OnQueryLoadListener<ParseObject> listener : this.onQueryLoadListeners) {

        listener.onLoading();

    }

}

public void notifyOnLoadedListeners(List<ParseObject> objects, Exception e) {

    for (OnQueryLoadListener<ParseObject> listener : this.onQueryLoadListeners) {

        listener.onLoaded(objects, e);

    }

}


}

我确实找到了问题

我在适配器中添加了覆盖方法,然后找到了。

@Override
public int getItemViewType(int position) {
    return position;
}

我不确定为什么现在会这样。谁能帮我知道问题的原因?

前几天我遇到了类似的问题。 onBindViewHolder 需要知道在调用时如何显示该行。我根据需要在 getItemViewType 中返回了两种不同的视图类型,在 onCreateViewHolder 中有条件地扩充了视图类型,然后我能够根据需要在 ViewHolder 上设置数据。