这一节新闻教程,比较长,因为涉及到联网和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); } }
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; } }
//默认选中的新闻分类
mCid = 1;
好了 我们再看怎么解析 JSON吧 getSpeCateNews类
先看json的格式
当然你可以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; } }
点击下载源码