Android 博客园客户端 (八) 下拉刷新、分页,AsyncTask
2014-10-26 19:58
274 查看
一直以来,无论是博客、新闻、还是推荐用户列表。只能加载固定的数量,也没有刷新功能。
为了实现这个功能,也试过很多第三方的开源控件,如PullToRefreshListVie等。无意中发现了Google官方发布了一个新的控件(SwipeRefreshLayout),支持下拉刷新,这个控件在Google应用中都有出现过。效果也是非常的不错。
具体的使用方法及代码如下:
需要注意的一点就是SwipeRefreshLayout中只能包含一个控件。其他属性和其他Layout大体相同。
第一点,下拉刷新:
使用的话,需要在Activity或者Fragment中导入并实现android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener接口,并且要重写onRefresh()方法。
第二点,分页处理:
需要实现OnScrollListener接口,并且重写和onScrollStateChangedonScroll和两个方法。
具体代码如下
在之前的项目中,使用了Handler+Thread来加载数据刷新控件,但是感觉代码比较混乱。在新的版本中使用了AsyncTask来替换。具体实现如下:
刷新数据后可能会出现数据重复,要去除重复,首先要在类中重写equals()方法,应为要考虑到不同类型,使用了泛型方法来对User、Blog、News和Comment来进行去重。具体如下:
项目地址:https://github.com/ZhangTingkuo/AndroidCnblogs
为了实现这个功能,也试过很多第三方的开源控件,如PullToRefreshListVie等。无意中发现了Google官方发布了一个新的控件(SwipeRefreshLayout),支持下拉刷新,这个控件在Google应用中都有出现过。效果也是非常的不错。
具体的使用方法及代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefreshLayoutHomeBlog" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/listViewHomeBlog" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </android.support.v4.widget.SwipeRefreshLayout> </LinearLayout>
需要注意的一点就是SwipeRefreshLayout中只能包含一个控件。其他属性和其他Layout大体相同。
第一点,下拉刷新:
使用的话,需要在Activity或者Fragment中导入并实现android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener接口,并且要重写onRefresh()方法。
第二点,分页处理:
需要实现OnScrollListener接口,并且重写和onScrollStateChangedonScroll和两个方法。
具体代码如下
package com.arlen.cnblogs.fragment; import java.util.ArrayList; import java.util.List; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.ListView; import com.arlen.cnblogs.BlogActivity; import com.arlen.cnblogs.R; import com.arlen.cnblogs.adapter.BlogListAdapter; import com.arlen.cnblogs.entity.Blog; import com.arlen.cnblogs.task.BlogListTask; import com.arlen.cnblogs.utils.AppMacros; import com.arlen.cnblogs.utils.AppUtils; public class BlogHomeFragment extends Fragment implements OnItemLongClickListener, OnItemClickListener, OnRefreshListener, OnScrollListener { private static final String TAG = BlogHomeFragment.class.getSimpleName(); private SwipeRefreshLayout swipeRefreshLayout; private ListView listView; private BlogListAdapter adapter; private String path; private int pageSize; private int pageIndex = 1; private List<Blog> blogList; private int lastVisibleIndex; private int maxVisibleIndex = 400; private Intent intent; public BlogHomeFragment() { super(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "onCreate"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.i(TAG, "onCreateView"); View rootView = inflater.inflate(R.layout.fragment_blog_home, container, false); return rootView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Log.i(TAG, "onViewCreated"); initComponent(); initData(); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.i(TAG, "onItemClick -- " + position); showBlogItem(blogList.get(position)); } @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { Log.i(TAG, "onItemLongClick -- " + position); return false; } @Override public void onRefresh() { new BlogListTask(blogList, swipeRefreshLayout, adapter).execute(path, "refresh"); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (adapter.getCount() < maxVisibleIndex) { if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && lastVisibleIndex == adapter.getCount() - 1) { pageIndex++; initPath(pageIndex); swipeRefreshLayout.setRefreshing(true); new BlogListTask(blogList, swipeRefreshLayout, adapter) .execute(path, "loadMore"); } } else { // Toast.makeText(getActivity(), "最后一页!", // Toast.LENGTH_SHORT).show(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { lastVisibleIndex = firstVisibleItem + visibleItemCount - 1; } private void initComponent() { swipeRefreshLayout = (SwipeRefreshLayout) this.getActivity() .findViewById(R.id.swipeRefreshLayoutHomeBlog); swipeRefreshLayout.setOnRefreshListener(this); swipeRefreshLayout.setColorSchemeResources( android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light); listView = (ListView) this.getActivity().findViewById( R.id.listViewHomeBlog); listView.setOnItemClickListener(this); listView.setOnItemLongClickListener(this); listView.setOnScrollListener(this); } private void initData() { blogList = new ArrayList<Blog>(); adapter = new BlogListAdapter(getActivity(), blogList); listView.setAdapter(adapter); initPath(1); swipeRefreshLayout.setRefreshing(true); new BlogListTask(blogList, swipeRefreshLayout, adapter).execute(path, "init"); } private void initPath(int pageIndex) { // http://wcf.open.cnblogs.com/blog/sitehome/paged/{PAGEINDEX}/{PAGESIZE} path = AppMacros.RECENT_BLOGS_PAGED; pageSize = AppMacros.PAGE_SIZE; path = path.replace("{PAGEINDEX}", "" + pageIndex); path = path.replace("{PAGESIZE}", "" + pageSize); Log.i(TAG, "pageIndex:" + pageIndex); } private void showBlogItem(Blog blogEntry) { intent = new Intent(this.getActivity(), BlogActivity.class); if (blogEntry.getAuthorAvatar() != null) { intent.putExtra("avatar", blogEntry.getAuthorAvatar().toString()); } else { intent.putExtra("avatar", ""); } intent.putExtra("title", blogEntry.getBlogTitle()); intent.putExtra("author", blogEntry.getAuthorName()); intent.putExtra("published", AppUtils.parseDateToString(blogEntry.getPublishedDateDate())); intent.putExtra("id", blogEntry.getBlogId()); intent.putExtra("link", blogEntry.getBlogTitle()); startActivity(intent); } }
在之前的项目中,使用了Handler+Thread来加载数据刷新控件,但是感觉代码比较混乱。在新的版本中使用了AsyncTask来替换。具体实现如下:
package com.arlen.cnblogs.task; import java.util.ArrayList; import java.util.List; import com.arlen.cnblogs.adapter.BlogListAdapter; import com.arlen.cnblogs.entity.Blog; import com.arlen.cnblogs.utils.AppUtils; import com.arlen.cnblogs.utils.HttpUtil; import android.os.AsyncTask; import android.support.v4.widget.SwipeRefreshLayout; public class BlogListTask extends AsyncTask<String, Void, Void> { private List<Blog> blogList; private List<Blog> newList = new ArrayList<Blog>(); private SwipeRefreshLayout swipeRefreshLayout; private BlogListAdapter adapter; public BlogListTask(List<Blog> blogList, SwipeRefreshLayout swipeRefreshLayout, BlogListAdapter adapter) { super(); this.blogList = blogList; this.swipeRefreshLayout = swipeRefreshLayout; this.adapter = adapter; } protected Void doInBackground(String... params) { newList = HttpUtil.getBlogList(params[0]); if (params[1].equals("init")) { blogList.addAll(newList); } else if (params[1].equals("refresh")) { newList.addAll(blogList); AppUtils.removeDuplicate(newList); blogList.clear(); blogList.addAll(newList); } else if (params[1].equals("loadMore")) { blogList.addAll(newList); AppUtils.removeDuplicate(blogList); } return null; } @Override protected void onPreExecute() { super.onPreExecute(); newList.clear(); } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); swipeRefreshLayout.setRefreshing(false); adapter.updataBlogList(blogList); adapter.notifyDataSetChanged(); } }
刷新数据后可能会出现数据重复,要去除重复,首先要在类中重写equals()方法,应为要考虑到不同类型,使用了泛型方法来对User、Blog、News和Comment来进行去重。具体如下:
@Override public boolean equals(Object object) { if (object instanceof Blog) { Blog blog = (Blog) object; return String.valueOf(blog.getBlogId()).equals( String.valueOf(this.getBlogId())); } else { return super.equals(object); } }
public static <T> void removeDuplicate(List<T> list) { for (int i = 0; i < list.size(); i++) { for (int j = i + 1; j < list.size(); j++) { if (list.get(i).equals(list.get(j))) { list.remove(j); } } } }
项目地址:https://github.com/ZhangTingkuo/AndroidCnblogs
相关文章推荐
- Android:下拉刷新,分页加载数据(服务端与客户端的的具体实现)
- Android腾讯微博客户端开发5:利用FootView实现ListView滑动动态加载实现分页
- Android腾讯微博客户端开发5:利用FootView实现ListView滑动动态加载实现分页
- Android 博客园客户端 (一) 基本界面
- Android 博客园客户端 (五) 查看评论、搜索博主
- Android 博客园客户端 (四) 基本功能完成(博客列表和内容、新闻列表和内容、推荐博主)
- Android腾讯微博客户端开发五:利用FootView实现ListView滑动动态加载实现分页
- [V2.0 alpha]又一款博客园Android客户端低调推出
- android客户端—AsyncTask的使用
- 又一个博客园Android客户端(新版本:V1.1.0,附APK下载)
- Android 博客园客户端 (七)登录功能
- listView下拉刷新(仿sina微博Android客户端效果)
- listView下拉刷新(仿sina微博Android客户端效果)
- listView下拉刷新(仿sina微博Android客户端效果)
- 推荐大家一个好用的实现分页加载和下拉刷新Android工具包
- 【博客园客户端】博客园Android客户端正式发布
- 没错,你没有看错,博客园Android客户端开源了!
- listView下拉刷新(仿sina微博Android客户端效果)
- Android 博客园客户端 (二) 新界面&部分功能
- 【Android】Android 博客园客户端 (七)登录功能