4gu*_*71n 22 android recycler-adapter android-recyclerview
我有一个RecyclerView显示两种,View一种代表用户出版物,另一种代表一种事件出版物.两者都有共同的元素,例如TextView显示时间戳的元素.所以我创建了一个PublicationViewHolder将TextView时间戳记转换为变量并加载它的方法.我的问题是适配器最初加载正确的值,但是当我向下滚动并再次向上滚动时,位置中的值会被其他位置的值更改.这是代码:
public class PublicationViewHolder extends RecyclerView.ViewHolder {
private TextView vTimeStamp;
public PublicationViewHolder(View itemView) {
super(itemView);
this.vTimeStamp = (TextView) itemView.findViewById(R.id.txt_view_publication_timestamp);
}
public void load(Publication publication, int i) {
load(publication);
try {
if (Publication.TYPE_USER_PUBLICATION == publication.getType()) {
load((UserPublication) publication);
} else if (Publication.TYPE_EVENT_PUBLICATION == publication.getType()) {
load((EventPublication) publication);
}
} catch (ClassCastException e) {
throw new RuntimeException("Publication type cast fail. See PublicationViewHolder.");
}
}
public void load(Publication publication) {
vTimeStamp.setText(DateFormatter.getTimeAgo(publication.getTimeStamp()));
}
public void load( UserPublication publication) {
//This method is override by UserPublicationViewHolder
};
public void load( EventPublication publication) {
//This method is override by EventPublicationViewHolder
};
}
Run Code Online (Sandbox Code Playgroud)
现在我UserPublicationViewHolder只为我的用户出版物.
public class UserPublicationViewHolder extends PublicationViewHolder {
private ImageView vImageView, vLikeButton, vDislikeButton, vFavButton, vEditPost, vDeletePost;
private TextView vText, vUsername, vLikeCount, vDislikeCount, vFavCount;
private PostImagesLayout vImagesContainer;
private TagCloudLocationFriends tagsView;
public UserPublicationViewHolder(View itemView) {
super(itemView);
vImageView = (ImageView) itemView.findViewById(R.id.img_view_publication_user);
vText = (TextView) itemView.findViewById(R.id.txt_view_publication_text);
vLikeCount = (TextView) itemView.findViewById(R.id.txt_view_like_count);
vFavCount = (TextView) itemView.findViewById(R.id.txt_view_fav_count);
vDislikeCount = (TextView) itemView.findViewById(R.id.txt_view_dislike_count);
vUsername = (TextView) itemView.findViewById(R.id.txt_view_publication_user_name);
vLikeButton = (ImageView) itemView.findViewById(R.id.img_view_like);
vDislikeButton = (ImageView) itemView.findViewById(R.id.img_view_dislike);
vFavButton = (ImageView) itemView.findViewById(R.id.img_view_fav);
vImagesContainer = (PostImagesLayout) itemView.findViewById(R.id.container_post_images);
tagsView = (TagCloudLocationFriends) itemView.findViewById(R.id.location_friends_tag);
// edit - remove icons
vDeletePost = (ImageView) itemView.findViewById(R.id.img_view_delete_post);
vEditPost = (ImageView) itemView.findViewById(R.id.img_view_edit_post);
}
@Override
public void load(UserPublication publication) {
//Load the UserPublicationViewHolder specific views.
}
}
Run Code Online (Sandbox Code Playgroud)
现在我将对事件出版物做同样的事情
public class EventPublicationViewHolder extends PublicationViewHolder {
private TextView vTextViewTitle;
private TextView vTextViewText;
public EventPublicationViewHolder(View itemView) {
super(itemView);
vTextViewTitle = (TextView) itemView.findViewById(R.id.txt_view_publication_event_title);
vTextViewText = (TextView) itemView.findViewById(R.id.txt_view_publication_event_text);
}
@Override
public void load(EventPublication publication) {
//Load the EventPublicationViewHolder specifics views
}
}
Run Code Online (Sandbox Code Playgroud)
现在这是我的RecyclerView适配器:
public class PublicationAdapter extends RecyclerView.Adapter<PublicationViewHolder> {
public static final int USER_PUBLICATION_TYPE = 1;
public static final int EVENT_PUBLICATION_TYPE = 2;
private List<Publication> publications = new ArrayList<Publication>();
public List<Publication> getPublications() {
return publications;
}
public void setPublications(List<Publication> publications) {
this.publications = publications;
}
@Override
public int getItemViewType(int position) {
if (publications.get(position) instanceof UserPublication) {
return USER_PUBLICATION_TYPE;
}
if (publications.get(position) instanceof EventPublication) {
return EVENT_PUBLICATION_TYPE;
}
throw new RuntimeException("Unknown view type in PublicationAdapter");
}
@Override
public PublicationViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
View v;
switch (type) {
case USER_PUBLICATION_TYPE:
v = LayoutInflater.from(getActivity()).inflate(R.layout.view_holder_user_publication, viewGroup, false);
return new UserPublicationViewHolder(v);
case EVENT_PUBLICATION_TYPE:
v = LayoutInflater.from(getActivity()).inflate(R.layout.view_holder_event_publication, viewGroup, false);
return new EventPublicationViewHolder(v);
}
return null;
}
@Override
public void onBindViewHolder(PublicationViewHolder aPublicationHolder, int i) {
aPublicationHolder.load(publications.get(i), i);
}
@Override
public long getItemId(int position) {
//Here I tried returning only position or 0 without luck.
//The id is unique BTW
return publications.get(position).getId();
}
@Override
public int getItemCount() {
return publications.size();
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道会出现什么问题,UserPublication和EventPublication都来自Publication.我没有做一些请求或重新加载适配器.我只加载适配器一次.
更新:
BTW我在片段中使用这个RecyclerView,它装载在一个PageAdapter中,它装载在片段内的ViewPager中,这可能是个问题吗?
更新: 这是其他绑定代码.
这是负载方法UserPublicationViewHolder.
@Override
public void load(UserPublication publication) {
PicassoHelper.publicationUser(getActivity(), publication.getUser().getAvatarUrl(),
vImageView);
vText.setText(publication.getText());
vUsername.setText(publication.getUser().getName());
boolean hasLocation = false;
if (publication.getImages().length > 0) {
vImagesContainer.setImages(publication.getImages());
} else {
vImagesContainer.setVisibility(View.GONE);
}
tagsView.setTags(new ArrayList<MinikastTag>());
tagsView.drawTags();
if(publication.getLocation() != null || publication.getTaggedFriends().size() > 0){
if(publication.getLocation() != null){
hasLocation = true;
tagsView.add(new MinikastTag(1,"Post from ",1));
tagsView.add(new MinikastTag(2, publication.getLocation().getName(), 2));
}
if(publication.getTaggedFriends().size() > 0){
if(hasLocation)
tagsView.add(new MinikastTag(3," with ",1));
else
tagsView.add(new MinikastTag(3,"With ",1));
int i = 0;
for(User aUser: publication.getTaggedFriends()){
MinikastTag aTag;
if(i == publication.getTaggedFriends().size() - 1 ) {
aTag = new MinikastTag(4, aUser.getName(), 3);
aTag.setUserID(aUser.getId());
aTag.setUserName(aUser.getName());
tagsView.add(aTag);
} else {
aTag = new MinikastTag(4, aUser.getName() + ", ", 3);
aTag.setUserID(aUser.getId());
aTag.setUserName(aUser.getName());
tagsView.add(aTag);
}
i = i+1;
}
}
}
tagsView.drawTags();
// likes, dislikes, favs
if(publication.getLikesAmount() > 0)
vLikeCount.setText(String.valueOf(publication.getLikesAmount()));
if(publication.getDislikesAmount() > 0)
vDislikeCount.setText(String.valueOf(publication.getDislikesAmount()));
if(publication.getLovesAmount() > 0)
vFavCount.setText(String.valueOf(publication.getLovesAmount()));
// reset buttons
vFavButton.setPressed(false);
vDislikeButton.setPressed(false);
vLikeButton.setPressed(false);
if(publication.getRelationship().equals("LOVE"))
vFavButton.setPressed(true);
else if (publication.getRelationship().equals("LIKE"))
vLikeButton.setPressed(true);
else if (publication.getRelationship().equals("DISLIKE"))
vDislikeButton.setPressed(true);
// edit - remove icons
if(String.valueOf(publication.getUser().getId()).equals(StartupSharedPreferences.getProfileId())){
vEditPost.setVisibility(View.VISIBLE);
vDeletePost.setVisibility(View.VISIBLE);
}else{
vEditPost.setVisibility(View.INVISIBLE);
vDeletePost.setVisibility(View.INVISIBLE);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是EventPublicationViewHolder的加载方法:
@Override
public void load(EventPublication publication) {
vTimeStamp.setVisibility(View.GONE);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//GoTo.eventDetail(getActivity(), publication);
}
});
vTextViewTitle.setText(publication.getTitle());
vTextViewText.setText(publication.getText());
}
Run Code Online (Sandbox Code Playgroud)
我评论了一些代码只是因为我正在测试,但正如你所看到的,我只做setTexts和一些图像.
这就是我设置适配器,LinearLayoutManager等的方法.在片段的onViewCreated方法中.
vRecyclerView = (FixedRecyclerView) view.findViewById(R.id.recycler_view_publications);
vSwipeRefresh = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
mFeedCallback.onScrollReady(vRecyclerView);
mLayoutManager = buildLayoutManager();
vRecyclerView.setLayoutManager(mLayoutManager);
vRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
mAdapter = new PublicationAdapter();
vSwipeRefresh.setOnRefreshListener(this);
vSwipeRefresh.setColorSchemeResources(R.color._SWIPER_COLOR_1, R.color._SWIPER_COLOR_2,
R.color._SWIPER_COLOR_3, R.color._SWIPER_COLOR_4);
vRecyclerView.setAdapter(mAdapter);
Run Code Online (Sandbox Code Playgroud)
BTW适配器使用我自己的自定义方法加载数据集,称为onHttpClientReady,但这似乎不是问题.
以下是一些截图:
我第一次进入应用程序时的首选:

