高仿新闻教程——加入网络数据(7)

这一节新闻教程,比较长,因为涉及到联网和json解析,这里的代码

联网工具 有httpclient和HttpConnnection或者xutils 都可以只要你喜欢 随君选择,但是在这一篇开头我就说了,此片文章我将会不用任何工具,所以联网工具类,我用的是Httpclient。

我尽量一步一步解析清楚,毕竟这一节如果讲清楚那就很麻烦了,因为联网和JSON都会讲很久

HttpUtils类  会得到一个json字符串

package com.xiaoxin.news.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpUtils {  

    public static String getData(String url) throws Exception {

        StringBuffer sb = new StringBuffer();
//      1. 创建HttpClient对象。
        HttpClient httpClient = new DefaultHttpClient();
//        2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
        HttpGet httpGet = new HttpGet(url);
//        3. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
        HttpResponse httpResponse = httpClient.execute(httpGet);
//        4.获得该响应消息的实体
        HttpEntity httpEntity = httpResponse.getEntity();
        
        if (httpEntity != null) {
        //5.得到一个json的流 你需要把他转成流
            InputStream instream = httpEntity.getContent();
        //6.得到是一个字节流 用BufferedReader存到混存六中
            BufferedReader reader = new BufferedReader(new InputStreamReader(

                    instream));

            String line = null;

            while ((line = reader.readLine()) != null) {

                sb.append(line);

            }
         //7.最后得到一个用toString得到String
            return sb.toString();

        }

        return null;

    }
}
到这里的时候,我想把array文件中的内容改了
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="categories">
        <item>1|焦点</item>
        <item>2|国内</item>
        <item>3|国际</item>
        <item>4|军事</item>
        <item>5|体育</item>
        <item>6|科技</item>
        <item>7|汽车</item>
        <item>8|财经</item>
        <item>9|游戏</item>
        <item>10|女人</item>
    </string-array>
</resources>
这样我们就可以通过点击 上面的标题栏 来改变显示内容,但是我突然发现 显示不了标题栏了,尼玛。。。。。。但是内容可以解析出来,这个问题就很诡异....

		//获取新闻分类
		String[] categoryArray = getResources().getStringArray(R.array.categories);
		//把新闻分类保存到List中
		final List<HashMap<String, Category>> categories = new ArrayList<HashMap<String, Category>>();
		//分割新闻类型字符串
		for(int i=0;i<categoryArray.length;i++)
		{
			String[] temp = categoryArray[i].split("[|]");
			if (temp.length==2)
			{
				int cid = StringUtil.String2Int(temp[0]);
				String title = temp[1];
				Category type = new Category(cid, title);
				HashMap<String, Category> hashMap = new HashMap<String, Category>();
				hashMap.put("category_title", type);
				categories.add(hashMap);
			}
		}

通过正则表达式 将ID和title分开了  用map集合存起来  这样就可以使用simpleadapter 将数据显示出来 上面有一个实体类,Category  也就是ID 和title  不过我把同tostring改了直接输出 title


package com.xiaoxin.news.custom;


public class Category
{
	//类型编号
	private int cid;
	//类型名称
	private String title;
	//类型次数
	private int sequnce;

	public Category()
	{
		super();
	}

	public Category(int cid, String title)
	{
		super();
		this.cid = cid;
		this.title = title;
	}

	public Category(int cid, String title, int sequnce)
	{
		super();
		this.cid = cid;
		this.title = title;
		this.sequnce = sequnce;
	}

	public int getCid()
	{
		return cid;
	}

	public void setCid(int cid)
	{
		this.cid = cid;
	}

	public String getTitle()
	{
		return title;
	}

	public void setTitle(String title)
	{
		this.title = title;
	}

	public int getSequnce()
	{
		return sequnce;
	}

	public void setSequnce(int sequnce)
	{
		this.sequnce = sequnce;
	}

	@Override
	public String toString()
	{
		return title;
	}
}

然后通过联网工具类得到的json 进行解析 其中ID 我默认选择第一个

       //默认选中的新闻分类
        mCid = 1;

好了 我们再看怎么解析 JSON吧  getSpeCateNews类


先看json的格式

高仿新闻教程——加入网络数据(7)_第1张图片

当然你可以GSON fastjson jackjson 但是 我这里用的就是自带json解析

因为json工具格式化的时候 还少了一个花括弧(大括号})

可以看出第一层是 { } 只要是大括号就用jsonobject

JSONObject jsonObject = new JSONObject(retStr);

然后就会得到大括号里面的内容 然后再取出在通过getInt 得到ret   通过 getObject得到data里面的内容

    //获取返回码,0表示成功
 int retCode = jsonObject.getInt("ret"); 如果成功在获取data里面的内容 json解析就是剥洋葱 一层一层拨开 取出我们想要的内容存到集合里面去 

如果遇到[]中括号 就用jsonArray 获取里面的内容  后面的解析 我就不叙述了,相信大家能够举一反三


