一、运行测试效果截图
二、程序说明
1、构造新闻实体News类。(详见News.java)
包含属性(title标题、author作者、pubDate发表日期、commentCount评论数、body新闻内容),包括构造方法、基本的get()、set()方法,对News类的封装比较简单。
/**
* 构造方法
* @param title 标题
* @param author 作者
* @param pubDate 发表日期
* @param commentCount 评论数
* @param body 新闻内容
*/
public News(String title, String author, String pubDate, int commentCount,
String body) {
super();
this.title = title;
this.author = author;
this.pubDate = pubDate;
this.commentCount = commentCount;
this.body = body;
}
2、构造存储新闻的ArrayList
(1)、有关List
(2)、在MainActivity主类中调用initNewsData()初始化每条新闻(为了简化讲解,在此暂用测试数据,自己随便编造的新闻,有关新闻的解析即来源后续还会专门讲解)。
/**
* 初始化新闻内容(插入20条新闻测试数据)
*/
private void initNewsData() {
for (int i = 1; i <= 20; i++) {
news = new News("简单的新闻列表事例标题" + i, "Freedom", "2014-1-" + i,
12 + i, "新闻内容" + i);
newsDataList.add(news);
}
}
(3)、调用testLoadNewsData()测试读取新闻列表项中的数据,我们可以使用LogCat看到测试结果。
/**
* 测试读取新闻列表项中的数据
*/
private void testLoadNewsData() {
Log.w("当前newsDataList中新闻数量为", String.valueOf(newsDataList.size()));
for (int i = 1; i <= newsDataList.size(); i++) {
News news = newsDataList.get(i - 1);
Log.i("第" + i + "条新闻标题", news.getTitle());
Log.i("第" + i + "条新闻作者", news.getAuthor());
Log.i("第" + i + "条新闻发表日期", news.getPubDate());
Log.i("第" + i + "条新闻评论数", String.valueOf(news.getCommentCount()));
Log.i("第" + i + "条新闻内容", news.getBody());
}
}
参见:使用JSoup解析HTML新闻的具体 点击打开链接
3、构造下拉刷新列表PullToRefreshListView extends ListView。(详见PullToRefreshListView.java)
(1)、有关ListView类。API中解析为A view that shows items in a vertically scrolling list. The items come from the ListAdapter
associated with this view.意思是说:ListView是一种用于垂直滚动显示列表项的视图容器(图例),其列表项的详细配置来源于列表项适配器ListAdapter类。
(2)、PullToRefreshListView类。SDK提供的ListView类是最简单原始的列表容器,显然达不到我们想要的,也是当前应用比较广泛的能够通过下拉、上滚等操作进行刷新的要求。因此我们可以通过extends ListView派生出PullToRefreshListView,重写其中的部分方法来实现这种需求,鉴于本例中新闻内容是测试数据,谈不上刷新,故在此不作此类的详细说明,后续。
4、构造新闻列表项适配器NewsListViewAdapter extends BaseAdapter。(详见NewsListViewAdapter.java)
(1)、有关BaseAdapter类。API中的解释如下图示。意思是说,BaseAdapter种由公共基类实现的适配器它用于为ListView、GridView、Spinner等列表类的容器适配列表项,由于它实现了ListAdapter、SpinnerAdapter、GridAdapter接口,所以必须重写ListAdapter中的getCount()、getItem()、getItemId()、getView()四种方法。
(2)、NewsListViewAdapter类的构造。包含属性(父列表容器listContainer、数据集合newsDataList、列表项布局资源itemViewResource、列表项组件集合listItemView),根据父列表构造列表项适配器,首先加载列表项界面(R.layout.news_list_item)、根据新闻数据条目返回列表项数目,读取每一条新闻数据并依次设置列表项上,最后返回每一个列表项。
public class NewsListViewAdapter extends BaseAdapter {
// 运行上下文
private Context context;
// 父列表视图容器
private LayoutInflater listContainer;
// 新闻数据集合
private List newsDataList;
// 列表项布局
private int itemViewResource;
// 列表项组件集合(title、author、count、date、flag)
static class ListItemView {
public TextView title;
public TextView author;
public TextView date;
public TextView count;
public ImageView flag;
}
/**
* 根据父列表构造列表项适配器,加载列表项界面、读取并设置列表项数据
* @param context 父列表
* @param newsDataList 列表项数据
* @param itemViewResource 列表项界面布局
*/
public NewsListViewAdapter(Context context, List newsDataList, int itemViewResource) {
this.context = context;
this.listContainer = LayoutInflater.from(context);
this.itemViewResource = itemViewResource;
this.newsDataList = newsDataList;
}
/**
* 根据新闻数据条目返回列表项数目
*/
public int getCount() {
return newsDataList.size();
}
public Object getItem(int arg0) {
return null;
}
public long getItemId(int arg0) {
return 0;
}
/**
* 根据位置和相关设定返回列表项
* @param position 列表项起始位置
* @param convertView 返回的每一个列表项
* @param parent 列表项父容器
*/
public View getView(int position, View convertView, ViewGroup parent) {
// 创建自定义列表项组件
ListItemView listItemView = null;
if (convertView == null) {
// 获取列表项布局(this.itemViewResource--)
convertView = listContainer.inflate(this.itemViewResource, null);
//初始化列表项各组件(title、author、count、date、flag)
listItemView = new ListItemView();
listItemView.title = (TextView) convertView
.findViewById(R.id.news_listitem_title);
listItemView.author = (TextView) convertView
.findViewById(R.id.news_listitem_author);
listItemView.count = (TextView) convertView
.findViewById(R.id.news_listitem_commentCount);
listItemView.date = (TextView) convertView
.findViewById(R.id.news_listitem_date);
listItemView.flag = (ImageView) convertView
.findViewById(R.id.news_listitem_flag);
// 设置控件集到convertView
convertView.setTag(listItemView);
} else {
listItemView = (ListItemView) convertView.getTag();
}
//依次读取列表项数据中的第position项数据赋于news对象
News news = newsDataList.get(position);
listItemView.title.setText(news.getTitle());
listItemView.author.setText(news.getAuthor());
listItemView.date.setText(news.getPubDate());
listItemView.count.setText(news.getCommentCount() + "");
listItemView.flag.setVisibility(View.VISIBLE);
return convertView;
}
}
5、构造新闻详细NewsDetail extends Activity。(详见NewsListViewAdapter.java)用于显示不同的新闻详细内容。
(1)、通过intent实例携带的position读取newsDataList中的新闻数据,并显示在详细界面的各组件中。
并显示在新闻详细界面中
/**
* 读取新闻数据并显示在新闻详细界面中
*/
private void initData() {
// 接收position位置(被点击的列表项位置news_id)
Intent intent = getIntent();
intent.getExtras();
Bundle data = intent.getExtras();
int position = data.getInt("news_id");
Log.i("接收到的数据", String.valueOf(position));
// 依position读取对应的新闻
News news = MainActivity.newsDataList.get(position-1);
news_detail_title.setText(news.getTitle());
news_detail_author.setText(news.getAuthor());
news_detail_date.setText(news.getPubDate());
news_detail_commentcount.setText(String.valueOf(news.getCommentCount()));
news_detail_body.setText(news.getBody());
}
(2)、在此类中也可以通过点击不同的列表项测试到数据。
/**
* 测试读取新闻列表项中的数据
*/
private void testNewsData() {
// 接收position位置(被点击的列表项位置news_id)
Intent intent = getIntent();
intent.getExtras();
Bundle data = intent.getExtras();
int position = data.getInt("news_id");
Log.i("测试接点击列表项位置", String.valueOf(position));
News news = MainActivity.newsDataList.get(position-1);
Log.w("标题", news.getTitle());
Log.w("作者", news.getAuthor());
Log.w("发表日期", news.getPubDate());
Log.w("评论数", String.valueOf(news.getCommentCount()));
Log.w("内容", news.getBody());
}
6、主活动MainActivity extends Activity类。(详见NewsListViewAdapter.java)
完成的操作主要包括加载主界面布局,初始化新闻数据,测试插入的数据的完整性,加载新闻列表容器,适配列表项,并为列表项绑定点击事件监听器,用于响应进入不同的新闻详细页面。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_list);
this.initNewsData();
this.testLoadNewsData();
newsListViewAdapter = new NewsListViewAdapter(this, newsDataList,
R.layout.news_list_item);
// 加载新闻列表(下拉刷新列表)
pullToRefreshListView = (PullToRefreshListView) findViewById(R.id.frame_listview_news);
// 绑定列表项适配器(为列表适配各项)
pullToRefreshListView.setAdapter(newsListViewAdapter);
// 绑定点击列表项事件监听器(依据点击的列表项启动新活动显示对应新闻详情)
pullToRefreshListView
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView> parent, View view,
int position, long id) {
Intent intent = new Intent(view.getContext(),
NewsDetail.class);
intent.putExtra("news_id", position);
view.getContext().startActivity(intent);
}
});
}
四、界面布局文件及相关资源
五、附送源代码
NewsListView.zip