然后当我回来时:

BTW之类的,不喜欢和喜欢的按钮,如果有人不止一次点击它们,将显示一个数值,如果这些值也是错过的.
更新: 现在我知道那不是因为嵌套的片段.我改变了我的代码,现在,每个选项卡片段都在PageStateAdapter中,该PageStateAdapter位于Activity内部的ViewPager中.但问题仍然存在.
更新: 我发现getItemId方法永远不会执行,IDK为什么呢.
Iva*_*van 68
这通常发生在你有"if(field!= null)holder.setField(field)"之类的东西时,没有else.持有者被回收,这意味着它将具有值,所以你需要清理或替换每个值,如果它是null你应该nullit,如果不是,你应该写它,总是.现在已经晚了,但作为别人的答案.
我建议检查您的类层次结构和用法。一般来说,如果您type == type在基类中执行某种操作,那么您就违背了抽象和继承的目的。像这样的东西对你有用:
public abstract class PublicationViewHolder extends RecyclerView.ViewHolder {
private TextView mTimeStamp;
public PublicationViewHolder(View itemView) {
mTimeStamp = (TextView)itemView.findViewById(R.id. txt_view_publication_timestamp);
}
public void bindViews(Publication publication) {
mTimeStamp.setText(DateFormatter.getTimeAgo(publication.getTimeStamp()));
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您的“事件”或“用户出版物”只需从此类派生并实现构造函数和bindViews()方法。 请务必在这两种情况下调用超类。 另外,请确保在方法中为特定出版物设置布局中的每个bindViews()视图。
在您的适配器中,您只需根据数据集中该位置的出版物类型创建正确的持有者:
public class PublicationAdapter extends RecyclerView.Adapter {
private ArrayList<Publication> mPubs;
// Your other code here, like
// swapPublications(), getItemCount(), etc.
...
public int getItemViewType(int position) {
return mPubs.get(position).getType();
}
public PublicationViewHolder createViewHolder(ViewGroup parent, int type) {
PublicationViewHolder ret;
View root;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (type == USER_PUBLICATION_TYPE) {
root =
inflater.inflate(R.layout.view_holder_user_publication,
parent,
false);
ret = new UserPubHolder(root);
} else {
root =
inflater.inflate(R.layout.view_holder_event_publication,
parent,
false);
ret = new EventPubHolder(root);
}
return ret;
}
public bindViewHolder(PublicationViewHolder holder, int position) {
holder.bindViews(mPubs.get(position));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23207 次 |
| 最近记录: |