1.这1篇我们要从网络为首页加载数据,解析数据,并为各个组件设置数据。我们先来看看HomePage的代码,逻辑后面分析。代码看起虽然挺多的,逻辑却没有几步。
public class HomeBasePage extends BasePage {
private Gson mGson;
private HomeDataBean mHomeData;
private List<HomeLunboData> mLunboDatas = new ArrayList<HomeDataBean.HomeLunboData>();
private List<HomeListViewData> mListViewDatas = newArrayList<HomeDataBean.HomeListViewData>();
private LunboAdapter mLunboAdapter;
private int selectedPosition;
private ListViewAdapter mListViewAdapter;
private BitmapUtils mBitmapUtils;
public HomeBasePage(MainActivity mainActivity) {
super(mainActivity);
// TODO自动生成的构造函数存根
}
@Override
public void initData(String themeDailyNumber) {
// BitmapUtils类专门用来异步从网络加载图片
if (mBitmapUtils == null) {
mBitmapUtils = new BitmapUtils(mainActivity);
mBitmapUtils.configDefaultBitmapConfig(Config.ARGB_4444);
}
// 首页显示设置按钮
ibSetting.setVisibility(View.VISIBLE);
// 设置首页标题
tvTitle.setText("首页");
// 从网络中加载数据
loadData();
}
@Override
protected void initListener() {
vpLunboPic.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// 轮播图1切换,拿到该页面的position,传给成员变量selectedPosition
selectedPosition = position;
// 为轮播图设置标题并把该页面对应的点从灰色变成白色
setTextAndSelectPoint();
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO自动生成的方法存根
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO自动生成的方法存根
}
});
// ListView的item1点击,带着该item的文章id去ArticleActivity
lvNews.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// 由于ListView有个头布局,而头布局的position为0,头布局不是文章item,所以position != 0
if (position != 0) {
String url = MyContants.BASEARTICLESTRING + mHomeData.stories.get(position⑴).id;
Intent intent = new Intent(mainActivity,ArticleActivity.class);
intent.putExtra("articleUrl", url);
mainActivity.startActivity(intent);
}
}
});
super.initListener();
}
private void loadData() {
mLunboAdapter = new LunboAdapter();
// 为轮播图的ViewPager设置Adapter
vpLunboPic.setAdapter(mLunboAdapter);
mListViewAdapter = new ListViewAdapter();
// 为ListView设置Adapter
lvNews.setAdapter(mListViewAdapter);
// 先从SharedPreference里面拿json数据
String jsonCache = SpTools.getString(mainActivity,
MyContants.HOMELATEST, "");
// 如果数据存在,直接去解析Json数据
if (!TextUtils.isEmpty(jsonCache)) {
// System.out.println(jsonCache);
parseData(jsonCache);
}
HttpUtils httpUtils = new HttpUtils();
// 用HttpUtils异步从网络获得数据
// 第1个参数:get方式获得数据
// 第2个参数:url地址
// 第3个参数:回调对象,获得数据成功或获得数据失败后调用
httpUtils.send(HttpMethod.GET, MyContants.HOMELATEST,
new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
// 获得数据成功后,拿到json数据
String homeJsonData = responseInfo.result;
// 这里做1个缓存,把json数据保存到SharedPreference里面
SpTools.putString(mainActivity,MyContants.HOMELATEST,
homeJsonData);
// System.out.println("Data" +homeJsonData);
if (!TextUtils.isEmpty(homeJsonData) ) {
parseData(homeJsonData);
}
}
@Override
public void onFailure(HttpException error, String msg) {
// TODO自动生成的方法存根
}
});
}
private void parseData(String homeJsonData) {
// 创建Gson对象,这个对象只要有1个就能够了,所以只有为空的时候才创建
if (mGson == null) {
mGson = new Gson();
}
// 用Gson解析数据
mHomeData = mGson.fromJson(homeJsonData, HomeDataBean.class);
//System.out.println(mHomeData.stories.get(0).images.get(0));
// 处理数据
processData();
}
private void processData() {
// 1.给ViewPager数据
setLunboData();
// 2.初始化点
initLunboPoints();
// 3.设置标题及点的选中
setTextAndSelectPoint();
// 4.为ListView设置数据
setListViewData();
}
private void setListViewData() {
// 为ListView设置数据
mListViewDatas = mHomeData.stories;
}
private class ListViewAdapter extends BaseAdapter {
@Override
public int getCount() {
return mListViewDatas.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroupparent) {
ViewHolder viewHolder;
if (convertView == null) {
// 加载ListView的item的布局
convertView = View.inflate(mainActivity, R.layout.list_item,
null);
viewHolder = new ViewHolder();
// 拿到item里面的各个组件
viewHolder.textView = (TextView) convertView
.findViewById(R.id.tv_list_item_title);
viewHolder.imageView = (ImageView) convertView
.findViewById(R.id.iv_list_item_image);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// 为item里面的TextView组件设置标题
viewHolder.textView.setText(mListViewDatas.get(position).title);
// 为item里面的ImageView组件设置图片,还是用BitmapUtils异步加载
String listImageUrl = mListViewDatas.get(position).images.get(0);
if (!TextUtils.isEmpty(listImageUrl)) {
mBitmapUtils.display(viewHolder.imageView, listImageUrl);
} else {
viewHolder.imageView.setVisibility(View.GONE);
}
return convertView;
}
}
private class ViewHolder {
TextView textView;
ImageView imageView;
}
private voidsetTextAndSelectPoint() {
// 设置轮播图的标题
tvLunboTitle.setText(mHomeData.top_stories.get(selectedPosition).title);
// 遍历,轮播图的setOnPageChangeListener的onPageChange方法中拿到了当前的页面的position,
// 并把它传给selectedPosition,如果i为selectedPosition,则把点设为白点
for (int i = 0; i < mLunboDatas.size(); i++) {
llLunboPoints.getChildAt(i).setEnabled(i == selectedPosition);
}
}
private void initLunboPoints() {
// 先移除轮播图下面所有的点
llLunboPoints.removeAllViews();
// 遍历轮播图的数量,即有多少轮播图,就创建几个点
for (int i = 0; i < mLunboDatas.size(); i++) {
View view = new View(mainActivity);
// 为View设置背景,背景为1个选择器,state_enabled为true的时候为白点,为false的时候为灰点
view.setBackgroundResource(R.drawable.selector_lunbo_points);
// 默许都设为灰色点
view.setEnabled(false);
// 为点View创建LayoutParams,里面传入的参数是px
// 所以我们创建了1个工具类DensityUtil的dip2px()方法将density单位转为像素单位px
LayoutParams layoutParams = new LayoutParams(DensityUtil.dip2px(
mainActivity, 5), DensityUtil.dip2px(mainActivity, 5));
// 为点View设置左侧边距
layoutParams.leftMargin = DensityUtil.dip2px(mainActivity, 5);
// 为点View设置LayoutParams
view.setLayoutParams(layoutParams);
// 把点加进LinearLayout
llLunboPoints.addView(view);
}
}
private class LunboAdapter extends PagerAdapter {
@Override
public int getCount() {
return mLunboDatas.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO自动生成的方法存根
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Objectobject) {
container.removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 轮播图的每页页面都是1个ImageView
ImageView imageView = new ImageView(mainActivity);
// ImageView上面的图片x轴,y轴上都拉伸
imageView.setScaleType(ScaleType.FIT_XY);
// 用BitmapUtills从网上异步加载图片,并放在ImageView容器中
// 第1个参数为容器
// 第2个参数为url
mBitmapUtils.display(imageView,
mHomeData.top_stories.get(position).image);
// 轮播图的ImageView1点击,带着该轮播图页面的文章id去ArticleActivity
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String url = MyContants.BASEARTICLESTRING + mHomeData.top_stories.get(vpLunboPic.getCurrentItem()).id;
Intent intent = new Intent(mainActivity,ArticleActivity.class);
intent.putExtra("articleUrl", url);
mainActivity.startActivity(intent);
}
});
container.addView(imageView);
return imageView;
}
}
private void setLunboData() {
// 拿到轮播图的数据
mLunboDatas = mHomeData.top_stories;
// 更新轮播图的展现
mLunboAdapter.notifyDataSetChanged();
}
}
2.我们现在来分析逻辑
进程上面已有了,不过就是设置1些能设置的控件,需要从网络拿的数据的进程就是,先从本地拿,本地没有,再去网络拿,然后就解析数据,然后用解析后的数据为轮播图及ListView设置数据,轮播图和ListView都用Adapter,进程也大同小异,前面都讲过了。还是不会的话看代码的注释吧。
3.这里我们专门来说1下怎样用Gson来解析json数据
1)Gson包复制到libs目录下面
2.从网上拿到json数据,放到HiJson软件下面
3.在项目中专门创建1个bean包,专门放各种Bean类
4.以首页数据为例,我们从网上拿到的数据是这样的
5.接下去放到Hijson里面格式化
6.根据结构创建HomeDataBean
public class HomeDataBean {
public String date;
public List<HomeListViewData> stories;
public List<HomeLunboData> top_stories;
// ListView的数据
public class HomeListViewData {
public String ga_prefix;
public String id;
public List<String> images;
public String title;
public String type;
public String multipic;
}
// 轮播图的数据
public class HomeLunboData {
public String ga_prefix;
public String id;
public String image;
public String title;
public String type;
}
}
7.创建Gson对象,调用Gson对象的fromJson方法解析
if (mGson == null) {
mGson = new Gson();
}
mHomeData = mGson.fromJson(homeJsonData, HomeDataBean.class);