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

Android demo-->网易新闻风格的RSS新闻抓取项目(一) 菜单栏、滚动广告和新闻列表的配置

2017-02-04 09:16 309 查看
启动页自定义一个加载等待层

public class LoadProgressDialog extends Dialog {

public Context context;

public LoadProgressDialog(Context context) {
super(context);
this.context = context;
}

public LoadProgressDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
this.context = context;
}

public LoadProgressDialog(Context context, int theme) {
super(context, theme);
this.context = context;

View view = LayoutInflater.from(context).inflate(R.layout.load, null);
ImageView img_loading = (ImageView) view.findViewById(R.id.img_load);
RelativeLayout img_close = (RelativeLayout) view.findViewById(R.id.img_cancel);

RotateAnimation rotateAnimation = (RotateAnimation)AnimationUtils.loadAnimation(context, R.anim.progress_bar_refresh);
img_loading.setAnimation(rotateAnimation);

setContentView(view);

img_close.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dismiss();
}
});
}
}

主界面是一个仿网易新闻客户端的样式,顶部从左到右,依次是跳转设置按钮,标题,天气按钮。下面是新闻菜单栏,分别是头条、体育、科技、娱乐、财经、更多。其中头条下先放置了一个轮播图片,再放置新闻列表,其他菜单只放置了新闻列表。

菜单栏下面有一个横条,

首先计算这个横条的移动距离

//计算横条移动距离
private void calculateOffset(){
cursor = (ImageView)findViewById(R.id.cursor);
DisplayMetrics dm = new DisplayMetrics();
getWin
4000
dowManager().getDefaultDisplay().getMetrics(dm);
int disPlayWidth = dm.widthPixels;// 获取屏幕分辨率宽度
offSet = disPlayWidth / 6; // 偏移量为六分之一屏幕
Matrix matrix = new Matrix();
matrix.postTranslate(offSet, 0);
cursor.setImageMatrix(matrix);// 设置动画初始位置
}


当点击某个菜单的时候这个横条就平移到当前菜单下

newsTitle1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//设置当前显示页面
viewPager.setCurrentItem(0);

if(curPage != 0)
{
ta = new TranslateAnimation(curPage * offSet, 0, 0, 0);
ta.setFillAfter(true);
ta.setDuration(200);
cursor.startAnimation(ta);
}
curPage = 0;
}
});

newsTitle2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
viewPager.setCurrentItem(1);
if(curPage != 1)
{
ta = new TranslateAnimation(curPage * offSet, offSet, 0, 0);
ta.setFillAfter(true);
ta.setDuration(200);
cursor.startAnimation(ta);
}
curPage = 1;
}
});

newsTitle3.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
viewPager.setCurrentItem(2);
if(curPage != 2)
{
ta = new TranslateAnimation(curPage * offSet, offSet * 2, 0, 0);
ta.setFillAfter(true);
ta.setDuration(200);
cursor.startAnimation(ta);
}
curPage = 2;
}
});

newsTitle4.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
viewPager.setCurrentItem(3);
if(curPage != 3)
{
ta = new TranslateAnimation(curPage * offSet, offSet * 3, 0, 0);
ta.setFillAfter(true);
ta.setDuration(200);
cursor.startAnimation(ta);
}
curPage = 3;
}
});

newsTitle5.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
viewPager.setCurrentItem(4);
if(curPage != 4)
{
ta = new TranslateAnimation(curPage * offSet, offSet * 4, 0, 0);
ta.setFillAfter(true);
ta.setDuration(200);
cursor.startAnimation(ta);
}
curPage = 4;
}
});

newsTitle6.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
viewPager.setCurrentItem(5);
if(curPage != 5)
{
ta = new TranslateAnimation(curPage * offSet, offSet * 5, 0, 0);
ta.setFillAfter(true);
ta.setDuration(200);
cursor.startAnimation(ta);
}
curPage = 5;
}
});


新闻列表展示使用的是ViewPager,首先把所有页面放入一个list

