我有一个带有自定义适配器的列表,刷新后我想添加要显示的新数据(如果有的话)。
但该列表没有更新。我为适配器尝试了所有带有 notifyDataSetChanged 的方法,但它没有更新。
请帮忙。我为此浪费了很多时间,我觉得我对这个失去了理智。
这是代码: NewsFeedArrayAdapter
public class NewsFeedArrayAdapter extends ArrayAdapter<FeedItem> {
private final String TAG_DEBUG = this.getClass().getName();
private LayoutInflater inflator;
public final static String PREFS_NAME = "shared_pref_eid";
ImageLoader imageLoader;
Utils utils;
public NewsFeedArrayAdapter(Activity context) {
super(context, R.layout.feed_story_content);
this.utils = new Utils(context);
inflator = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = ImageLoader.getInstance(context);
}
/**
* Static Inner class.
*
* Makes the ListView more efficient since Android recycles views in a ListView.
*/
public static class ViewHolder {
public ImageView profilePicture, image;
public TextView author, timePast, message, likes, comments;
public LinearLayout like, comment, share, likesCommentsCounter;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = null;
FeedItem feedItem = FeedItemParser.FEEDS.get(position);
ViewHolder holder = null;
if (convertView == null) {
rowView = inflator.inflate(R.layout.feed_story_content, parent, false);
holder = new ViewHolder();
holder.profilePicture = (ImageView) rowView.findViewById(R.id.feed_story_profile_picture);
holder.author = (TextView) rowView.findViewById(R.id.feed_story_author);
holder.timePast = (TextView) rowView.findViewById(R.id.feed_story_time_past);
holder.message = (TextView) rowView.findViewById(R.id.feed_story_message);
holder.image = (ImageView) rowView.findViewById(R.id.feed_story_image);
holder.like = (LinearLayout) rowView.findViewById(R.id.feed_feedback_like_container);
holder.comment = (LinearLayout) rowView.findViewById(R.id.feed_feedback_comment_container);
holder.share = (LinearLayout) rowView.findViewById(R.id.feed_feedback_share_container);
holder.likes = (TextView) rowView.findViewById(R.id.feed_story_likes);
holder.comments = (TextView) rowView.findViewById(R.id.feed_story_comments);
rowView.setTag(holder);
} else {
rowView = convertView;
holder = ((ViewHolder) rowView.getTag());
}
Log.i(TAG_DEBUG, "feedItem = " + feedItem);
if (feedItem != null) {
if (!TextUtils.isEmpty(feedItem.feed_story_from_name)) {
holder.author.setText(feedItem.feed_story_from_name);
} else {
holder.author.setText("Unknown");
}
if (!TextUtils.isEmpty(feedItem.feed_story_created_time)) {
// Convert the date to calendar date
Calendar calendarDate = null;
try {
calendarDate = ISO8601.toCalendar(feedItem.feed_story_created_time);
} catch (ParseException e) {
e.printStackTrace();
}
CharSequence relativeTimeSpan = DateUtils.getRelativeTimeSpanString(
calendarDate.getTimeInMillis(),
System.currentTimeMillis(),
DateUtils.SECOND_IN_MILLIS);
holder.timePast.setText(relativeTimeSpan);
} else {
holder.timePast.setText("Unknown");
}
Log.i(TAG_DEBUG, "feedItem.feed_story_message = " + feedItem.feed_story_message);
if (!TextUtils.isEmpty(feedItem.feed_story_message)) {
holder.message.setText(feedItem.feed_story_message);
} else {
holder.message.setText("Unkown");
// holder.message.setVisibility(View.GONE);
}
// Display the icon of the feed
int defaultResourceIcon = R.drawable.no_avatar;
if (feedItem.feed_story_from_id != null) {
String iconUrl = "https://graph.facebook.com/" + feedItem.feed_story_from_id + "/picture?type=normal";
if (Session.getActiveSession() != null &&
Session.getActiveSession().getAccessToken() != null) {
iconUrl += "&access_token=" + Session.getActiveSession().getAccessToken();
}
Log.i(TAG_DEBUG, "iconUrl = " + iconUrl);
imageLoader.displayImage(iconUrl, holder.profilePicture, 70, defaultResourceIcon);
} else {
imageLoader.cancelDisplayTaskFor(holder.profilePicture);
holder.profilePicture.setImageResource(defaultResourceIcon);
}
// Display the picture of the feed
int defaultResourcePicture = R.drawable.empty;
if (!TextUtils.isEmpty(feedItem.feed_story_picture)) {
holder.image.setVisibility(View.VISIBLE);
Log.i(TAG_DEBUG, "feed_picture = " + feedItem.feed_story_picture + "\nfeed_picture_height = " + feedItem.feed_story_picture_height);
imageLoader.displayImage(feedItem.feed_story_picture, holder.image, -1, defaultResourcePicture);
} else {
imageLoader.cancelDisplayTaskFor(holder.image);
// holder.image.setImageResource(defaultResourcePicture);
holder.image.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(feedItem.feed_story_likes)) {
holder.likes.setVisibility(View.VISIBLE);
String likes = feedItem.feed_story_likes + " like";
if (!feedItem.feed_story_likes.contentEquals("1")) {
likes += "s";
}
holder.likes.setText(likes);
} else {
holder.likes.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(feedItem.feed_story_comments)) {
holder.comments.setVisibility(View.VISIBLE);
String comments = feedItem.feed_story_comments + " comment";
if (!feedItem.feed_story_comments.contentEquals("1")) {
comments += "s";
}
holder.comments.setText(comments);
} else {
holder.comments.setVisibility(View.GONE);
}
holder.like.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
utils.customToast("Like content - TBA");
}
});
holder.comment.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
utils.customToast("Comment section - TBA");
}
});
holder.share.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
utils.customToast("Sharing content - TBA");
}
});
}
return rowView;
}
@Override
public int getCount() {
return FeedItemParser.FEEDS.size();
}
}
列表中的适配器是在第一个请求之后设置的,当我得到第一个结果时,如下所示:
ListView actualListView = mPullRefreshListView.getRefreshableView();
// Need to use the Actual ListView when registering for Context Menu
registerForContextMenu(actualListView);
// Sort the list before displaying
Collections.sort(FeedItemParser.FEEDS, Comparators.CREATED_TIME);
// Set the custom adapter
customAddapter = new NewsFeedArrayAdapter(activity);
// Populate the fragment with the data from JSON
actualListView.setAdapter(customAddapter);
FeedItemParser 是一个自定义类,我在其中存储自定义对象:
public class FeedItemParser {
// JSON Node names
public static final String
TAG_DATA = "data", // Array
TAG_ID = "id", // String
TAG_FROM = "from", // Object
TAG_FROM_ID = "id", // String
TAG_FROM_CATEGORY = "category", // String
TAG_FROM_NAME = "name", // String
TAG_TO = "to", // Object
TAG_TO_DATA = "data", // Array
TAG_TO_DATA_ID = "id", // String
TAG_TO_DATA_NAME = "name", // String
TAG_MESSAGE = "message", // String
TAG_PICTURE = "picture", // String
TAG_ACTIONS = "actions", // Array
TAG_ACTIONS_NAME = "name", // String
TAG_ACTIONS_LINK = "link", // String
TAG_PRIVACY = "privacy", // Object
TAG_PRIVACY_VALUE = "value", // String
TAG_TYPE = "type", // String
TAG_STATUS_TYPE = "status_type", // String
TAG_CREATED_TIME = "created_time", // String
TAG_UPDATED_TIME = "updated_time", // String
TAG_LIKES = "likes", // Object
TAG_LIKES_COUNT = "count", // String
TAG_COMMENTS = "comments", // Object
TAG_COMMENTS_DATA = "data", // Array
TAG_PAGING = "paging", // Object
TAG_PAGING_PREVIOUS = "previous",// String
TAG_PAGING_NEXT = "next"; // String
/**
* An array of Shelter items.
*/
public static List<FeedItem> FEEDS = new ArrayList<FeedItem>();
/**
* A map of Array items, by ID.
*/
public static Map<String, FeedItem> FEED_MAP = new HashMap<String, FeedItem>();
public static void addItem(FeedItem item) {
FEEDS.add(FEEDS.size(), item);
FEED_MAP.put(item.feed_story_id, item);
}
public static void addPicture (String feed_story_id, String picture, String height) {
FeedItem feedItem = FEED_MAP.get(feed_story_id);
feedItem.feed_story_picture = picture;
feedItem.feed_story_picture_height = height;
}
public static class FeedItem {
public String feed_story_id, feed_story_from_id, feed_story_from_category,
feed_story_from_name, feed_story_message, feed_story_picture, feed_story_picture_height,
feed_story_privacy, feed_story_type, feed_story_status_type, feed_story_created_time,
feed_story_updated_time, feed_story_likes, feed_story_comments;
/**
* @param feed_story_id
* @param feed_story_from_id
* @param feed_story_from_category
* @param feed_story_from_name
* @param feed_story_message
* @param feed_story_picture
* @param feed_story_privacy
* @param feed_story_type
* @param feed_story_status_type
* @param feed_story_created_time
* @param feed_story_updated_time
*/
public FeedItem(String feed_story_id, String feed_story_from_id, String feed_story_from_category,
String feed_story_from_name, String feed_story_message, String feed_story_picture,
String feed_story_picture_height, String feed_story_privacy, String feed_story_type,
String feed_story_status_type, String feed_story_created_time, String feed_story_updated_time,
String feed_story_likes, String feed_story_comments) {
this.feed_story_id = feed_story_id;
this.feed_story_from_id = feed_story_from_id;
this.feed_story_from_category = feed_story_from_category;
this.feed_story_from_name = feed_story_from_name;
this.feed_story_message = feed_story_message;
this.feed_story_picture = feed_story_picture;
this.feed_story_picture_height = feed_story_picture_height;
this.feed_story_privacy = feed_story_privacy;
this.feed_story_type = feed_story_type;
this.feed_story_status_type = feed_story_status_type;
this.feed_story_created_time = feed_story_created_time;
this.feed_story_updated_time = feed_story_updated_time;
this.feed_story_likes = feed_story_likes;
this.feed_story_comments = feed_story_comments;
}
@Override
public String toString() {
return feed_story_message;
}
}
}
当我请求新数据(刷新)时,我在我的对象中添加新数据(与我第一次做的方式相同):
FeedItemParser.addItem(new FeedItem(
id,
from_id,
from_category,
from_name,
message,
null, // Will be gotten through another request
null,
privacy_value,
type,
status_type,
created_time,
updated_time,
likes,
comments));
之后我打电话
ListView actualListView = mPullRefreshListView.getRefreshableView();
// Need to use the Actual ListView when registering for Context Menu
registerForContextMenu(actualListView);
// Sort the list before displaying
Collections.sort(FeedItemParser.FEEDS, Comparators.CREATED_TIME);
// Notify list adapter to update the list
customAddapter.notifyDataSetChanged();
解决方案
根据@Selvin 的建议,我在添加更多数据后设法更新了我的列表。基本上我改变了我的适配器(我不再使用过滤列表,但我直接使用我的自定义对象)。添加新对象后,我通过调用notifyDataSetChanged()
现有适配器来更新列表。我也更新了我的代码,也许它会帮助其他人遇到这种情况。
再次感谢@Selvin。