您的位置:首页 > 移动开发 > Android开发

Android 博客园客户端 (八) 下拉刷新、分页,AsyncTask

2014-10-26 19:58 274 查看
一直以来,无论是博客、新闻、还是推荐用户列表。只能加载固定的数量,也没有刷新功能。

为了实现这个功能,也试过很多第三方的开源控件,如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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: