新闻客户端,顾名思义就是看新闻用的客户端。
该新闻用到的知识模块有:android高级界面设计(Fragment、ViewPager),android网络通信(http通信),开源组件(xutils框架-HttpUtils模块、xutils框架-BitmapUtils模块),开源框架(library)。所需jar包:xUtils、gson、android-support-v4。
主界面滑动标签:library框架用于主界面标签
•主界面ViewPager:ViewPager与上部分的library框架结合做成Fragment动态效果
•ListView中的每个Item:
•
•
•HttpUtils模块进行是用于进行访问网络,获取json数据
•BitmapUtils模块进行网络图片的加载和显示
•android-support-v4.jar包提供ViewPager控件
•library开源代码框架库,是用来实现简易新闻客户端上端的滑动标签,同时它与ViewPager控件结合最终实现的是Fragment的动态实现。
•简易新闻客户端上端滑动标签是用了library开源代码框架中的com.viewpagerindicator.TabPageIndicator控件
•ViewPager控件是android-support-v4.jar包中的android.support.v4.view.ViewPager控件。
•用了com.viewpagerindicator.TabPageIndicator这个控件之后,要对界面主题(Theme)进行修改,在styles.xml文件中创建相关的style
首先导入libary库:千万不要直接把库拷贝进项目文件夹中,这样可能会出现各种其他不知名的错误,建议通过Import Module方式一步步导入库文件。然后在file->project structure->dependencies->3Model dependency中选择library库就可以了,还要在2中导入一个gson.jar和xUtils.jar。此时库已成功导入。
我们首先来写布局文件,activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <include android:id="@+id/header" android:layout_width="match_parent" android:layout_height="@dimen/header_height" layout="@layout/header"/> <com.viewpagerindicator.TabPageIndicator android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/header"> </com.viewpagerindicator.TabPageIndicator> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/indicator"> </android.support.v4.view.ViewPager> </RelativeLayout>
第2个是头部header.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="@dimen/header_height" android:background="@mipmap/setting_iv_bg" android:gravity="center"> <TextView android:text="@string/header_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/header_text_size" /> </RelativeLayout>
第三个是下面的viepage页面,fragment.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/newsList" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> </LinearLayout>
以及细节部分fragment_list_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/newIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:src="@mipmap/skyblue_logo_whatsapp_checked"/> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_toRightOf="@+id/newIcon" > <TextView android:id="@+id/newTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/newTitleTxtSize" /> <TextView android:id="@+id/newTime" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/newTimeTxtSize" /> </LinearLayout> </RelativeLayout>
既然是一个新闻客户端那必须要有数据,那么数据当然就需要json解析来从第三方网站获取新闻数据,下面来简要介绍一下json数据的解析过程。
这个时候我们需要在src中新建一个bean类来存放json的数据
public class jsonBean { private String title; private String url; private String listimage; private String pubdate; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getListimage() { return listimage; } public void setListimage(String listimage) { this.listimage = listimage; } public String getPubdate() { return pubdate; } public void setPubdate(String pubdate) { this.pubdate = pubdate; } }
然后再bean中再创建一个ListBean.java,用于存取多个新闻的内容,这里面需要两个内部类,通过data获取NewsList,然后通过NewsLis获取到NewsItem中的值。
public class listBean { //变量名最好跟json中一样 public NewsList data; public static class NewsList{ //变量名最好跟json中一样 public ArrayList<NewsItem> news; } public static class NewsItem{ public String title; public String url; public String listimage; public String pubdate; }}
接下来就需要访问网络了,新建一个utils包,再建一个NetUtils.java类
public class NetUtils { //定义我们需要的变量 private HttpUtils httpUtils; //全局变量 private Gson gson=new Gson(); private List<News> newsList=new ArrayList<News>(); private News news; //获取新闻信息 public List<News> getNews(String url){ //访问网络是一个耗时操作,建议开启新线程 GetNewsRunnable getNewsRunnable=new GetNewsRunnable(httpUtils, gson, newsList, news, url); getNewsRunnable.run(); return newsList; } public void addAll(List<News> newsList){ this.newsList.addAll(newsList); } }
新建一个GetNewsRunnable.java,请求网络。
public class GetNewsRunnable implements Runnable{ private HttpUtils httpUtils; private Gson gson; private List<News> newsList; private News news; private String url; private NetUtils netUtils; public GetNewsRunnable(HttpUtils httpUtils,Gson gson,List<News> newsList,News news,String url){ this.httpUtils=httpUtils; this.gson=gson; this.newsList=newsList; this.news=news; this.url=url; netUtils=new NetUtils(); } //run方法中访问网络并解析json数据 public void run() { if(newsList==null){ newsList=new ArrayList<News>(); } httpUtils=new HttpUtils(); httpUtils.send(HttpMethod.GET, url, new RequestCallBack<String>() { public void onFailure(HttpException arg0, String arg1) { Log.e("failure", "访问失败"); } public void onSuccess(ResponseInfo<String> responseInfo) { Log.e("success", "访问成功"); //访问成功,就进行数据解析 NewsListBean newsListBean=gson.fromJson(responseInfo.result, NewsListBean.class); //for-each循环 for(NewsListBean.NewsItem newsItem:newsListBean.data.news){ news=new News(); news.setTitle(newsItem.title); news.setListimage(newsItem.listimage); news.setUrl(newsItem.url); news.setPubdate(newsItem.pubdate); newsList.add(news); netUtils.addAll(newsList); } } }); } }好了,我们现在需要添加一个适配器了,4个构造方法getCount()、getItem、getItemId、getView可以自动生成就可以了, 在适配器中我们首先把变量写好
//定义变量 private List<News> newsList; private LayoutInflater mInflater; //获取外部布局用的 private BitmapUtils mBitmapUtils; //加载和显示图片用的
public NewsListAdapter(Context context,List<News> newsList){ this.newsList=newsList; this.mInflater=LayoutInflater.from(context); mBitmapUtils=new BitmapUtils(context); }
//真正存放东西的方法 @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder=null; if(convertView==null){//如果传进来的view为空,就进行创建,并填充内容 holder=new ViewHolder(); convertView=mInflater.inflate(R.layout.fragment_list_item, null); holder.newIcon=(ImageView) convertView.findViewById(R.id.newIcon); holder.newTime=(TextView) convertView.findViewById(R.id.newTime); holder.newTitle=(TextView) convertView.findViewById(R.id.newTitle); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); } //将数据放到我们的控件当中 News news=newsList.get(position); holder.newTitle.setText(news.getTitle()); holder.newTime.setText(news.getPubdate()); mBitmapUtils.display(holder.newIcon, news.getListimage()); return convertView; } //模拟我们传递的控件 class ViewHolder{ ImageView newIcon; TextView newTitle; TextView newTime; } //把所有News加进List中 public void addListItem(List<News> list){ newsList.addAll(list);
通过适配器将数据传送到listview中,之后我们要用到fragment,
//这里是ListView的滚动和点击事件 newsList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { // TODO Auto-generated method stub //获取新闻详细信息的地址 String descriptionUrl=newsDatas.get(position).getUrl(); //定义并实例化Intent Intent intent=new Intent(getActivity().getApplicationContext(),DescriptActivity.class); String name="url"; //将值放到intent当中 intent.putExtra(name, descriptionUrl); //开启Activity startActivity(intent); } });然后我们添加一些详情页 TabIndicatorAdapter
最后描述新闻详情
public class DescriptActivity extends Activity { private WebView newsDescription; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_descript); String url=this.getIntent().getExtras().get("url").toString(); newsDescription=(WebView) findViewById(R.id.newsDescription); /** * 适配屏幕 */ newsDescription.getSettings().setUseWideViewPort(true); newsDescription.getSettings().setLoadWithOverviewMode(true); newsDescription.setVerticalScrollBarEnabled(true); newsDescription.setHorizontalScrollBarEnabled(false); newsDescription.loadUrl(url); } }记得在清单文件中添加网络权限等,还有一些步骤就不一一细说了,具体的可以下载源码看一下。
<uses-permission android:name="android.permission.INTERNET" />最终效果图为:
源码下载地址:点击打开链接http://download.csdn.net/detail/sdksdk0/9446330