新聞client。顧名思義就是看新聞用的client。java
該新聞用到的知識模塊有:android高級界面設計(Fragment、ViewPager),android網絡通訊(http通訊)。開源組件(xutils框架-HttpUtils模塊、xutils框架-BitmapUtils模塊),開源框架(library)。android
所需jar包:xUtils、gson、android-support-v4。json
主界面滑動標籤: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控件。app
•用了com.viewpagerindicator.TabPageIndicator這個控件以後,要對界面主題(Theme)進行改動。在styles.xml文件裏建立相關的style框架
首先導入libary庫:千萬不要直接把庫拷貝進項目目錄中。這樣可能會出現各類其它不知名的錯誤,建議經過Import Module方式一步步導入庫文件。而後在file->project structure->dependencies->3Model dependency中選擇library庫就可以了,還要在2中導入一個gson.jar和xUtils.jar。ide
此時庫已成功導入。佈局
咱們首先來寫佈局文件,activity_main.xmlpost
<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.xmlthis
<?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採用全然獨立於語言的文本格式。但是也使用了相似於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