解析Json数据并通过Fragment填充到ViewPager中

来源:互联网 发布:驱动管理软件 知乎 编辑:程序博客网 时间:2024/06/06 11:43

今天我们讲下如何从网络解析Json数据并通过Fragment填充到ViewPager中。

再次明确一点:对于使用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;@Overridepublic 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> {@Overrideprotected 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;}@Overrideprotected 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;//继承自FragmentActivitypublic 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;@Overrideprotected 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>> {@Overrideprotected List<News> doInBackground(String... params) {//调用HttpUtils中的方法得到list集合list = HttpUtils.getNews(path);return list;}@Overrideprotected 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时@Overridepublic void onPageSelected(int arg0) {// 循环设置每一个圆点图标为icon01for (int i = 0; i < icons.length; i++) {icons[i].setImageResource(R.drawable.icon01);}// 设置arg0位置,就是我们页面所处位置的圆点图标为icon02icons[arg0].setImageResource(R.drawable.icon02);}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic 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() {@Overridepublic void onClick(View v) {// 切换到当前圆点对应的ViewPagerviewPager.setCurrentItem((Integer) v.getTag());}});// 把圆点加入到LinearLayout布局控件中layout.addView(icons[i]);}// 默认设置第1个图标为icon02icons[0].setImageResource(R.drawable.icon02);}}// 创建适配器,对于使用Fragment填充ViewPager,自定义适配器要继承FragmentPagerAdapterclass MyAdapter extends FragmentPagerAdapter {// 其构造函数有一个FragmentManager对象public MyAdapter(FragmentManager fm) {super(fm);}// 得到arg0位置的Fragment以填充到Activity中@Overridepublic Fragment getItem(int arg0) {return fragments.get(arg0);}// fragments集合的总数,简单说就是切换页面的个数@Overridepublic int getCount() {return fragments.size();}}}
好了,具体的实现就是这四个步骤了,接下来我们看一下运行结果吧:








1 0
原创粉丝点击