/**
	 * 获取指定类型的新闻列表
	 * @param cid 类型ID
	 * @param newsList 保存新闻信息的集合
	 */
	private List<HashMap<String, Object>> getSpeCateNews(int cid)
	{
		List<HashMap<String, Object>> newsList = new ArrayList<HashMap<String, Object>>();
		String url = "http://192.168.1.12:8080/web/getSpecifyCategoryNews?cid="+cid+"&startnid=0&count=10";
		try
		{
			String retStr = HttpUtils.getData(url);
			System.out.println(retStr);
			//以Get方式请求,并获得返回结果
			JSONObject jsonObject = new JSONObject(retStr);
			//获取返回码,0表示成功
			int retCode = jsonObject.getInt("ret");
			if (0==retCode)
			{
				JSONObject dataObject = jsonObject.getJSONObject("data");
				//获取返回数目
				int totalnum = dataObject.getInt("totalnum");
				if (totalnum>0)
				{
					//获取返回新闻集合
					JSONArray newslist = dataObject.getJSONArray("newslist");
					for(int i=0;i<newslist.length();i++)
					{
						JSONObject newsObject = (JSONObject)newslist.opt(i); 
						HashMap<String, Object> hashMap = new HashMap<String, Object>();
						hashMap.put("nid", newsObject.getInt("nid"));
						hashMap.put("newslist_item_title", newsObject.getString("title"));
						hashMap.put("newslist_item_digest", newsObject.getString("digest"));
						hashMap.put("newslist_item_source", newsObject.getString("source"));
						hashMap.put("newslist_item_ptime", newsObject.getString("ptime"));
						newsList.add(hashMap);
					}
				}
				else
				{
					Toast.makeText(MainActivity.this, "该栏目下暂时没有新闻", Toast.LENGTH_LONG).show();
				}
			}
			else
			{
				Toast.makeText(MainActivity.this, "获取新闻失败", Toast.LENGTH_LONG).show();
			}
		} catch (Exception e)
		{
			e.printStackTrace();
			Toast.makeText(MainActivity.this, "获取新闻失败", Toast.LENGTH_LONG).show();
		}
		return newsList;
	}


通过json解析 我们会得到一个一个list集合内容 

<span style="font-size:18px;">newsList</span>
<span style="color:#FF0000;">然后放入simpleadapter第二个参数   第三个参数就是放集合里面 要传递的数据 </span>
new String[]{"newslist_item_title","newslist_item_digest","newslist_item_source","newslist_item_ptime"}, 
<span style="color:#CC0000;">第四个是数据要填充的 组件ID</span>
new int[]{R.id.newslist_item_title,R.id.newslist_item_digest,R.id.newslist_item_source,R.id.newslist_item_ptime});
最后  看下全部代码吧
package com.xiaoxin.news.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.GridView;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.xiaoxin.news.custom.Category;
import com.xiaoxin.news.custom.CustomSimpleAdapter;
import com.xiaoxin.news.util.DensityUtil;
import com.xiaoxin.news.util.HttpUtils;
import com.xiaoxin.news.util.StringUtil;

public class MainActivity extends Activity
{
	private final int COLUMNWIDTHPX = 55;
	private final int FLINGVELOCITYPX = 800; // 滚动距离

	private int mColumnWidthDip;
	private int mFlingVelocityDip;
	private int mCid;
	private ListView mNewsList;
	private SimpleAdapter mNewsListAdapter;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		//把px转换成dip
		mColumnWidthDip = DensityUtil.px2dip(this, COLUMNWIDTHPX);
		mFlingVelocityDip = DensityUtil.px2dip(this, FLINGVELOCITYPX);
		
		//获取新闻分类
		String[] categoryArray = getResources().getStringArray(R.array.categories);
		//把新闻分类保存到List中
		final List<HashMap<String, Category>> categories = new ArrayList<HashMap<String, Category>>();
		//分割新闻类型字符串
		for(int i=0;i<categoryArray.length;i++)
		{
			String[] temp = categoryArray[i].split("[|]");
			if (temp.length==2)
			{
				int cid = StringUtil.String2Int(temp[0]);
				String title = temp[1];
				Category type = new Category(cid, title);
				HashMap<String, Category> hashMap = new HashMap<String, Category>();
				hashMap.put("category_title", type);
				categories.add(hashMap);
			}
		}
		//默认选中的新闻分类
		mCid = 1;
		//创建Adapter,指明映射字段
		CustomSimpleAdapter categoryAdapter = new CustomSimpleAdapter(this, categories, R.layout.category_title, new String[]{"category_title"}, new int[]{R.id.category_title});
		
