zoukankan      html  css  js  c++  java
  • Android 博客园客户端 (八) 下拉刷新、分页,AsyncTask

    一直以来,无论是博客、新闻、还是推荐用户列表。只能加载固定的数量,也没有刷新功能。

    为了实现这个功能,也试过很多第三方的开源控件,如PullToRefreshListVie等。无意中发现了Google官方发布了一个新的控件(SwipeRefreshLayout),支持下拉刷新,这个控件在Google应用中都有出现过。效果也是非常的不错。

    具体的使用方法及代码如下:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="fill_parent"
     3     android:layout_height="fill_parent"
     4     android:orientation="vertical" >
     5 
     6     <android.support.v4.widget.SwipeRefreshLayout
     7         android:id="@+id/swipeRefreshLayoutHomeBlog"
     8         android:layout_width="match_parent"
     9         android:layout_height="match_parent" >
    10 
    11         <ListView
    12             android:id="@+id/listViewHomeBlog"
    13             android:layout_width="match_parent"
    14             android:layout_height="wrap_content" >
    15         </ListView>
    16     </android.support.v4.widget.SwipeRefreshLayout>
    17 
    18 </LinearLayout>

    需要注意的一点就是SwipeRefreshLayout中只能包含一个控件。其他属性和其他Layout大体相同。

    第一点,下拉刷新:

    使用的话,需要在Activity或者Fragment中导入并实现android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener接口,并且要重写onRefresh()方法。

    第二点,分页处理:

    需要实现OnScrollListener接口,并且重写和onScrollStateChangedonScroll和两个方法。

    具体代码如下

      1 package com.arlen.cnblogs.fragment;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 
      6 import android.content.Intent;
      7 import android.os.Bundle;
      8 import android.support.v4.app.Fragment;
      9 import android.support.v4.widget.SwipeRefreshLayout;
     10 import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
     11 import android.util.Log;
     12 import android.view.LayoutInflater;
     13 import android.view.View;
     14 import android.view.ViewGroup;
     15 import android.widget.AbsListView;
     16 import android.widget.AbsListView.OnScrollListener;
     17 import android.widget.AdapterView;
     18 import android.widget.AdapterView.OnItemClickListener;
     19 import android.widget.AdapterView.OnItemLongClickListener;
     20 import android.widget.ListView;
     21 
     22 import com.arlen.cnblogs.BlogActivity;
     23 import com.arlen.cnblogs.R;
     24 import com.arlen.cnblogs.adapter.BlogListAdapter;
     25 import com.arlen.cnblogs.entity.Blog;
     26 import com.arlen.cnblogs.task.BlogListTask;
     27 import com.arlen.cnblogs.utils.AppMacros;
     28 import com.arlen.cnblogs.utils.AppUtils;
     29 
     30 public class BlogHomeFragment extends Fragment implements
     31         OnItemLongClickListener, OnItemClickListener, OnRefreshListener,
     32         OnScrollListener {
     33     private static final String TAG = BlogHomeFragment.class.getSimpleName();
     34 
     35     private SwipeRefreshLayout swipeRefreshLayout;
     36     private ListView listView;
     37 
     38     private BlogListAdapter adapter;
     39 
     40     private String path;
     41     private int pageSize;
     42     private int pageIndex = 1;
     43     private List<Blog> blogList;
     44 
     45     private int lastVisibleIndex;
     46     private int maxVisibleIndex = 400;
     47 
     48     private Intent intent;
     49 
     50     public BlogHomeFragment() {
     51         super();
     52     }
     53 
     54     @Override
     55     public void onCreate(Bundle savedInstanceState) {
     56         super.onCreate(savedInstanceState);
     57         Log.i(TAG, "onCreate");
     58     }
     59 
     60     @Override
     61     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     62             Bundle savedInstanceState) {
     63         Log.i(TAG, "onCreateView");
     64         View rootView = inflater.inflate(R.layout.fragment_blog_home,
     65                 container, false);
     66         return rootView;
     67     }
     68 
     69     @Override
     70     public void onViewCreated(View view, Bundle savedInstanceState) {
     71         super.onViewCreated(view, savedInstanceState);
     72         Log.i(TAG, "onViewCreated");
     73         initComponent();
     74         initData();
     75     }
     76 
     77     @Override
     78     public void onItemClick(AdapterView<?> parent, View view, int position,
     79             long id) {
     80         Log.i(TAG, "onItemClick -- " + position);
     81         showBlogItem(blogList.get(position));
     82     }
     83 
     84     @Override
     85     public boolean onItemLongClick(AdapterView<?> parent, View view,
     86             int position, long id) {
     87         Log.i(TAG, "onItemLongClick -- " + position);
     88         return false;
     89     }
     90 
     91     @Override
     92     public void onRefresh() {
     93         new BlogListTask(blogList, swipeRefreshLayout, adapter).execute(path,
     94                 "refresh");
     95     }
     96 
     97     @Override
     98     public void onScrollStateChanged(AbsListView view, int scrollState) {
     99         if (adapter.getCount() < maxVisibleIndex) {
    100             if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
    101                     && lastVisibleIndex == adapter.getCount() - 1) {
    102 
    103                 pageIndex++;
    104                 initPath(pageIndex);
    105                 swipeRefreshLayout.setRefreshing(true);
    106                 new BlogListTask(blogList, swipeRefreshLayout, adapter)
    107                         .execute(path, "loadMore");
    108             }
    109         } else {
    110             // Toast.makeText(getActivity(), "最后一页!",
    111             // Toast.LENGTH_SHORT).show();
    112         }
    113     }
    114 
    115     @Override
    116     public void onScroll(AbsListView view, int firstVisibleItem,
    117             int visibleItemCount, int totalItemCount) {
    118         lastVisibleIndex = firstVisibleItem + visibleItemCount - 1;
    119     }
    120 
    121     private void initComponent() {
    122         swipeRefreshLayout = (SwipeRefreshLayout) this.getActivity()
    123                 .findViewById(R.id.swipeRefreshLayoutHomeBlog);
    124         swipeRefreshLayout.setOnRefreshListener(this);
    125         swipeRefreshLayout.setColorSchemeResources(
    126                 android.R.color.holo_blue_bright,
    127                 android.R.color.holo_green_light,
    128                 android.R.color.holo_orange_light,
    129                 android.R.color.holo_red_light);
    130 
    131         listView = (ListView) this.getActivity().findViewById(
    132                 R.id.listViewHomeBlog);
    133         listView.setOnItemClickListener(this);
    134         listView.setOnItemLongClickListener(this);
    135         listView.setOnScrollListener(this);
    136     }
    137 
    138     private void initData() {
    139         blogList = new ArrayList<Blog>();
    140         adapter = new BlogListAdapter(getActivity(), blogList);
    141         listView.setAdapter(adapter);
    142 
    143         initPath(1);
    144         swipeRefreshLayout.setRefreshing(true);
    145         new BlogListTask(blogList, swipeRefreshLayout, adapter).execute(path,
    146                 "init");
    147     }
    148 
    149     private void initPath(int pageIndex) {
    150         // http://wcf.open.cnblogs.com/blog/sitehome/paged/{PAGEINDEX}/{PAGESIZE}
    151         path = AppMacros.RECENT_BLOGS_PAGED;
    152         pageSize = AppMacros.PAGE_SIZE;
    153         path = path.replace("{PAGEINDEX}", "" + pageIndex);
    154         path = path.replace("{PAGESIZE}", "" + pageSize);
    155 
    156         Log.i(TAG, "pageIndex:" + pageIndex);
    157     }
    158 
    159     private void showBlogItem(Blog blogEntry) {
    160         intent = new Intent(this.getActivity(), BlogActivity.class);
    161 
    162         if (blogEntry.getAuthorAvatar() != null) {
    163             intent.putExtra("avatar", blogEntry.getAuthorAvatar().toString());
    164         } else {
    165             intent.putExtra("avatar", "");
    166         }
    167         intent.putExtra("title", blogEntry.getBlogTitle());
    168         intent.putExtra("author", blogEntry.getAuthorName());
    169         intent.putExtra("published",
    170                 AppUtils.parseDateToString(blogEntry.getPublishedDateDate()));
    171         intent.putExtra("id", blogEntry.getBlogId());
    172         intent.putExtra("link", blogEntry.getBlogTitle());
    173 
    174         startActivity(intent);
    175     }
    176 }

    在之前的项目中,使用了Handler+Thread来加载数据刷新控件,但是感觉代码比较混乱。在新的版本中使用了AsyncTask来替换。具体实现如下:

     1 package com.arlen.cnblogs.task;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import com.arlen.cnblogs.adapter.BlogListAdapter;
     7 import com.arlen.cnblogs.entity.Blog;
     8 import com.arlen.cnblogs.utils.AppUtils;
     9 import com.arlen.cnblogs.utils.HttpUtil;
    10 
    11 import android.os.AsyncTask;
    12 import android.support.v4.widget.SwipeRefreshLayout;
    13 
    14 public class BlogListTask extends AsyncTask<String, Void, Void> {
    15     private List<Blog> blogList;
    16     private List<Blog> newList = new ArrayList<Blog>();
    17     private SwipeRefreshLayout swipeRefreshLayout;
    18     private BlogListAdapter adapter;
    19 
    20     public BlogListTask(List<Blog> blogList,
    21             SwipeRefreshLayout swipeRefreshLayout, BlogListAdapter adapter) {
    22         super();
    23         this.blogList = blogList;
    24         this.swipeRefreshLayout = swipeRefreshLayout;
    25         this.adapter = adapter;
    26     }
    27 
    28     protected Void doInBackground(String... params) {
    29 
    30         newList = HttpUtil.getBlogList(params[0]);
    31 
    32         if (params[1].equals("init")) {
    33             blogList.addAll(newList);
    34         } else if (params[1].equals("refresh")) {
    35             newList.addAll(blogList);
    36             AppUtils.removeDuplicate(newList);
    37             blogList.clear();
    38             blogList.addAll(newList);
    39         } else if (params[1].equals("loadMore")) {
    40             blogList.addAll(newList);
    41             AppUtils.removeDuplicate(blogList);
    42         }
    43         return null;
    44     }
    45 
    46     @Override
    47     protected void onPreExecute() {
    48         super.onPreExecute();
    49         newList.clear();
    50     }
    51 
    52     @Override
    53     protected void onPostExecute(Void result) {
    54         super.onPostExecute(result);
    55 
    56         swipeRefreshLayout.setRefreshing(false);
    57         adapter.updataBlogList(blogList);
    58         adapter.notifyDataSetChanged();
    59     }
    60 
    61 }

    刷新数据后可能会出现数据重复,要去除重复,首先要在类中重写equals()方法,应为要考虑到不同类型,使用了泛型方法来对User、Blog、News和Comment来进行去重。具体如下:

     1     @Override
     2     public boolean equals(Object object) {
     3         if (object instanceof Blog) {
     4             Blog blog = (Blog) object;
     5             return String.valueOf(blog.getBlogId()).equals(
     6                     String.valueOf(this.getBlogId()));
     7         } else {
     8             return super.equals(object);
     9         }
    10     }
    1     public static <T> void removeDuplicate(List<T> list) {
    2         for (int i = 0; i < list.size(); i++) {
    3             for (int j = i + 1; j < list.size(); j++) {
    4                 if (list.get(i).equals(list.get(j))) {
    5                     list.remove(j);
    6                 }
    7             }
    8         }
    9     }

    项目地址:https://github.com/ZhangTingkuo/AndroidCnblogs

  • 相关阅读:
    python类内置方法之__call__
    selenium之python源码解读-webdriver继承关系
    Jmeter之JDBC类型组件
    Jmeter逻辑控制之if控制器
    Java连接MySQL Warning: Establishing SSL connection without server's identity verification is not recommended
    Python3 Windows服务器简单实现 手机访问
    如何在C语言 C++里面调用 DOS命令
    常用DOS命令(1) color,dir,copy,shutdown,mkdir(md),rmdir(rd),attrib,cd
    Java实现队列
    Java 实现 栈
  • 原文地址:https://www.cnblogs.com/zhangtingkuo/p/4052623.html
Copyright © 2011-2022 走看看