• 新闻客户端案例开发


      新闻客户端,顾名思义就是看新闻用的客户端。

      该新闻用到的知识模块有:android高级界面设计(FragmentViewPager),android网络通信(http通信),开源组件(xutils框架-HttpUtils模块、xutils框架-BitmapUtils模块),开源框架(library)。所需jar包:xUtilsgsonandroid-support-v4。

     主界面滑动标签:library框架用于主界面标签
    主界面ViewPagerViewPager与上部分的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数据的解析过程。

    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   


  • 相关阅读:
    ASM ClassReader failed to parse class file
    idea运行java项目js中文乱码如何解决
    Error:(182, 32) java: 常量字符串过长
    ssh启动报错:org.dom4j.DocumentException: Connection timed out: connect Nested exception: Connection timed out: connect
    [Intro to Deep Learning with PyTorch -- L2 -- N14] Sigmoid function
    [CSS3] CSS Selector
    [HTML5] document.activeElement
    [Intro to Deep Learning with PyTorch -- L2 -- N9] Perceptron Trick
    [Javascript] Broadcaster, operator, listener pattern: Write a debounce operator -- 1
    [CSS] place-content = align-items + justify-content
  • 原文地址:https://www.cnblogs.com/sdksdk0/p/5585074.html
Copyright © 2020-2023  润新知