安卓解析json,使用BaseAdapter添加至ListView中,中间存储用JavaBean来实现
这是一个小练习,要求解析一个提供的json文件。并将其中的id,title值获取,以ListView形式展示出来。(开发工具是android studio)
下面开始:
首先我想到的是先把json文件内容读进一个String类型的变量中去保存,然后再对字符串进行解析。Id和title可以看做为一组数据,然后整个文件有很多组数据,所以创建了
1 ArrayList<HashMap> ArrayList=new ArrayList<>();
list中保存所有条数据,需要时再获取。所以,我用了Map,当然这只是针对实现功能来讲。后来我对此进行了改进,决定用JavaBean来存储数据。JavaBean比Map在此的好处是,我可以清楚的知道每条数据由哪些部分构成,这在数据量大的时候比较有好处。
要把json文件读进来,文件放在assets目录下。文件读取的工作单独在一个.java文件里面进行,在activity里面使用
OpenFile openFile=new OpenFile(); String JsonContext=openFile.oFile("json.txt",this);
"json.txt"为文件路径,this代表传递当前context,如果不传递参数this,在一个非activity的java里面获取assets资源文件比较麻烦,所以此处传了个context对象。(至少我现在没搜到如何在一个非activity的java里面打开assets资源文件)。
这是读取文件的j代码,单独在一个java里面:
public class OpenFile extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public String oFile(String Path, Context context){ InputStream inputStream = null; try { inputStream = context.getAssets().open(Path); } catch (IOException e) { e.printStackTrace(); } InputStreamReader inputStreamReader=new InputStreamReader(inputStream); BufferedReader bufferedReader=new BufferedReader(inputStreamReader); String JsonContext="";/*存放JSON数据的字符串变量*/ String tempString; try { while((tempString =bufferedReader.readLine()) != null){ JsonContext += tempString; } } catch (IOException e) { e.printStackTrace(); } try { inputStream.close(); inputStreamReader.close();/*及时关闭流*/ } catch (IOException e) { e.printStackTrace(); } return JsonContext; } }
小练习一个,并没开多线程来读文件。
inputStream = context.getAssets().open(Path);
关于在android studio里面读取assets资源文件,可以使用上面的方法来进行。重点是解析json内容。上面用Jsoncontext获取了文件的内容,下面要进行解析:
JSONObject jsonObject_=new JSONObject(JsonContext);/*整个内容是一个对象*/ JSONArray jsonArray=jsonObject_.getJSONArray("stories");/*对象里面是一个个数组、属性,可用KEY获取某数组*/ int size = jsonArray.length();/*数组里又是一个个对象,遍历数组,利用KEY获取目标值*/for(int i = 0; i < size; i++){ JSONObject jsonObject = jsonArray.getJSONObject(i); NewsBean newsBean=new NewsBean(); String title=(String) jsonObject.get("title"); String id =jsonObject.get("id").toString(); newsBean.setId(id); newsBean.setTitle(title); newsBeanArrayList.add(newsBean);}
注释里面也已经写了一些,先把整个内容存为一个JSONObject ,这个对象里面有普通的KEY:VALUE,也有KEY:ARRAY,显然我们需要的东西在KEY:ARRAY里面,我们利用KEY也即stories来获取该数组,数组里面有好多对象,利用for循环遍历,从每个对象中获取我们想要的数据。下面是我所解析的json原文件:
{ "date": "20161228", "stories": [ { "images": [ "http://pic2.zhimg.com/7ee47bcb49143225aeb8a8a370e4d709.jpg" ], "type": 0, "id": 9094984, "ga_prefix": "122822", "title": "小事 · 即使身为医生" }, { "images": [ "http://pic1.zhimg.com/5bd9eabd8c53e171798fee13d42673fc.jpg" ], "type": 0, "id": 9103638, "ga_prefix": "122821", "title": "春节将至,我也想要个这样的形婚对象" }, { "images": [ "http://pic3.zhimg.com/772cf1999171db2992b32ae71dc071de.jpg" ], "type": 0, "id": 9104614, "ga_prefix": "122820", "title": "投行中各种岗位的职能和级别都是什么?" }, { "images": [ "http://pic2.zhimg.com/962ab131caef4de67f9a608aa1adc369.jpg" ], "type": 0, "id": 9101614, "ga_prefix": "122819", "title": "5000 块买不起袋大米,韩「圆」面额干嘛搞还么大?" }, { "images": [ "http://pic2.zhimg.com/e1bf9f3b4bb33e6c6659fe5fb3aa08fd.jpg" ], "type": 0, "id": 9104329, "ga_prefix": "122818", "title": "卡丽 · 费希尔,我们的公主,走了" }, { "images": [ "http://pic4.zhimg.com/6aba8539df59fb3dbadeaedbfaf54b4b.jpg" ], "type": 0, "id": 9104500, "ga_prefix": "122817", "title": "知乎好问题 · 如何学习单板滑雪?" }, { "images": [ "http://pic2.zhimg.com/193971026e5dc269cc03fb0b0f22483d.jpg" ], "type": 0, "id": 9103736, "ga_prefix": "122816", "title": "为什么美国本土皮卡那么火?因为鸡" }, { "title": "一个没有方向的巨人摔倒了,这是 Twitter 背后的故事", "ga_prefix": "122815", "images": [ "http://pic3.zhimg.com/b0e61dd89b0421eaf9c990b6bd10e696.jpg" ], "multipic": true, "type": 0, "id": 9103202 }, { "title": "新年到,杀年猪,鲜香爽口的酸菜白肉锅也上桌了", "ga_prefix": "122815", "images": [ "http://pic2.zhimg.com/b9045eccb23e72ce32a55b4895fc2539.jpg" ], "multipic": true, "type": 0, "id": 9095420 }, { "images": [ "http://pic1.zhimg.com/85ef349a9ced422f54029cb08106c774.jpg" ], "type": 0, "id": 9102480, "ga_prefix": "122813", "title": "孕妇呼吸被污染的空气,孩子也会受影响,这是证据" }, { "images": [ "http://pic3.zhimg.com/b4f604f118572634b1db38700c9a8c1a.jpg" ], "type": 0, "id": 9096964, "ga_prefix": "122812", "title": "大误 · 你看这有一个洞" }, { "images": [ "http://pic3.zhimg.com/573b48c15c83a4acc32bbda0a2ad8b72.jpg" ], "type": 0, "id": 9103208, "ga_prefix": "122811", "title": "听说手机都会爆炸,电动汽车那么多的电池真的安全吗?" }, { "title": "自由随性,清醒而疯狂,就爱「不正常」的浅野忠信", "ga_prefix": "122810", "images": [ "http://pic1.zhimg.com/58b11e74cc78c299766f956023c2c7b0.jpg" ], "multipic": true, "type": 0, "id": 9100776 }, { "images": [ "http://pic4.zhimg.com/7561fd80ca4122261c3b34ab31df118f.jpg" ], "type": 0, "id": 9083880, "ga_prefix": "122809", "title": "用来给孩子爬来爬去的垫子,买之前可得好好挑选" }, { "images": [ "http://pic1.zhimg.com/3d81afc4f9738fafbfee0a357c381e90.jpg" ], "type": 0, "id": 9087927, "ga_prefix": "122808", "title": "打算年后跳槽,现在就准备一份漂亮的简历吧" }, { "images": [ "http://pic4.zhimg.com/c6df92901b4aa48e6017584454481b67.jpg" ], "type": 0, "id": 9101814, "ga_prefix": "122807", "title": "一瓶一块,三瓶两块五,该怎么买?" }, { "images": [ "http://pic1.zhimg.com/11b50a06a8ae68bf32057e40b8c9b588.jpg" ], "type": 0, "id": 9086246, "ga_prefix": "122807", "title": "法律意义上,宿舍算「住宅」吗?" }, { "images": [ "http://pic3.zhimg.com/7642324a20c278c69d0c15b0cbda5be6.jpg" ], "type": 0, "id": 9101810, "ga_prefix": "122807", "title": "2016 年度盘点 · 奥巴马,全球最有名的科技宅" }, { "images": [ "http://pic3.zhimg.com/785abaf0cc4f4b26763a6c97ebd28626.jpg" ], "type": 0, "id": 9102445, "ga_prefix": "122806", "title": "瞎扯 · 如何正确地吐槽" } ],}
关于javabean的写法,很是老套:
public class NewsBean{ private String id; private String title; public String getId(){ return id; } public void setId( String newId){ this.id=newId; } public String getTitle(){ return title; } public void setTitle(String newTitle){ this.title=newTitle; } }
这是MyAdapter的书写:
public class MyAdapter extends BaseAdapter { private ArrayList<NewsBean> newsBeanArrayList; private Context context; private LayoutInflater mInflater=null; public MyAdapter(ArrayList<NewsBean> newsBeanArrayList,Context mContext){ this.newsBeanArrayList=newsBeanArrayList; this.context=mContext; } @Override public int getCount() { return this.newsBeanArrayList.size(); } @Override public Object getItem(int position) { return this.newsBeanArrayList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { NewsBean newsBean=newsBeanArrayList.get(position);//把newsBeanArrayList中特定位置的NewsBean对象获得 if (convertView==null){ convertView=mInflater.from(context).inflate(R.layout.user,null); } TextView tv_1=(TextView) convertView.findViewById(R.id.key); TextView tv_2=(TextView) convertView.findViewById(R.id.value); String id=; String title=newsBean.getTitle(); tv_1.setText(id); tv_2.setText(title); convertView.setTag(newsBean); return convertView; } }
主要是写好那四个方法,前三个基本没问题,主要是写getView,弄明白里面的三个参数的作用。这是最简单的一种写法,可以在此基础上进行很多的优化。
下面是Activity的代码:
public class Main2Activity extends ListActivity { private final String TAG="Main2Activity"; static int a=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); final ArrayList<NewsBean> newsBeanArrayList=new ArrayList<>(); /*流操作读JSON文件,并存到JsonContext中*/ OpenFile openFile=new OpenFile(); String JsonContext=openFile.oFile("json.txt",this); try { JSONObject jsonObject_=new JSONObject(JsonContext);/*整个内容是一个对象*/ JSONArray jsonArray=jsonObject_.getJSONArray("stories");/*对象里面是一个个数组、属性,可用KEY获取某数组*/ int size = jsonArray.length();/*数组里又是一个个对象,遍历数组,利用KEY获取目标值*/ Log.i(TAG,"size"+size); for(int i = 0; i < size; i++){ JSONObject jsonObject = jsonArray.getJSONObject(i); NewsBean newsBean=new NewsBean(); String title=(String) jsonObject.get("title"); String id =jsonObject.get("id").toString(); newsBean.setId(id); newsBean.setTitle(title); newsBeanArrayList.add(newsBean); } JSONArray jsonArray2=jsonObject_.getJSONArray("top_stories"); size = jsonArray2.length(); Log.i(TAG,"size"+size); for(int i = 0; i < size; i++){ JSONObject jsonObject = jsonArray2.getJSONObject(i); NewsBean newsBean=new NewsBean(); String title=(String) jsonObject.get("title"); String id =jsonObject.get("id").toString(); newsBean.setId(id); newsBean.setTitle(title); newsBeanArrayList.add(newsBean); } } catch (JSONException e) { e.printStackTrace(); } MyAdapter myAdapter=new MyAdapter(newsBeanArrayList,this);//创建适配器,传参数为NewsBean集合,Context->this, setListAdapter(myAdapter); } }
整个程序就是MainActivity 里面点击按钮进入Main2Activity,然后创建List集合,调用OpenFile打开文件,返回String类型的值赋值给JsonContext,对 JsonContext进行一步步解析,将解析得到的结果存到一个个的NewsBean对象之中,并把所有的NewsBean添加至List集合中去。最后BaseAdapter的书写为ListView添加适配器。