package net.dev123.yibo.service.adapter; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import net.dev123.commons.util.ListUtil; import net.dev123.mblog.entity.Status; import net.dev123.yibo.R; import net.dev123.yibo.YiBoApplication; import net.dev123.yibo.common.Constants; 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.MyHomeCache; 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.MyHomePageDownTask; import net.dev123.yibo.service.task.MyHomePageUpTask; import net.dev123.yibo.service.task.MyHomeReadLocalTask; 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 MyHomeListAdapter extends CacheAdapter<Status> { private MyHomeCache cache; private List<Status> listNewBlogs; private int newCount = 0; //新微博数量; public MyHomeListAdapter(Context context, LocalAccount account) { super(context, account); YiBoApplication yibo = (YiBoApplication)context.getApplicationContext(); if (account == null) { this.account = yibo.getCurrentAccount(); } cache = new MyHomeCache(context, account); listNewBlogs = new ArrayList<Status>(Constants.PAGING_DEFAULT_COUNT * 2); listNewBlogs = Collections.synchronizedList(listNewBlogs); paging.moveToNext(); List<StatusWrap> listWrap = cache.read(paging); cache.addAll(listWrap); Status max = getMax(); paging.setGlobalMax(max); if (max == null) { MyHomePageUpTask task = new MyHomePageUpTask(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 null; } 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; } MyHomePageDownTask task; task = new MyHomePageDownTask(MyHomeListAdapter.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); MyHomeReadLocalTask readLocaTask = new MyHomeReadLocalTask( MyHomeListAdapter.this, cache, divider ); readLocaTask.execute(max, since); } }); } else { ((TextView)convertView.findViewById(R.id.tvFooter)).setText(R.string.label_no_more); } } return convertView; } @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 max = null; if (cache != null && cache.size() > 0) { StatusWrap wrap = cache.get(cache.size() - 1); max = wrap.getWrap(); } return max; } @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; } @Override public boolean remove(int position) { if (position < 0 || position >= getCount()) { return false; } cache.remove(position); this.notifyDataSetChanged(); return true; } @Override public boolean remove(Status status) { if (status == null) { return false; } cache.remove(new StatusWrap(status)); this.notifyDataSetChanged(); return true; } @Override public void clear() { refresh(); 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() { newCount = listNewBlogs.size(); if (newCount > 0 && listNewBlogs.get(newCount - 1) instanceof LocalStatus) { newCount--; } NotificationEntity entity = new NotificationEntity(); entity.setTickerText(context.getString(R.string.msg_myhome_ticker_text)); String accountName = account.getUser().getScreenName(); entity.setContentTitle(context.getString( R.string.msg_myhome_content_title, accountName, newCount)); entity.setContentText(account.getServiceProvider().getServiceProviderName() + ": " + getNewBlogsDesc(newCount)); entity.setContentType(Skeleton.TYPE_MY_HOME); return entity; } public String getNewBlogsDesc(int newCount) { StringBuffer desc = new StringBuffer(); if (ListUtil.isEmpty(listNewBlogs)) { return desc.toString(); } List<String> listScreenName = new ArrayList<String>(); String screenName = null; for (int i = 0; i < newCount && listScreenName.size() < 3; 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_myhome_content_text_3, listScreenName.get(0), listScreenName.get(1), listScreenName.get(2) ) ); } else if (listScreenName.size() == 2) { desc.append( context.getString( R.string.msg_myhome_content_text_2, listScreenName.get(0), listScreenName.get(1) ) ); } else if (listScreenName.size() == 1){ desc.append(context.getString(R.string.msg_myhome_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(); 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 (adapter == this) { int position = lvMicroBlog.getFirstVisiblePosition(); View view = lvMicroBlog.getChildAt(0); int y = 0; if (view != null && position >= 1) { y = view.getTop(); //System.out.println("y:" + y + " position:" + position); position += offset; lvMicroBlog.setSelectionFromTop(position, y); } } return true; } public StatusWrap toWrap(Status status, Date date) { if (status == null) { return null; } StatusWrap wrap = new StatusWrap(status); wrap.setReadedTime(date); return wrap; } public List<Status> getListNewBlogs() { return listNewBlogs; } public void setListNewBlogs(List<Status> listNewBlogs) { this.listNewBlogs = listNewBlogs; } public LocalAccount getAccount() { return account; } @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; } }