//映射newsViewPager需要的页面列表
viewList = new ArrayList<View>();
viewList.add(getLayoutInflater().inflate(R.layout.news_pager_1, null));
viewList.add(getLayoutInflater().inflate(R.layout.news_pager_2, null));
viewList.add(getLayoutInflater().inflate(R.layout.news_pager_3, null));
viewList.add(getLayoutInflater().inflate(R.layout.news_pager_4, null));
viewList.add(getLayoutInflater().inflate(R.layout.news_pager_5, null));
viewList.add(getLayoutInflater().inflate(R.layout.news_pager_6, null));


然后给ViewPager设置适配器来加载各菜单页面

viewPager.setAdapter(new PagerAdapter() {

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
// TODO Auto-generated method stub
((ViewPager)arg0).removeView((View)viewList.get(arg1));
}

@Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub

}

@Override
public int getCount() {
// TODO Auto-generated method stub
return viewList.size();
}

@Override
public Object instantiateItem(View arg0, int arg1) {
((ViewPager)arg0).addView((View)viewList.get(arg1), 0);

switch (arg1) {
case 0:
initNewsImgViewPager(new PictureInfoObtainFromWeb(), AllURL.picURL);
if(flagCountTopNews){
requestTopNews(new TopNewsListObtainFromXml(), AllURL.URLmarquee, new RSSHandler(0));
flagCountTopNews = false;
}
else
getTopNews();
break;

case 1:
if (flagCountSportsNews) {
requestSportsNews(new TopNewsListObtainFromXml(), AllURL.URLsports, new RSSHandler(1));
flagCountSportsNews = false;
}
else
getSportsNews();
break;

case 2:
if(flagCountScienceNews){
requestScienceNews(new TopNewsListObtainFromXml(), AllURL.URLscience, new RSSHandler(2));
flagCountScienceNews = false;
}else
getScienceNews();
break;

case 3:
if(flagCountEntainNews){
requestEntainNews(new TopNewsListObtainFromXml(), AllURL.URLentain, new RSSHandler(3));
flagCountEntainNews = false;
}else
getEntainNews();
break;

case 4:
if(flagCountFinanceNews){
requestFinanceNews(new TopNewsListObtainFromXml(), AllURL.URLfinance, new RSSHandler(4));
flagCountFinanceNews = false;
}else
getFinanceNews();
break;
}

return (View)viewList.get(arg1);
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}

@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
// TODO Auto-generated method stub

}

@Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}

@Override
public void startUpdate(View arg0) {
// TODO Auto-generated method stub

}
});


头条页面需要轮播图片,这里开启一个线程使用了Jsoup来解析URL地址,将解析到的图片信息放入list,然后通知MainActivity的Handler去处理图片信息

public class PictureInfoObtainFromWeb{
private String url = null;

public void pictureInfoObtain(String URL){
this.url = URL;
new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
Document doc = Jsoup.connect(url).timeout(8000).get();

//找到class为slides的节点
Elements divs = doc.select("div.slides");

if (divs != null) {
List<StringBuffer> picTitleBuffer = new ArrayList<StringBuffer>();
List<StringBuffer> picLinkBuffer = new ArrayList<StringBuffer>();
List<StringBuffer> pageLinkBuffer = new ArrayList<StringBuffer>();

Elements pageLink = divs.select("a[href]");
Elements picTitle = divs.select("img[alt]");
Elements picLink = divs.select("img[src]");

for(int j = 0; j < pageLink.size(); ++j){
if (pageLink.get(j) != null) {
StringBuffer temp = new StringBuffer();
temp.append(pageLink.get(j).attr("abs:href"));

pageLinkBuffer.add(temp);
}
}

for(int j = 0; j < pageLink.size(); ++j){
if (picLink.get(j) != null) {
StringBuffer temp = new StringBuffer();
temp.append(picLink.get(j).attr("abs:src"));

picLinkBuffer.add(temp);
}
}

for(int j = 0; j < pageLink.size(); ++j){
if (picTitle.get(j) != null) {
StringBuffer temp = new StringBuffer();
temp.append(picTitle.get(j).attr("alt"));

picTitleBuffer.add(temp);
}
}

for (int k = 0; k < pageLink.size(); ++k) {
PictureInfo info = new PictureInfo();
info.setPageLink(pageLinkBuffer.get(k));
info.setPicLink(picLinkBuffer.get(k));
info.setPicTitle(picTitleBuffer.get(k));

MainActivity.picInfoList.add(info);
}
}

if (MainActivity.picInfoList != null)
MainActivity.srcHandler0.sendEmptyMessage(1);

} catch (MalformedURLException e) {
// TODO: handle exception
e.printStackTrace();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}).start();
}

}


