ANDROID 开发一个新闻阅读器 4章 新闻列表-下
1.
功能描述
这一讲中我们将对上一章中已经实现新闻列表做一个功能上的强化,其中包括 返回按键, 新闻的收藏夹, 以及新闻列表的上下翻页。
下图是我们设计的样式,最上方的按钮栏这边不再多做介绍了,在原有基础上 增加了上一页,下一页 按钮。
界面如图:

2.
界面布局
修改之前的 news_result_list.xml 文件, 添加翻页按钮,在之前的布局里加入这2个布局:
1 <RelativeLayout android:id="@+id/result_RelativeLayout01"
2 android:layout_width="fill_parent"
3 android:layout_height="wrap_content"
4 android:background="@color/yellow">
5 <Button android:id="@+id/result_back"
6 android:layout_width="wrap_content"
7 android:layout_height="wrap_content"
8 android:layout_alignParentLeft="true"
9 android:paddingLeft="2dip"
10 android:text="@string/back"/>
11 // 上页按钮
12 <Button android:id="@+id/result_last_pg"
13 android:layout_width="wrap_content"
14 android:layout_height="wrap_content"
15 android:layout_toRightOf="@id/result_back"
16 android:text="@string/last_page"/>
17
18 <Button android:id="@+id/result_collection"
19 android:layout_width="wrap_content"
20 android:layout_height="wrap_content"
21 android:layout_alignParentRight="true"
22 android:paddingRight="2dip"
23 android:text="@string/collection" />
24 // 下页按钮
25 <Button android:id="@+id/result_next_pg"
26 android:layout_width="wrap_content"
27 android:layout_height="wrap_content"
28 android:layout_toLeftOf="@id/result_collection"
29 android:text="@string/next_page"/>
30 </RelativeLayout>
因为是在 RelativeLayout 布局下,所以 分别通过属性
android:layout_toRightOf="@id/result_back"
和
android:layout_toLeftOf="@id/result_collection"
让其位于 返回 和 收藏按钮的左右两侧
同时在 strings.xml 文件下定义 last_page 和 next_page 的text 字段
<string name="last_page">上页</string>
<string name="next_page">下页</string>
添加按钮后的界面:

接下来为
上页, 下页 按钮添加响应事件:
3.
后台逻辑层
修改 newsResultListActivity.java, 添加两个新的Button 控件:
public Button result_last_pg, result_next_pg;
findView() 方法下添加 这两个控件的资源获取方法:
1 /**
2 * 获取页面上定义的控件资源
3 */
4 public void findView(){
5
6 result_last_pg = (Button)this.findViewById(R.id.result_last_pg);
7 result_next_pg = (Button)this.findViewById(R.id.result_next_pg);
8 ......
9 ......
10 ......
11 }
在 onCreate() 方法里 增加一个监听方法的 调用,但注意一定要在执行完 findView() 方法,获取控件资源后才能执行
1 //为空间添加监听事件
2 setListener();
同时声明该方法, 并分别给按钮 result_back, result_collection, result_last_pg, result_next_pg 添加监听事件:
1
2 /**
3 * 设置页面上控件的监听事件
4 */
5 public void setListener(){
6 result_last_pg.setOnClickListener(new OnClickListener(){
7
8 @Override
9 public void onClick(View v) {
10 // TODO Auto-generated method stub
11
12 }
13
14 });
15
16 result_next_pg.setOnClickListener(new OnClickListener(){
17
18 @Override
19 public void onClick(View v) {
20 // TODO Auto-generated method stub
21
22 }
23
24 });
25
26 result_back.setOnClickListener(new OnClickListener(){
27
28 @Override
29 public void onClick(View v) {
30 onDestroy();
31 }
32
33 });
34
35 result_collection.setOnClickListener(new OnClickListener(){
36
37 @Override
38 public void onClick(View v) {
39 // TODO Auto-generated method stub
40
41 }
42
43 });
44 }
创建2个文件分别是 ResultListHelpI.java 和 ResultListHelpImpl.java 前者是接口, 后者则是接口的具体实现:
接口代码:
1 import java.util.List;
2 //声明一个接口 interface
3 public interface ResultListHelpI {
4 /**
5 *
6 * @Title: getCount
7 * @Description: 记录总数
8 * @return 设定文件
9 */
10 public int getCount();
11 /**
12 *
13 * @Title: nextPage
14 * @Description: 下一页
15 */
16 public void nextPage();
17 /**
18 *
19 * @Title: prePage
20 * @Description: 前一页
21 */
22 public void prePage();
23 /**
24 *
25 * @Title: gotoPage
26 * @Description: go to x page
27 * @param n
28 * 设定文件
29 */
30 public void gotoPage(int n);
31 /**
32 *
33 * @Title: setPerPage
34 * @Description: 每页显示的条数
35 * @param page
36 * 设定文件
37 */
38 public void setPerPage(int page);
39 /**
40 *
41 * @Title: getPerPage
42 * @Description: get 每页显示的条数
43 */
44 public int getPerPage();
45 /**
46 *
47 * @Title: hasNextPage
48 * @Description: 是否有下一页
49 * @return 设定文件
50 */
51 public boolean hasNextPage();
52 /**
53 *
54 * @Title: hasHeadpage
55 * @Description:是否有上一页
56 * @return 设定文件
57 */
58 public boolean hasPrepage();
59 /**
60 *
61 * @Title: getCurrentPage
62 * @Description: 当前页数
63 * @return 设定文件
64 */
65 public int getCurrentPage();
66 /**
67 *
68 * @Title: getPageNUm
69 * @Description: 获取页数
70 * @return 设定文件
71 */
72 public int getPageNum();
73 /**
74 *
75 * @Title: currentList
76 * @Description: 当前记录集
77 * @return 设定文件
78 */
79 public List<?> getCurrentList();
80 /**
81 *
82 * @Title: initList
83 * @Description: 初始化 list
84 * @param list 设定文件
85 */
86 public void initList(List<?> list);
87 }
接口的具体实现 代码:
1 import java.util.List;
2
3 public class ResultListHelpImpl implements ResultListHelpI {
4
5 // 总list
6 private List<?> list;
7 // 默认每页显示10条
8 private int perPage = 10;
9 // 默认当前页为 第一页
10 private int currentPage = 1;
11 // 默认页数 为 一页
12 private int pageNum = 1;
13 // 当前List
14 private List<?> cList;
15 // 所有数据总数
16 private int allNum;
17
18 /**
19 * 默认构造函数
20 *
21 * @Title:
22 * @Description:
23 */
24 public ResultListHelpImpl() {
25
26 }
27
28 /**
29 * 带参数的构造函数
30 *
31 * @Title:
32 * @Description:
33 * @param list
34 * 数据集
35 * @param perPage
36 * 每页显示条数
37 */
38 public ResultListHelpImpl(List<?> list, int perPage) {
39 this.list = list;
40 if (perPage >= 1) {
41 this.perPage = perPage;
42 }
43 if (list != null && list.size() > this.perPage) {
44 this.cList = list.subList(0, this.perPage - 1);
45 }
46 // 页数
47 this.allNum = this.list.size();
48 if (this.allNum % this.perPage == 0) {
49 this.pageNum = this.allNum / this.perPage;
50 } else {
51 this.pageNum = this.allNum / this.perPage + 1;
52 }
53 }
54
55 /**
56 *
57 * @Title: getCount
58 * @Description: 记录总数
59 * @return 设定文件
60 */
61
62 public int getCount() {
63 // TODO Auto-generated method stub
64 return this.allNum;
65 }
66
67 /**
68 *
69 * @Title: getCurrentPage
70 * @Description: 当前页数
71 * @return 设定文件
72 */
73
74 public int getCurrentPage() {
75 // TODO Auto-generated method stub
76 return this.currentPage;
77 }
78
79 /**
80 *
81 * @Title: getPageNum
82 * @Description: 获取总页数
83 * @return 设定文件
84 */
85
86 public int getPageNum() {
87 // TODO Auto-generated method stub
88
89 return this.pageNum;
90 }
91
92 /**
93 *
94 * @Title: getPerPage
95 * @Description: get 每页显示的条数
96 */
97
98 public int getPerPage() {
99 // TODO Auto-generated method stub
100 return this.perPage;
101 }
102
103 /**
104 *
105 * @Title: gotoPage
106 * @Description: go to x page
107 * @param n
108 * 设定文件
109 */
110
111 public void gotoPage(int n) {
112 // TODO Auto-generated method stub
113 if (n > this.pageNum) {
114 n = this.pageNum;
115 this.currentPage = n;
116 } else {
117 this.currentPage = n;
118 }
119 }
120
121 /**
122 *
123 * @Title: hasNextPage
124 * @Description: 是否有下一页
125 * @return 设定文件
126 */
127
128 public boolean hasNextPage() {
129 // TODO Auto-generated method stub
130 this.currentPage++;
131 if (this.currentPage <= this.pageNum) {
132 return true;
133 } else {
134 this.currentPage = this.pageNum;
135 }
136 return false;
137 }
138
139 /**
140 *
141 * @Title: hasHeadpage
142 * @Description:是否有上一页
143 * @return 设定文件
144 */
145
146 public boolean hasPrepage() {
147 // TODO Auto-generated method stub
148 this.currentPage--;
149 if (this.currentPage > 0) {
150 return true;
151 } else {
152 this.currentPage = 1;
153 }
154 return false;
155 }
156 /**
157 *
158 * @Title: nextPage
159 * @Description: 下一页
160 */
161
162 public void nextPage() {
163 // TODO Auto-generated method stub
164 this.hasNextPage();
165 }
166
167 /**
168 *
169 * @Title: prePage
170 * @Description: 前一页
171 */
172
173 public void prePage() {
174 // TODO Auto-generated method stub
175 this.hasPrepage();
176 }
177
178 /**
179 *
180 * @Title: setPerPage
181 * @Description: 每页显示的条数
182 * @param page
183 * 设定文件
184 */
185
186 public void setPerPage(int page) {
187 // TODO Auto-generated method stub
188 this.perPage = page;
189 }
190
191 /**
192 *
193 * @Title: currentList
194 * @Description: 当前记录集
195 * @return 设定文件
196 */
197
198 public List<?> getCurrentList() {
199
200 if (this.currentPage == this.pageNum) {
201 this.cList = this.list.subList((this.currentPage-1) * this.perPage, this.allNum);
202 } else {
203
204 this.cList = this.list.subList((this.currentPage - 1)
205 * this.perPage, this.currentPage * (this.perPage));
206 }
207 return this.cList;
208 }
209
210 /**
211 *
212 * @Title: initList
213 * @Description: 初始化 list
214 * @param list
215 * 设定文件
216 */
217 public void initList(List<?> list) {
218
219 this.list = list;
220 if (this.perPage <= 0) {
221 this.perPage = 10;
222 }
223
224 // 页数
225 this.allNum = this.list.size();
226 if (this.allNum % this.perPage == 0) {
227 this.pageNum = this.allNum / this.perPage;
228 } else {
229 this.pageNum = this.allNum / this.perPage + 1;
230 }
231 }
232
233 }
在 newsResultListActivity 中定义 接口的对象:
1 private ResultListHelpImpl resultListHelpI ;
在 getWebData 类中,当返回的记录不为空的时候,我们调用接口里的方法 对其做分页的处理
1 if(dataList == null || dataList.size() == 0){
2 messageListener.sendMessage(m2);
3 return;
4 }else{
5 //每页显示10笔记录
6 resultListHelpI = new ResultListHelpImpl(dataList, 10);
7
8 currentList = new ArrayList<newsDataTO>();
9 //获取当前的记录,存入currentList中
10 currentList = (List<newsDataTO>)resultListHelpI.getCurrentList();
11 messageListener.sendMessage(m1);
12 }
将之前的显示方法 displayNewsResult() 中的dataList 换成做过分页处理的currentList
1 /**
2 * 将从网络上获取的数据显示在我们自定义的ListView 里面
3 */
4 public void displayNewsResult(){
5 //无返回数据信息提示 设置为不可见,这样用户就看不到页面上 '请等待' 这些提示
6 newsResultListEmptyText.setVisibility(View.GONE);
7 //
8 newsResultListAdapter newsResultAdapter = new newsResultListAdapter(currentList, mContext);
9 newsResultList.setAdapter(newsResultAdapter);
10
11 newsResultList.setOnItemClickListener(new OnItemClickListener(){
12 @Override
13 public void onItemClick(AdapterView<?> arg0, View arg1,
14 int arg2, long arg3) {
15
16 onClickItemNo =(int) ((newsDataTO)currentList.get(arg2)).getId();
17 // http://pic.think-land.com/xml.php?id=20026
18 // startLoadingDialog();
19 // Thread t1 = new Thread(new startUpdate_detail());
20 // t1.start();
21 }
22
23 });
24 }
这时候在上页,下页的监听程序中加入翻页的逻辑,如果已经是第一页或者是最后一页,则弹出提示消息
1 result_last_pg.setOnClickListener(new OnClickListener(){
2
3 @Override
4 public void onClick(View v) {
5 if(resultListHelpI != null){
6 //如果存在上一页的话, 当前页减1
7 if(!resultListHelpI.hasPrepage()) {
8 Toast.makeText(newsResultListActivity.this,"已经是第一页了",Toast.LENGTH_SHORT).show();
9 }else{
10 currentList = (List<newsDataTO>) resultListHelpI.getCurrentList();
11 displayNewsResult();
12 }
13 }
14 }
15 });
16
17 result_next_pg.setOnClickListener(new OnClickListener(){
18
19 @Override
20 public void onClick(View v) {
21 if(resultListHelpI != null){
22 //如果存在下一页的话,当前页加1
23 if(!resultListHelpI.hasNextPage()) {
24 Toast.makeText(newsResultListActivity.this,"已经是最后一页了",Toast.LENGTH_SHORT).show();
25 }else{
26 currentList = (List<newsDataTO>) resultListHelpI.getCurrentList();
27 displayNewsResult();
28 }
29 }
30 }
31 });
重载onDestory 方法,同时给返回按钮加上监听事件,点击后关闭当前页,返回到上一菜单,如下
1 //重载的方法
2 @Override
3 public void onDestroy() {
4 super.onDestroy();
5 this.finish();
6 }
监听事件:
1 //返回按鈕
2 result_back.setOnClickListener(new OnClickListener(){
3
4 @Override
5 public void onClick(View v) {
6 onDestroy();
7 }
8 });
完整的 newsResultListActivity.java 内的代码,如下:
newsResultListActivity
1 import java.io.InputStream;
2 import java.net.URL;
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6
7 import com.thinkland.demo.mnr.common.MyNewsReaderConstant;
8 import com.thinkland.demo.mnr.common.ResultListHelpImpl;
9 import com.thinkland.demo.mnr.data.newsDataTO;
10 import com.thinkland.demo.mnr.helper.newsResultListAdapter;
11 import com.thinkland.demo.mnr.net.getWebDataHelperI;
12 import com.thinkland.demo.mnr.net.getWebDataHelperImpl;
13
14 import android.app.Activity;
15 import android.app.ProgressDialog;
16 import android.content.Context;
17 import android.content.Intent;
18 import android.os.Bundle;
19 import android.os.Handler;
20 import android.os.Message;
21 import android.view.View;
22 import android.view.View.OnClickListener;
23 import android.widget.AdapterView;
24 import android.widget.Button;
25 import android.widget.ListView;
26 import android.widget.TextView;
27 import android.widget.Toast;
28 import android.widget.AdapterView.OnItemClickListener;
29
30 public class newsResultListActivity extends Activity{
31
32 protected static final int threadS1 = 0x2311;
33 protected static final int threadF1 = 0x2312;
34
35 public String newsType = "0";
36 public List<newsDataTO> dataList;
37 public List<newsDataTO> currentList;
38 public int onClickItemNo;
39
40 public ProgressDialog pd;
41 public Button result_back, result_collection ;
42 public Button result_last_pg, result_next_pg;
43 public TextView newsResultListEmptyText; //用来显示无新闻记录,或者请用户等待 一类的提示信息
44 public ListView newsResultList; //页面的ListView控件
45
46 public Context mContext;
47 public getWebDataHelperI gwdhI;
48 private ResultListHelpImpl resultListHelpI ;
49
50 @Override
51 public void onCreate(Bundle savedInstanceState) {
52 super.onCreate(savedInstanceState);
53 setContentView(R.layout.news_result_list);
54
55 mContext = newsResultListActivity.this;
56
57 Intent aIntent = getIntent();
58 Bundle aBundle = aIntent.getExtras();
59 if(aBundle != null){
60 //获取上一个Activity 传递过来的新闻类型参数
61 newsType = aBundle.getString(MyNewsReaderConstant.MAIN_NEWS_TYPE);
62 }
63
64 //显示一个loading框
65 startLoadingDialog();
66
67 //获取页面上定义的控件资源,包括listview
68 findView();
69
70 //为空间添加监听事件
71 setListener();
72
73 //开启一个线程用来获取网络新闻数据
74 Thread webThread = new Thread(new getWebData());
75 webThread.start();
76
77 }
78
79 /**
80 * 显示一个loading 的弹出框
81 */
82 public void startLoadingDialog(){
83
84 pd = ProgressDialog.show(newsResultListActivity.this, null, MyNewsReaderConstant.PROGRESS_ALERT_LOADING, true,true);
85 }
86
87 /**
88 * 获取页面上定义的控件资源
89 */
90 public void findView(){
91
92 result_last_pg = (Button)this.findViewById(R.id.result_last_pg);
93 result_next_pg = (Button)this.findViewById(R.id.result_next_pg);
94 result_back = (Button)this.findViewById(R.id.result_back);
95 result_collection = (Button)this.findViewById(R.id.result_collection);
96 newsResultListEmptyText = (TextView)this.findViewById(R.id.newsResultListEmptyText);
97 newsResultList = (ListView)this.findViewById(R.id.newsResultList);
98 }
99
100 /**
101 * 设置页面上控件的监听事件
102 */
103 public void setListener(){
104
105 //上頁按鈕
106 result_last_pg.setOnClickListener(new OnClickListener(){
107
108 @Override
109 public void onClick(View v) {
110 if(resultListHelpI != null){
111 //如果存在上一页的话, 当前页减1
112 if(!resultListHelpI.hasPrepage()) {
113 Toast.makeText(newsResultListActivity.this,"已经是第一页了",Toast.LENGTH_SHORT).show();
114 }else{
115 currentList = (List<newsDataTO>) resultListHelpI.getCurrentList();
116 displayNewsResult();
117 }
118 }
119 }
120 });
121
122 //下頁按鈕
123 result_next_pg.setOnClickListener(new OnClickListener(){
124
125 @Override
126 public void onClick(View v) {
127 if(resultListHelpI != null){
128 //如果存在下一页的话,当前页加1
129 if(!resultListHelpI.hasNextPage()) {
130 Toast.makeText(newsResultListActivity.this,"已经是最后一页了",Toast.LENGTH_SHORT).show();
131 }else{
132 currentList = (List<newsDataTO>) resultListHelpI.getCurrentList();
133 displayNewsResult();
134 }
135 }
136 }
137 });
138
139 //返回按鈕
140 result_back.setOnClickListener(new OnClickListener(){
141
142 @Override
143 public void onClick(View v) {
144 onDestroy();
145 }
146
147 });
148
149 //收藏书签按钮
150 result_collection.setOnClickListener(new OnClickListener(){
151
152 @Override
153 public void onClick(View v) {
154 // TODO Auto-generated method stub
155
156 }
157
158 });
159 }
160
161
162 /**
163 * 将从网络上获取的数据显示在我们自定义的ListView 里面
164 */
165 public void displayNewsResult(){
166 //无返回数据信息提示 设置为不可见,这样用户就看不到页面上 '请等待' 这些提示
167 newsResultListEmptyText.setVisibility(View.GONE);
168 //
169 newsResultListAdapter newsResultAdapter = new newsResultListAdapter(currentList, mContext);
170 newsResultList.setAdapter(newsResultAdapter);
171
172 newsResultList.setOnItemClickListener(new OnItemClickListener(){
173 @Override
174 public void onItemClick(AdapterView<?> arg0, View arg1,
175 int arg2, long arg3) {
176
177 onClickItemNo =(int) ((newsDataTO)currentList.get(arg2)).getId();
178 // http://pic.think-land.com/xml.php?id=20026
179 // startLoadingDialog();
180 // Thread t1 = new Thread(new startUpdate_detail());
181 // t1.start();
182 }
183
184 });
185 }
186
187
188 /**
189 * 子线程, 用来获取网络新闻数据
190 */
191 public class getWebData implements Runnable{
192
193 @Override
194 public void run() {
195 Message m1 = new Message();
196 Message m2 = new Message();
197 m1.what = threadS1;
198 m2.what = threadF1;
199
200 dataList = new ArrayList<newsDataTO>();
201 boolean sendErrorMsg = false;
202
203 //searchValues 数组,用来存放网络查询参数
204 String[] searchColumns = {"type"};
205 String[] searchValues = {newsType};
206 gwdhI = new getWebDataHelperImpl();
207 dataList = gwdhI.getNewsResultListByType(searchColumns, searchValues);
208
209 if(dataList == null || dataList.size() == 0){
210 messageListener.sendMessage(m2);
211 return;
212 }else{
213 //每页显示10笔记录
214 resultListHelpI = new ResultListHelpImpl(dataList, 10);
215
216 currentList = new ArrayList<newsDataTO>();
217 //获取当前的记录,存入currentList中
218 currentList = (List<newsDataTO>)resultListHelpI.getCurrentList();
219 messageListener.sendMessage(m1);
220 }
221
222 }
223
224 }
225
226 Handler messageListener = new Handler(){
227
228 public void handleMessage(Message msg){
229 switch(msg.what){
230 case threadS1:
231 pd.dismiss(); //关闭loading框
232 displayNewsResult(); //显示新闻列表
233 break;
234 case threadF1:
235 pd.dismiss(); //关闭loading框
236
237 //todo 显示未能查询到记录的信息
238 newsResultListEmptyText.setVisibility(View.VISIBLE);
239 newsResultListEmptyText.setText(getResources().getString(R.string.serverConnectErrorMsg));
240 break;
241 }
242 }
243 };
244
245 @Override
246 public void onDestroy() {
247 super.onDestroy();
248 this.finish();
249 }
250 }
251
4.
Manifest
配置
无修改
5.
运行效果
a. 点击上页或者下页时候,列表内容变化,并且一页只显示10笔记录。


- 点击返回按钮,返回到上一目录

程序包下载地址:http://u.115.com/file/f5f6adce29#MyNewsReader.rar
posted on 2011-04-07 14:31 thinkland001 阅读(212) 评论(0) 收藏 举报

浙公网安备 33010602011771号