新聞client案例開發

  新聞client。顧名思義就是看新聞用的client。java

  該新聞用到的知識模塊有:android高級界面設計(FragmentViewPager),android網絡通訊(http通訊)。開源組件(xutils框架-HttpUtils模塊、xutils框架-BitmapUtils模塊),開源框架(library)。android

所需jar包:xUtilsgsonandroid-support-v4。json

 主界面滑動標籤:library框架用於主界面標籤
主界面ViewPagerViewPager與上部分的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(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   

相關文章
相關標籤/搜索