PictureObtainFromWeb负责将图片链接转换成Bitmap

public class PictureObtainFromWeb {
private String url = null;
// public static ImageView tv_image = null;
// public static TextView tv_title = null;
private Bitmap bitmap = null;

public Bitmap getPictureFromWeb(PictureInfo picInfo) {
this.url = picInfo.getPicLink().toString();

// 如果imgCache集合中有当前bitmap的url,就直接获取bitmap
if (MainActivity.imgCache.containsKey(url)) {
synchronized (MainActivity.imgCache) {
// SoftReference 软引用,如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;
// 如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。
// 软引用可用来实现内存敏感的高速缓存
SoftReference<Bitmap> bitmapReference = MainActivity.imgCache
.get(url);
if (bitmapReference != null)
bitmap = bitmapReference.get();
}
} else {// 如果imgCache集合中没有当前bitmap的url,则通过流转换,并保存到imgCache中
try {
URL u = new URL(url);
HttpURLConnection con = (HttpURLConnection) u.openConnection();
InputStream iStream = con.getInputStream();
bitmap = BitmapFactory.decodeStream(iStream);

MainActivity.imgCache.put(url,
new SoftReference<Bitmap>(bitmap));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}

return bitmap;
}
}


获取了图片之后,创建tvImageHandler来进行UI线程图片更新,对viewPagerImg设置适配器,开启一个线程实现每5秒换图片

imgAutoChangeHandler = new Handler(){
@Override
public void handleMessage(Message msg){
if (msg.what == 1) {
viewPagerImg.setCurrentItem(msg.arg1);
}
}
};

//图片list已准备好 可以为viewpagerImg的pageradapter提供数据
tvImageHandler = new Handler(){
public void handleMessage(Message msg){
tv_title.setText(picInfoList.get(0).getPicTitle());

//隐藏欢迎页面
welcomeImage.setVisibility(ImageView.INVISIBLE);
loadProgressDialog.dismiss();

viewPagerImg.setAdapter(new PagerAdapter() {
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
// TODO Auto-generated method stub
((ViewPager)arg0).removeView((ImageView)arg2);
}

@Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub

}

@Override
public int getCount() {
// TODO Auto-generated method stub
return imageViewList.size();
}

@Override
public Object instantiateItem(View arg0, int arg1){
((ViewPager)arg0).addView((ImageView)imageViewList.get(arg1), 0);
return (ImageView)imageViewList.get(arg1);
}
});

new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
try {
Thread.sleep(5000);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

Message msg = imgAutoChangeHandler.obtainMessage();
msg.what = 1;

if (picInfoList.size() == 0)
msg.arg1 = (curPageImg + 1) % 3;
else
msg.arg1 = (curPageImg + 1) % picInfoList.size();

imgAutoChangeHandler.sendMessage(msg);
curPageImg += 1;
}
}
}).start();
}
};
}
};

viewPagerImg.setCurrentItem(0);
viewPagerImg.setOnPageChangeListener(new OnPageChangeListener() {

@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
//				curPageImg = arg0;
viewPagerImg.setCurrentItem(arg0);
tv_title.setText(picInfoList.get(arg0).getPicTitle());
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub

}

@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub

}
});

接下来获取头条新闻列表,其他体育、科技、娱乐、财经和更多的新闻列表跟头条的一样,因此只讲述头条新闻列表的获取方式

首先创建一个RSSHandler,使用xml解析方式获取uri对应的数据,包括新闻标题、链接、描述、时间、作者。