		GridView category = new GridView(this);
		category.setColumnWidth(mColumnWidthDip);//每个单元格宽度
		category.setNumColumns(GridView.AUTO_FIT);//单元格数目
		category.setGravity(Gravity.CENTER);//设置对其方式
		//设置单元格选择是背景色为透明,这样选择时就不现实黄色北京
		category.setSelector(new ColorDrawable(Color.TRANSPARENT));
		//根据单元格宽度和数目计算总宽度
		int width = mColumnWidthDip * categories.size();
		LayoutParams params = new LayoutParams(width, LayoutParams.FILL_PARENT);
		//更新category宽度和高度,这样category在一行显示
		category.setLayoutParams(params);
		//设置适配器
		category.setAdapter(categoryAdapter);
		//把category加入到容器中
		LinearLayout categoryList = (LinearLayout) findViewById(R.id.category_layout);
		categoryList.addView(category);
		//添加单元格点击事件
		category.setOnItemClickListener(new OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id)
			{
				TextView categoryTitle;
				//恢复每个单元格背景色
				for (int i = 0; i < parent.getChildCount(); i++)
				{
					categoryTitle = (TextView) (parent.getChildAt(i));
					categoryTitle.setBackgroundDrawable(null);
					categoryTitle.setTextColor(0XFFADB2AD);
				}
				//设置选择单元格的背景色
				categoryTitle = (TextView) (parent.getChildAt(position));
				categoryTitle.setBackgroundResource(R.drawable.categorybar_item_background);
				categoryTitle.setTextColor(0XFFFFFFFF);
			}
		});
		
		// 箭头
		final HorizontalScrollView categoryScrollview = (HorizontalScrollView) findViewById(R.id.category_scrollview);
		Button categoryArrowRight = (Button) findViewById(R.id.category_arrow_right);
		categoryArrowRight.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				categoryScrollview.fling(DensityUtil.px2dip(MainActivity.this, mFlingVelocityDip));
			}
		});
		
		//获取指定栏目的新闻列表
		List<HashMap<String, Object>> newsData = getSpeCateNews(mCid);
		mNewsListAdapter = new SimpleAdapter(this, newsData, R.layout.newslist_item, 
										new String[]{"newslist_item_title","newslist_item_digest","newslist_item_source","newslist_item_ptime"}, 
										new int[]{R.id.newslist_item_title,R.id.newslist_item_digest,R.id.newslist_item_source,R.id.newslist_item_ptime});
		mNewsList = (ListView)findViewById(R.id.newslist);
		mNewsList.setAdapter(mNewsListAdapter);
		mNewsList.setOnItemClickListener(new OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id)
			{
				Intent intent = new Intent(MainActivity.this, NewsDetailsActivity.class);
				startActivity(intent);
			}
		});
	}
	
	/**
	 * 获取指定类型的新闻列表
	 * @param cid 类型ID
	 * @param newsList 保存新闻信息的集合
	 */
	private List<HashMap<String, Object>> getSpeCateNews(int cid)
	{
		List<HashMap<String, Object>> newsList = new ArrayList<HashMap<String, Object>>();
		String url = "http://192.168.1.12:8080/web/getSpecifyCategoryNews?cid="+cid+"&startnid=0&count=10";
		try
		{
			String retStr = HttpUtils.getData(url);
			System.out.println(retStr);
			//以Get方式请求,并获得返回结果
			JSONObject jsonObject = new JSONObject(retStr);
			//获取返回码,0表示成功
			int retCode = jsonObject.getInt("ret");
			if (0==retCode)
			{
				JSONObject dataObject = jsonObject.getJSONObject("data");
				//获取返回数目
				int totalnum = dataObject.getInt("totalnum");
				if (totalnum>0)
				{
					//获取返回新闻集合
					JSONArray newslist = dataObject.getJSONArray("newslist");
					for(int i=0;i<newslist.length();i++)
					{
						JSONObject newsObject = (JSONObject)newslist.opt(i); 
						HashMap<String, Object> hashMap = new HashMap<String, Object>();
						hashMap.put("nid", newsObject.getInt("nid"));
						hashMap.put("newslist_item_title", newsObject.getString("title"));
						hashMap.put("newslist_item_digest", newsObject.getString("digest"));
						hashMap.put("newslist_item_source", newsObject.getString("source"));
						hashMap.put("newslist_item_ptime", newsObject.getString("ptime"));
						newsList.add(hashMap);
					}
				}
				else
				{
					Toast.makeText(MainActivity.this, "该栏目下暂时没有新闻", Toast.LENGTH_LONG).show();
				}
			}
			else
			{
				Toast.makeText(MainActivity.this, "获取新闻失败", Toast.LENGTH_LONG).show();
			}
		} catch (Exception e)
		{
			e.printStackTrace();
			Toast.makeText(MainActivity.this, "获取新闻失败", Toast.LENGTH_LONG).show();
		}
		return newsList;
	}
}

最后我将把数据库和服务器 端 客户端源码全部上传 数据库 是一个sql文件 你只需要直接在mysql导入即可 ,服务器端 直接在 myeclipse中配置用tomcat里面运行就行了


点击下载源码

你可能感兴趣的:(新闻)