package net.dev123.yibo.service.adapter; import java.util.ArrayList; import java.util.Date; import java.util.List; import net.dev123.mblog.entity.Status; import net.dev123.mblog.entity.UnreadCount; import net.dev123.yibo.R; import net.dev123.yibo.common.NotificationEntity; import net.dev123.yibo.common.theme.ThemeUtil; import net.dev123.yibo.db.LocalAccount; import net.dev123.yibo.db.LocalStatus; import net.dev123.yibo.service.cache.MetionsCache; import net.dev123.yibo.service.cache.ReclaimLevel; import net.dev123.yibo.service.cache.wrap.StatusWrap; import net.dev123.yibo.service.task.FlushTask; import net.dev123.yibo.service.task.InitAdapterTask; import net.dev123.yibo.service.task.MetionsPageDownTask; import net.dev123.yibo.service.task.MetionsReadLocalTask; import net.dev123.yibo.widget.Skeleton; import android.app.Activity; import android.content.Context; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Adapter; import android.widget.HeaderViewListAdapter; import android.widget.ListView; import android.widget.TextView; public class MentionsListAdapter extends CacheAdapter<Status> { private MetionsCache cache = null; private List<Status> listNewBlogs = null; private int newCount = 0; public MentionsListAdapter(Context context, LocalAccount account) { super(context, account); cache = new MetionsCache(context, account); listNewBlogs = new ArrayList<Status>(); InitAdapterTask task = new InitAdapterTask(cache, this); task.execute(); } @Override public int getCount() { return cache.size(); } @Override public Object getItem(int position) { if (position < 0 || position > getCount() - 1) { return null; } Object obj = getItemWrap(position); if (obj != null) { obj = ((StatusWrap)obj).getWrap(); } return obj; } private Object getItemWrap(int position) { if (position < 0) { position = 0; } if (position > getCount() - 1) { position = getCount() - 1; } return cache.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Object obj = getItemWrap(position); StatusWrap statusWrap = (StatusWrap) obj; if (statusWrap == null) { return convertView; } int viewType = getItemViewType(position); if (viewType == ITEM_VIEW_TYPE_LOCAL_DIVIDER || viewType == ITEM_VIEW_TYPE_REMOTE_DIVIDER) { convertView = fillInDividerView(convertView, statusWrap, position); } else { convertView = StatusUtil.initConvertView(context, convertView, account.getServiceProvider()); StatusUtil.fillConvertView(convertView, statusWrap); } return convertView; } private View fillInDividerView(View convertView, StatusWrap wrap, final int position) { if (wrap == null || !(wrap.getWrap() instanceof LocalStatus)) { return convertView; } final LocalStatus divider = (LocalStatus)wrap.getWrap(); if (getItemViewType(position) == ITEM_VIEW_TYPE_REMOTE_DIVIDER) { if (convertView == null) { convertView = inflater.inflate(R.layout.list_item_gap, null); ThemeUtil.setListViewGap(convertView); } View llLoadingState = convertView.findViewById(R.id.llLoadingState); if (divider.isLoading()) { llLoadingState.setVisibility(View.VISIBLE); } else { llLoadingState.setVisibility(View.GONE); } convertView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { v.setClickable(false); v.findViewById(R.id.llLoadingState).setVisibility(View.VISIBLE); Status max = (Status)getItem(position - 1); if (max instanceof LocalStatus && ((LocalStatus)max).isDivider()) { max = null; } Status since = (Status)getItem(position + 1); if (since instanceof LocalStatus && ((LocalStatus)since).isDivider()) { since = null; } MetionsPageDownTask task; task = new MetionsPageDownTask(MentionsListAdapter.this, divider); task.execute(max, since); } }); } else { if (convertView == null) { convertView = inflater.inflate(R.layout.list_item_more, null); ThemeUtil.setListViewMore(convertView); } if (divider.isLoading()) { convertView.findViewById(R.id.llLoadingState).setVisibility(View.VISIBLE); convertView.findViewById(R.id.tvFooter).setVisibility(View.GONE); } else { convertView.findViewById(R.id.llLoadingState).setVisibility(View.GONE); convertView.findViewById(R.id.tvFooter).setVisibility(View.VISIBLE); } if (paging.hasNext()) { convertView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (divider.isLoading()) { return; } v.setClickable(false); v.findViewById(R.id.llLoadingState).setVisibility(View.VISIBLE); v.findViewById(R.id.tvFooter).setVisibility(View.GONE); Status max = (Status)getItem(position - 1); Status since = (Status)getItem(position + 1); MetionsReadLocalTask localCacheTask = new MetionsReadLocalTask( MentionsListAdapter.this, cache, divider ); localCacheTask.execute(max, since); } }); } else { ((TextView)convertView.findViewById(R.id.tvFooter)).setText(R.string.label_no_more); } } return convertView; } @Override public boolean addCacheToFirst(List<Status> list) { if (list == null || list.size() == 0) { return false; } List<StatusWrap> listStatusWrap = new ArrayList<StatusWrap>(list.size()); Date currentDate = new Date(); StatusWrap wrap = null; for (Status status : list) { wrap = toWrap(status, currentDate); listStatusWrap.add(wrap); } cache.addAll(0, listStatusWrap); this.notifyDataSetChanged(); FlushTask task = new FlushTask(cache); task.execute(); return true; } @Override public boolean addCacheToDivider(Status value, List<Status> list) { if (list == null || list.size() == 0) { return false; } int i = cache.indexOf(new StatusWrap(value)); if (i == -1) { return false; } cache.remove(i); List<StatusWrap> listWrap = new ArrayList<StatusWrap>(list.size()); Date currentDate = new Date(); StatusWrap wrap = null; for (Status temp : list) { wrap = toWrap(temp, currentDate); listWrap.add(wrap); } cache.addAll(i, listWrap); this.notifyDataSetChanged(); FlushTask task = new FlushTask(cache); task.execute(); return true; } @Override public boolean addCacheToLast(List<Status> list) { if (list == null || list.size() == 0) { return false; } List<StatusWrap> listStatusWrap = new ArrayList<StatusWrap>(list.size()); Date currentDate = new Date(); StatusWrap wrap = null; for (Status status : list) { wrap = toWrap(status, currentDate); listStatusWrap.add(wrap); } cache.addAll(listStatusWrap); this.notifyDataSetChanged(); FlushTask task = new FlushTask(cache); task.execute(); return true; } public StatusWrap toWrap(Status status, Date date) { if (status == null) { return null; } StatusWrap wrap = new StatusWrap(status); wrap.setReadedTime(date); return wrap; } @Override public void clear() { cache.clear(); this.notifyDataSetChanged(); } @Override public void reclaim(ReclaimLevel level) { boolean isReclaim = cache.reclaim(level); if (isReclaim) { try { this.notifyDataSetChanged(); } catch(Exception e) { this.notifyDataSetInvalidated(); } } } public void addNewBlogs(List<Status> list) { if (list == null || list.size() == 0) { return; } listNewBlogs.addAll(0, list); } public NotificationEntity getNotificationEntity(UnreadCount unreadCount) { if (unreadCount != null) { newCount = unreadCount.getMetionCount(); } else { newCount = listNewBlogs.size(); if (newCount > 0 && listNewBlogs.get(newCount - 1) instanceof LocalStatus) { newCount--; } } NotificationEntity entity = new NotificationEntity(); entity.setTickerText(context.getString(R.string.msg_metions_ticker_text)); String accountName = account.getUser().getScreenName(); entity.setContentTitle(context.getString( R.string.msg_metions_content_title, accountName, newCount)); entity.setContentText(account.getServiceProvider().getServiceProviderName() + ": " + getNewBlogsDesc(newCount)); entity.setContentType(Skeleton.TYPE_MENTION); return entity; } public String getNewBlogsDesc(int newCount) { StringBuffer desc = new StringBuffer(); if (listNewBlogs == null || listNewBlogs.size() <= 0 || newCount <= 0) { return desc.toString(); } List<String> listScreenName = new ArrayList<String>(); String screenName = null; int showScreenNameCount = 3; if (showScreenNameCount > newCount) { showScreenNameCount = newCount; } for (int i = 0; i < listNewBlogs.size() && listScreenName.size() < showScreenNameCount; i++) { Status status = listNewBlogs.get(i); if (status == null || status instanceof LocalStatus || status.getUser() == null) { continue; } screenName = status.getUser().getScreenName(); if (!listScreenName.contains(screenName)) { listScreenName.add(screenName); } } if (listScreenName.size() >= 3) { desc.append( context.getString( R.string.msg_metions_content_text_3, listScreenName.get(0), listScreenName.get(1), listScreenName.get(2) ) ); } else if (listScreenName.size() == 2) { desc.append( context.getString( R.string.msg_metions_content_text_2, listScreenName.get(0), listScreenName.get(1) ) ); } else { desc.append(context.getString(R.string.msg_metions_content_text_1, listScreenName.get(0))); } return desc.toString(); } public boolean refresh() { if (listNewBlogs == null || listNewBlogs.size() == 0) { return false; } addCacheToFirst(listNewBlogs); int offset = listNewBlogs.size(); listNewBlogs.clear(); newCount = 0; ListView lvMicroBlog = (ListView)((Activity)context).findViewById(R.id.lvMicroBlog); if (lvMicroBlog == null) { return true; } Adapter adapter = lvMicroBlog.getAdapter(); if (adapter instanceof HeaderViewListAdapter) { adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter(); } if (lvMicroBlog != null && adapter == this ) { int position = lvMicroBlog.getFirstVisiblePosition(); View view = lvMicroBlog.getChildAt(0); int y = 0; if (view != null && position >= 1) { y = view.getTop(); position += offset; lvMicroBlog.setSelectionFromTop(position, y); } } return true; } @Override public Status getMax() { Status max = null; if (cache != null && cache.size() > 0) { StatusWrap wrap = cache.get(0); max = wrap.getWrap(); } if (listNewBlogs != null && listNewBlogs.size() > 0) { Status temp = listNewBlogs.get(0); if (max != null && max.getCreatedAt() != null) { max = max.getCreatedAt().before(temp.getCreatedAt()) ? temp : max; } else { max = temp; } } return max; } @Override public Status getMin() { Status min = null; if (cache != null && cache.size() > 0) { StatusWrap wrap = cache.get(cache.size() - 1); min = wrap.getWrap(); } return min; } public LocalAccount getAccount() { return account; } public void setAccount(LocalAccount account) { this.account = account; } public List<Status> getListNewBlogs() { return listNewBlogs; } @Override public int getItemViewType(int position) { Status status = (Status)getItem(position); if (status == null) { return ITEM_VIEW_TYPE_REMOTE_DIVIDER; } if (!(status instanceof LocalStatus)) { return ITEM_VIEW_TYPE_DATA; } LocalStatus localStatus = (LocalStatus)status; if (!localStatus.isDivider()) { return ITEM_VIEW_TYPE_DATA; } if (localStatus.isLocalDivider()) { return ITEM_VIEW_TYPE_LOCAL_DIVIDER; } return ITEM_VIEW_TYPE_REMOTE_DIVIDER; } @Override public int getViewTypeCount() { return 3; } }