关闭

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

标签: androiddemo网易新闻风格RSS抓取
617人阅读 评论(0) 收藏 举报
分类:

启动页自定义一个加载等待层

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();
		getWindowManager().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.newSAXParser();
					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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5882次
    • 积分:263
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条