public class RSSHandler extends DefaultHandler{
private RSSItem item = null;
private String tag = "";
private String temp = null;
private StringBuffer bufferTitle = null;
private StringBuffer bufferDes = null;
private int newsType = 0;

public RSSHandler(int type){
this.newsType = type;
}

public void startDodument(){

}

@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException{
super.startElement(uri, localName, qName, attributes);
if (localName.equals("item")){
item = new RSSItem();
bufferTitle = new StringBuffer();
bufferDes = new StringBuffer();
}

tag = localName;
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
if (localName.equals("item")) {

switch (newsType) {
case 0:
MainActivity.tempNewsList.add(item);
break;
case 1:
MainActivity.tempSportsNewsList.add(item);
break;
case 2:
MainActivity.tempScienceNewsList.add(item);
break;
case 3:
MainActivity.tempEntainNewsList.add(item);
break;
case 4:
MainActivity.tempFinanceNewsList.add(item);
break;
}

item = null;
bufferTitle = null;
bufferDes = null;
}
tag = null;
}

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
if (item != null) {
temp = new String(ch, start, length);

if (tag == "title") {
item.setTitle(bufferTitle.append(Html.fromHtml(temp)));

}else if (tag == "link"){
item.setLink(temp);

}else if(tag == "description") {
//				if (temp.length() < 6) {
//					item.setDescription(item.getTitle());
//				}else
item.setDescription(bufferDes.append(Html.fromHtml(temp.replaceAll("\\s", ""))));

}else if (tag == "author") {
item.setAuthor(temp);

}else if (tag == "pubDate") {
//String data = temp.substring(16, 25);
//item.setPubDate(data);
item.setPubDate(temp);
}
}
}

@Override
public void endDocument() throws SAXException {
super.endDocument();
}
}

然后创建TopNewsListObtainFromXml类,为ListView数据加载做准备

//实现topNewsListObtain接口  用户在这里实现获取listView所需数据
public class TopNewsListObtainFromXml{
private DefaultHandler mRssHandler = null;

public void topNewsListObtain(final String RssUrl, DefaultHandler rssHandler){
this.mRssHandler = rssHandler;

new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
URL url = new URL(RssUrl);
URLConnection con = url.openConnection();
con.connect();
InputStream input = con.getInputStream();

SAXParserFactory fac = SAXParserFactory.newInstance();
SAXParser parser = fac.ne
aca0
wSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setContentHandler(mRssHandler);
Reader r = new InputStreamReader(input, Charset.forName("utf-8"));
reader.parse(new InputSource(r));

if (RssUrl == AllURL.URLmarquee && MainActivity.tempNewsList.size() > 0) {
MainActivity.mMsgHandler.sendEmptyMessage(0);

}else if (RssUrl == AllURL.URLsports && MainActivity.tempSportsNewsList.size() > 0) {
MainActivity.mMsgSportsHandler.sendEmptyMessage(1);

}else if (RssUrl == AllURL.URLscience && MainActivity.tempScienceNewsList.size() > 0) {
MainActivity.mMsgScienceHandler.sendEmptyMessage(2);

}else if (RssUrl == AllURL.URLentain && MainActivity.tempEntainNewsList.size() > 0) {
MainActivity.mMsgEntainHandler.sendEmptyMessage(3);

}else if (RssUrl == AllURL.URLfinance && MainActivity.tempFinanceNewsList.size() > 0) {
MainActivity.mMsgFinanceHandler.sendEmptyMessage(4);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}).start();
}
}


最后ListView展示数据

private void requestFinanceNews(TopNewsListObtainFromXml topNewsListOb, final String url, DefaultHandler rsshandler){
topFinanceNewsList = new ArrayList<RSSItem>();
tempFinanceNewsList = new ArrayList<RSSItem>();

//获取adapter所属数据
topNewsListOb.topNewsListObtain(url, rsshandler);

mMsgFinanceHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what == 4) {
try {
for(int i = 0; i < tempFinanceNewsList.size(); ++i)
topFinanceNewsList.add(tempFinanceNewsList.get(i));

tempFinanceNewsList.clear();

topFinanceNewsListView = (TopNewsListView)findViewById(R.id.top_finance_news_listView);
listAdapterFinance = new ListAdapterFinance();
topFinanceNewsListView.setAdapter(listAdapterFinance);

topFinanceNewsListViewRefresh();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
};
}


项目名称:NewsReader
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