种Android网易新闻之新闻阅读器制作(2)
类Android网易新闻之新闻阅读器制作(2)
完成splash之后,便开始制作列表页。就像之前说的,列表页具有更新和分页的功能,这两个功能都是很常见的。为了使列表支持拖动刷新功能,这里我用到了一个开源插件PullToRefreshListView,这个开源的组件可以使列表页拥有拖动更新的功能。
这是由 johannilsson 以及众位其好友的研究成果,并已 Apache 2.0 协议开源托管在 Github:https://github.com/johannilsson/android-pulltorefresh ,具体效果图如下:
他的原理是继承listview,并利用headview,配合上ontouch和onscroll来检测用户下拉和上滑的动作来实现这种效果。
有了PullToRefreshListView之后,我们的列表就有了下拉更新功能,再配合上footview我们就可以实现分页功能了。至此,UI部分没什么好讲的。再来看看工作线程,我们大概要建立两个工作线程,一个负责更新,一个负责取当前列表及其分页。
这里我们既可以使用Thread+Handler+Message的方式,也可以是用AsyncTask来建立工作线程,
如更新部分我们使用了AsyncTask:
private
class
GetDataTask
extends
AsyncTask
<
Void, Void, List
<
News
>>
{
@Override
protected List < News > doInBackground(Void params) {
// Simulates a background job.
// 更新获取数据
try {
if (ApplicationEx.isNetworkConnected(CiReader. this )) {
List < News > updatelist = HttpDataService
.getNewsListForUpdate(CiReader. this , cur_tab,
firstItem, LIMIT);
// 存储
if (updatelist != null && ! updatelist.isEmpty()) {
Iterator < News > iter = updatelist.iterator();
while (iter.hasNext()) {
News news = iter.next();
news.storageNews(CiReader. this );
((LinkedList < News > ) list).addFirst(news);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
@Override
protected void onPostExecute(List < News > result) {
// mListItems.addFirst("Added after refresh ");
if ( ! ApplicationEx.isNetworkConnected(CiReader. this )) {
Tools.displayMsg(CiReader. this , " 无网络连接 " );
}
// Call onRefreshComplete when the list has been refreshed.
pulltorefreshlist.onRefreshComplete();
super .onPostExecute(result);
}
}
@Override
protected List < News > doInBackground(Void params) {
// Simulates a background job.
// 更新获取数据
try {
if (ApplicationEx.isNetworkConnected(CiReader. this )) {
List < News > updatelist = HttpDataService
.getNewsListForUpdate(CiReader. this , cur_tab,
firstItem, LIMIT);
// 存储
if (updatelist != null && ! updatelist.isEmpty()) {
Iterator < News > iter = updatelist.iterator();
while (iter.hasNext()) {
News news = iter.next();
news.storageNews(CiReader. this );
((LinkedList < News > ) list).addFirst(news);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
@Override
protected void onPostExecute(List < News > result) {
// mListItems.addFirst("Added after refresh ");
if ( ! ApplicationEx.isNetworkConnected(CiReader. this )) {
Tools.displayMsg(CiReader. this , " 无网络连接 " );
}
// Call onRefreshComplete when the list has been refreshed.
pulltorefreshlist.onRefreshComplete();
super .onPostExecute(result);
}
}
取列表及分页数据的AsyncTask:
class
MoreAsyncTask
extends
AsyncTask
<
Void, Void, List
<
News
>>
{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super .onPreExecute();
loadingbutton.setText( " 正在载入 " );
System.out.println( " pre " );
}
protected List < News > doInBackground(Void arg0) {
// TODO Auto-generated method stub
// 取最新20条
List < News > addlist = DBUtil.getNewsListByCategory(CiReader. this ,
cur_tab, lastItem, LIMIT);
if (addlist == null || addlist.isEmpty()) {
// 申请网络,取20条数据,没有任何数据,
// 在splash里面完成前20条数据的加载
if (ApplicationEx.isNetworkConnected(CiReader. this )) {
addlist = HttpDataService.getNewsList(CiReader. this ,
cur_tab, lastItem, LIMIT);
// 存储
if (addlist != null && ! addlist.isEmpty()) {
Iterator < News > iter = addlist.iterator();
while (iter.hasNext()) {
News news = iter.next();
news.storageNews(CiReader. this );
}
}
System.out.println( " test3 " );
} else {
// 无网络连接
}
} else if (addlist.size() < LIMIT) {
// 申请网络,去取不足的部分,这时需要得到
// 第一条数据的content_file_name这个字段值
if (ApplicationEx.isNetworkConnected(CiReader. this )) {
lastItem = addlist.get(addlist.size() - 1 )
.getContent_file_name();
List < News > addlist2 = HttpDataService.getNewsList(
CiReader. this , cur_tab, lastItem,
LIMIT - addlist.size());
if (addlist2 != null && ! addlist2.isEmpty()) {
addlist.addAll(addlist2);
Iterator < News > iter2 = addlist2.iterator();
while (iter2.hasNext()) {
News news = iter2.next();
news.storageNews(CiReader. this );
}
}
} else {
// 无网络连接
}
}
if (addlist != null && ! addlist.isEmpty()) {
list.addAll(addlist);
News lastnews = addlist.get(addlist.size() - 1 );
lastItem = lastnews.getContent_file_name();
}
System.out.println( " back " );
return addlist;
}
@Override
protected void onPostExecute(List < News > result) {
// TODO Auto-generated method stub
super .onPostExecute(result);
System.out.println( " post " );
if (result != null && ! result.isEmpty()) {
loadingbutton.setText( " 查看下面20条结果 " );
footview.setVisibility(View.GONE);
} else if ( ! ApplicationEx.isNetworkConnected(CiReader. this )) {
Tools.displayMsg(CiReader. this , " 无网络连接 " );
} else {
loadingbutton.setText( " 没有了 " );
loadingbutton.setOnClickListener( null );
}
}
}
分页是利用了footview来显示的:
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super .onPreExecute();
loadingbutton.setText( " 正在载入 " );
System.out.println( " pre " );
}
protected List < News > doInBackground(Void arg0) {
// TODO Auto-generated method stub
// 取最新20条
List < News > addlist = DBUtil.getNewsListByCategory(CiReader. this ,
cur_tab, lastItem, LIMIT);
if (addlist == null || addlist.isEmpty()) {
// 申请网络,取20条数据,没有任何数据,
// 在splash里面完成前20条数据的加载
if (ApplicationEx.isNetworkConnected(CiReader. this )) {
addlist = HttpDataService.getNewsList(CiReader. this ,
cur_tab, lastItem, LIMIT);
// 存储
if (addlist != null && ! addlist.isEmpty()) {
Iterator < News > iter = addlist.iterator();
while (iter.hasNext()) {
News news = iter.next();
news.storageNews(CiReader. this );
}
}
System.out.println( " test3 " );
} else {
// 无网络连接
}
} else if (addlist.size() < LIMIT) {
// 申请网络,去取不足的部分,这时需要得到
// 第一条数据的content_file_name这个字段值
if (ApplicationEx.isNetworkConnected(CiReader. this )) {
lastItem = addlist.get(addlist.size() - 1 )
.getContent_file_name();
List < News > addlist2 = HttpDataService.getNewsList(
CiReader. this , cur_tab, lastItem,
LIMIT - addlist.size());
if (addlist2 != null && ! addlist2.isEmpty()) {
addlist.addAll(addlist2);
Iterator < News > iter2 = addlist2.iterator();
while (iter2.hasNext()) {
News news = iter2.next();
news.storageNews(CiReader. this );
}
}
} else {
// 无网络连接
}
}
if (addlist != null && ! addlist.isEmpty()) {
list.addAll(addlist);
News lastnews = addlist.get(addlist.size() - 1 );
lastItem = lastnews.getContent_file_name();
}
System.out.println( " back " );
return addlist;
}
@Override
protected void onPostExecute(List < News > result) {
// TODO Auto-generated method stub
super .onPostExecute(result);
System.out.println( " post " );
if (result != null && ! result.isEmpty()) {
loadingbutton.setText( " 查看下面20条结果 " );
footview.setVisibility(View.GONE);
} else if ( ! ApplicationEx.isNetworkConnected(CiReader. this )) {
Tools.displayMsg(CiReader. this , " 无网络连接 " );
} else {
loadingbutton.setText( " 没有了 " );
loadingbutton.setOnClickListener( null );
}
}
}
private
class
scrollListener
implements
OnScrollListener{
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
switch (scrollState){
case OnScrollListener.SCROLL_STATE_IDLE:
if (view.getLastVisiblePosition() == (view.getCount() - 1 )){
footview.setVisibility(View.VISIBLE);
}
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
switch (scrollState){
case OnScrollListener.SCROLL_STATE_IDLE:
if (view.getLastVisiblePosition() == (view.getCount() - 1 )){
footview.setVisibility(View.VISIBLE);
}
}
}
}
}
讲到这里列表页的关键问题就讲完了,代码里面还有涉及到从网络取数据存本地数据库的部分。这又涉及到一些sqlite的操作,这个可以放到后面再讲一些自己的心得。下面一讲将内容页是如何制作的。