本程序代码参考自开源中国App。数据获取方式:Bmob云存储。本程序已实现下拉刷新和上拉加载,并显示上拉加载状态。
01 效果图
PullDownload.png02 Layout
recycler_footer_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="46dp"
android:gravity="center"
android:minHeight="46dp"
android:orientation="horizontal">
<ProgressBar
android:id="@+id/pb_footer"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" />
<TextView
android:id="@+id/tv_footer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载中..." />
</LinearLayout>
02 RecyclerView的Adapter
public class TweetAdapter extends RecyclerView.Adapter{
private Context mContext;
protected ArrayList<Tweet> mItems;
public static final int VIEW_TYPE_NORMAL = 0;
public static final int VIEW_TYPE_FOOTER = -1;
public static final int STATE_HIDE = 1;
public static final int STATE_LOADING = 2;
public static final int STATE_NO_MORE = 3;
public static final int STATE_LOAD_ERROR = 4;
private int mState;
public TweetAdapter(Context context, ArrayList<Tweet> items){
this.mContext = context;
if(items == null){
items = new ArrayList<>();
}
this.mItems = items;
mState = STATE_HIDE;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == VIEW_TYPE_FOOTER){
return new FooterViewHolder(LayoutInflater.from(mContext).inflate(R.layout.recycler_footer_view, parent, false));
}
else {
return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_list_tweet, parent, false));
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder.getItemViewType() == VIEW_TYPE_FOOTER){
FooterViewHolder fvh = (FooterViewHolder) holder;
fvh.itemView.setVisibility(View.VISIBLE);
switch (mState) {
case STATE_LOADING:
fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_loading));
fvh.pb_footer.setVisibility(View.VISIBLE);
break;
case STATE_NO_MORE:
fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_not_more));
fvh.pb_footer.setVisibility(View.GONE);
break;
case STATE_LOAD_ERROR:
fvh.tv_footer.setText(mContext.getResources().getString(R.string.state_load_error));
fvh.pb_footer.setVisibility(View.GONE);
break;
case STATE_HIDE:
fvh.itemView.setVisibility(View.GONE);
break;
}
}
else{
ViewHolder viewHolder = (ViewHolder) holder;
Tweet item = mItems.get(position);
Glide.with(mContext)
.load(item.getAuthor().getPortrait())
.asBitmap()
.placeholder(R.mipmap.widget_face)
.error(R.mipmap.widget_face)
.into(viewHolder.mViewPortrait);
viewHolder.mViewName.setText(item.getAuthor().getName());
viewHolder.mViewTime.setText(StringUtil.formatSomeAgo(item.getPubDate()));
viewHolder.mViewPlatform.setText(getAppClientName(item.getAppClient()));
viewHolder.mViewLikeCount.setText(String.valueOf(item.getLikeCount()));
viewHolder.mViewCommentCount.setText(String.valueOf(item.getCommentCount()));
String content = "";
if (!TextUtils.isEmpty(item.getContent())) {
content = item.getContent().replaceAll("[\n\\s]+", " ");
}
Spannable spannable = AssimilateUtil.assimilateOnlyTag(mContext, content);
spannable = AssimilateUtil.assimilateOnlyLink(mContext, spannable);
viewHolder.mViewContent.setText(spannable);
viewHolder.mViewContent.setMovementMethod(LinkMovementMethod.getInstance());
viewHolder.mViewContent.setFocusable(false);
viewHolder.mViewContent.setLongClickable(false);
viewHolder.mViewLikeState.setImageResource(item.getLiked() ? R.mipmap.thumb_up_active : R.mipmap.thumb_up_normal);
viewHolder.mViewLikeState.setTag(position);
}
}
@Override
public int getItemCount() {
return mItems.size() + 1;
}
@Override
public int getItemViewType(int position) {
if(position + 1 == getItemCount()){
return VIEW_TYPE_FOOTER;
}
else{
return VIEW_TYPE_NORMAL;
}
}
public static class ViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.iv_tweet_face) CircleImageView mViewPortrait;
@BindView(R.id.tv_tweet_name) TextView mViewName;
@BindView(R.id.tv_tweet_time) TextView mViewTime;
@BindView(R.id.tv_tweet_platform) TextView mViewPlatform;
@BindView(R.id.tv_tweet_like_count) TextView mViewLikeCount;
@BindView(R.id.tv_tweet_comment_count) TextView mViewCommentCount;
@BindView(R.id.tweet_item) TextView mViewContent;
@BindView(R.id.iv_like_state) ImageView mViewLikeState;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
public static class FooterViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.pb_footer) ProgressBar pb_footer;
@BindView(R.id.tv_footer) TextView tv_footer;
public FooterViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
public void setState(int state) {
if(this.mState != state){
this.mState = state;
updateItem(getItemCount() - 1);
}
}
public void updateItem(int position) {
if (getItemCount() > position) {
notifyItemChanged(position);
}
}
public void addAll(List<Tweet> items) {
if (items != null) {
this.mItems.addAll(items);
notifyItemRangeInserted(this.mItems.size(), items.size());
}
}
public void clear() {
this.mItems.clear();
notifyDataSetChanged();
}
private String getAppClientName(int appClient){
String appClientName = "";
switch (appClient){
case 3 :
appClientName = "Android";
break;
case 4 :
appClientName = "iPhone";
break;
}
return appClientName;
}
}
03 源代码
下载地址。
04 App
数据来自Bmob云存储,可以直接下载App运行看效果。
网友评论