解析Json数据并通过Fragment填充到ViewPager中
2015-10-11 09:45
621 查看
昨天还有一个重要的知识点没有写,今天就整理出来写一篇博文吧。
昨天讲的最后一个知识点就是把网络解析的内容通过Fragment填充到ViewPager中。这和我们之前的一篇博文点击打开链接是比较类似的,
唯一的不同是我们需要解析出来数据来填充ViewPager,但是整体的思路都是使用Fragment来填充的。
再次明确一点,我怕自己忘了,所以又写一遍:对于使用Fragment来填充ViewPager的实现,我们自定义的Fragment所继承的Fragment
是v4包下的,还有就是MainActivity继承的是FragmentActivity。
好了,接下来我们看一下具体的实现步骤吧。
一、在activity_main.xml文件中声明一个ViewPager控件和一个LinearLayout控件
这个Linear控件是用来填充我们切换界面时的图标显示及变化的。
①这里我们先贴一下所要解析的Json数据的格式吧
②在上图中,我们想要得到内层的“subject”和"photo"所对应的数据,所以这里我们把两者封装到了一个News类中:
这里我们解析的是一段标题和一个图片,所以对于xml文件来说,一个TextView和ImageView就可以了。
①xml文件:
我们直接看代码吧,注释还是比较详细的。
昨天讲的最后一个知识点就是把网络解析的内容通过Fragment填充到ViewPager中。这和我们之前的一篇博文点击打开链接是比较类似的,
唯一的不同是我们需要解析出来数据来填充ViewPager,但是整体的思路都是使用Fragment来填充的。
再次明确一点,我怕自己忘了,所以又写一遍:对于使用Fragment来填充ViewPager的实现,我们自定义的Fragment所继承的Fragment
是v4包下的,还有就是MainActivity继承的是FragmentActivity。
好了,接下来我们看一下具体的实现步骤吧。
一、在activity_main.xml文件中声明一个ViewPager控件和一个LinearLayout控件
这个Linear控件是用来填充我们切换界面时的图标显示及变化的。
<LinearLayout 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" android:padding="10dp" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="6" > </android.support.v4.view.ViewPager> <LinearLayout android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:background="@android:color/holo_orange_light" android:orientation="horizontal"> </LinearLayout> </LinearLayout>二、接下来是明确我们想要得到的数据并把它们封装到一个类中,然后得到该类的集合
①这里我们先贴一下所要解析的Json数据的格式吧
②在上图中,我们想要得到内层的“subject”和"photo"所对应的数据,所以这里我们把两者封装到了一个News类中:
package com.example.text_05_bean; import java.io.Serializable; public class News implements Serializable { private String subject; private String photo; public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getPhoto() { return photo; } public void setPhoto(String photo) { this.photo = photo; } }③接下来是解析网络数据并得到News对象的集合,这里我们定义了一个HttpUtils工具类:
package com.example.text_05_http; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.example.text_05_bean.News; public class HttpUtils { // 得到解析出来的Json数据 public static String getJsonContent(String path) { String result = ""; BufferedReader bufr = null; try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); bufr = new BufferedReader(new InputStreamReader( conn.getInputStream())); String line = ""; while ((line = bufr.readLine()) != null) { result += line; } } catch (Exception e) { e.printStackTrace(); } finally { try { bufr.close(); } catch (IOException e) { e.printStackTrace(); } } return result; } // 得到我们需要的存放News对象的集合 public static List<News> getNews(String path) { List<News> list = new ArrayList<News>(); String json = getJsonContent(path); try { // 得到Json数据中最外层的对象 JSONObject obj = new JSONObject(json); // 根据内层的变量名称和对象类型得到我们需要的数据 JSONArray arr = obj.getJSONObject("paramz").getJSONArray("tops"); for (int i = 0; i < arr.length(); i++) { JSONObject obj2 = arr.getJSONObject(i); News news = new News(); // 根据解析到的对象得到对应的值并设置到News对象的对应属性中 news.setSubject(obj2.getString("subject")); news.setPhoto("http://litchiapi.jstv.com" + obj2.getString("photo")); // 把News对象添加到list集合中 list.add(news); } } catch (JSONException e) { e.printStackTrace(); } return list; } }三、然后是创建MyFragment类继承自v4包下的Fragment,并新建一个布局文件用来显示我们解析的内容
这里我们解析的是一段标题和一个图片,所以对于xml文件来说,一个TextView和ImageView就可以了。
①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" > <TextView android:id="@+id/tv_subject" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="50dp" android:text="信息" /> <ImageView android:id="@+id/im_photo" android:layout_width="match_parent" android:layout_height="150dp" android:layout_below="@id/tv_subject" android:layout_marginTop="10dp" android:src="@drawable/ic_launcher" /> </RelativeLayout>②MyFragment类:
package com.example.text_05; import java.net.HttpURLConnection; import java.net.URL; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.example.text_05_bean.News; public class MyFragment extends Fragment { private Bitmap bitmap; private ImageView iv; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment, null); TextView tv = (TextView) view.findViewById(R.id.tv_subject); iv = (ImageView) view.findViewById(R.id.im_photo); //得到传来的bundle对象并得到其携带的数据,就是News对象 Bundle bundle = getArguments(); News news = (News) bundle.getSerializable("news"); tv.setText(news.getSubject()); String path = news.getPhoto(); //执行加载图片的异步任务 new MyTask().execute(path); return view; } //异步任务加载图片资源 class MyTask extends AsyncTask<String, Void, Bitmap> { @Override protected Bitmap doInBackground(String... params) { try { URL url = new URL(params[0]); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); bitmap = BitmapFactory.decodeStream(conn.getInputStream()); } catch (Exception e) { e.printStackTrace(); } return bitmap; } @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); iv.setImageBitmap(bitmap); } } }四、最后一步了,也是比较难写但却又非常重要的对于ViewPager布局的填充了,
我们直接看代码吧,注释还是比较详细的。
package com.example.text_05; import java.util.ArrayList; import java.util.List; import com.example.text_05_bean.News; import com.example.text_05_http.HttpUtils; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.Menu; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; //继承自FragmentActivity public class MainActivity extends FragmentActivity { private String path = "http://litchiapi.jstv.com/api/getTops?limit=5&column=0&val=F467412B44B421716757A6B2D7635B4A"; private ViewPager viewPager; // 定义存储Fragment的集合 private List<Fragment> fragments; // 声明我们定义的Fragment的子类 private MyFragment fragment; // 声明我们在activity_main.xml文件布局中定义的LinearLayou控件 private LinearLayout layout; private List<News> list; // 定义FragmentManager管理者 private FragmentManager fm; // 定义存储圆点图标的集合 private ImageView[] icons; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewPager); fragments = new ArrayList<Fragment>(); layout = (LinearLayout) findViewById(R.id.layout); list = new ArrayList<News>(); // 获得Fragment管理者对象,对于使用Fragment填充ViewPager时,获得的管理者对象 // 是getSupportFragmentManager() fm = getSupportFragmentManager(); // 启动异步任务 new MyTask().execute(path); } // 定义异步任务解析数据得到list集合 class MyTask extends AsyncTask<String, Void, List<News>> { @Override protected List<News> doInBackground(String... params) { //调用HttpUtils中的方法得到list集合 list = HttpUtils.getNews(path); return list; } @Override protected void onPostExecute(List<News> result) { super.onPostExecute(result); // 根据解析出来的集合的长度创建MyFragment对象并把解析出来的数据依次添加到Fragment中 for (int i = 0; i < result.size(); i++) { fragment = new MyFragment(); // 把我们解析出来的News对象放置在bundle中并传序列化给Fragment // 这样该Fragment就可以得到集合中每个索引所对应的News对象 // 然后再添加到fragments集合中,这样集合中的Fragment就有数据存在了 // 并进而可以把在MyFragment得到并把数据填充到ViewPager中 Bundle bundle = new Bundle(); bundle.putSerializable("news", result.get(i)); fragment.setArguments(bundle); // 把MyFragment对象添加到fragments集合中 fragments.add(fragment); } // 创建我们自定义的适配器对象,这里需要传一个Fragment管理者参数,在onCreate方法中我们已经得到了 MyAdapter adapter = new MyAdapter(fm); viewPager.setAdapter(adapter); // 设置ViewPager的监听事件,就是当我们切换ViewPager时改变对应圆点的状态 viewPager.setOnPageChangeListener(new OnPageChangeListener() { // 当选中页面的位置为arg0时 @Override public void onPageSelected(int arg0) { // 循环设置每一个圆点图标为icon01 for (int i = 0; i < icons.length; i++) { icons[i].setImageResource(R.drawable.icon01); } // 设置arg0位置,就是我们页面所处位置的圆点图标为icon02 icons[arg0].setImageResource(R.drawable.icon02); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); // 初始化圆点,根据解析出来的集合长度定义icons数组的长度 icons = new ImageView[result.size()]; for (int i = 0; i < icons.length; i++) { // 把图片资源加载到icons数组中 icons[i] = new ImageView(MainActivity.this); icons[i].setImageResource(R.drawable.icon01); // 设置圆点的属性 icons[i].setMaxHeight(20); icons[i].setAdjustViewBounds(true); // 给圆点设置一个标记以实现在点击不同圆点时切换到不同的界面 icons[i].setTag(i); icons[i].setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 切换到当前圆点对应的ViewPager viewPager.setCurrentItem((Integer) v.getTag()); } }); // 把圆点加入到LinearLayout布局控件中 layout.addView(icons[i]); } // 默认设置第1个图标为icon02 icons[0].setImageResource(R.drawable.icon02); } } // 创建适配器,对于使用Fragment填充ViewPager,自定义适配器要继承FragmentPagerAdapter class MyAdapter extends FragmentPagerAdapter { // 其构造函数有一个FragmentManager对象 public MyAdapter(FragmentManager fm) { super(fm); } // 得到arg0位置的Fragment以填充到Activity中 @Override public Fragment getItem(int arg0) { return fragments.get(arg0); } // fragments集合的总数,简单说就是切换页面的个数 @Override public int getCount() { return fragments.size(); } } }好了,具体的实现就是这四个步骤了,接下来我们看一下运行结果吧:
相关文章推荐
- Javascript Array Reduce 用法解读
- Javascript函数式编程简单介绍
- 详解Javascript 中的this指针
- JavaScript 动态插入 CSS
- JS函数式编程【译】4.4 函数式响应式编程
- Ember.js 入门指南——包裹内容
- JS 快速排序
- Javascript的继承
- JS 对象引用和深拷贝
- Javascript函数式编程简单介绍
- Javascript函数式编程语言
- javascript函数式编程程序员的工具集
- Maven打包
- Ember.js 入门指南——包裹内容
- B/S学习之路—JavaScript学习笔记—第一天&基本语法
- JS实现Ajax---例:获取服务器时间
- B/S学习之路—JavaScript学习笔记—第二天&DOM
- 解决JSP路径问题的方法(jsp文件开头path, basePath作用)
- [LeetCode][JavaScript]Game of Life
- [LeetCode][JavaScript]Word Pattern