新闻client。顾名思义就是看新闻用的client。
该新闻用到的知识模块有: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开源码框架库,是用来实现简易新闻client上端的滑动标签。同一时候它与ViewPager控件结合终于实现的是Fragment的动态实现。
?简易新闻client上端滑动标签是用了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>
既然是一个新闻client那必需要有数据。那么数据当然就需要json解析来从第三方站点获取新闻数据,以下来简要介绍一下json数据的解析过程。
?JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。
JSON採用全然独立于语言的文本格式。可是也使用了类似于C语言家族的习惯(包含C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使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