应用详情页的json的数据在应用的文件夹中,应用的文件夹是以应用的包名开始的文件夹,之前的解析的数据都是在根目录下,只需要添加index即可,现在需要添加上包名。
HomeFragment.java点击条目实现页面的跳转,这个里面携带了参数是点击的条目的包名
/**在该方法去处理条目的点击事件*/
@Override
public void onInnerItemClick(int position) {
Toast.makeText(UiUtils.getContext(), "position:"+position, 0).show();
super.onInnerItemClick(position);
AppInfo appInfo = datas.get(position);
//点击以后跳转到详情页
Intent intent = new Intent(UiUtils.getContext(), DetailActivity.class);
//携带参数,点击的是哪一个应用,把包名传递过去
intent.putExtra("packageName", appInfo.getPackageName());
startActivity(intent);
}
package com.ldw.market.fragment;
import java.util.List;
import android.content.Intent;
import android.os.Bundle;
import android.text.format.Formatter;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import com.ldw.market.DetailActivity;
import com.ldw.market.R;
import com.ldw.market.Adapter.DefaultAdapter;
import com.ldw.market.domain.AppInfo;
import com.ldw.market.holder.BaseHolder;
import com.ldw.market.holder.HomePictureHolder;
import com.ldw.market.http.HttpHelper;
import com.ldw.market.protocol.HomeProtocol;
import com.ldw.market.utils.UiUtils;
import com.ldw.market.view.BaseListView;
import com.ldw.market.view.LoadingPage.LoadResult;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
/*
* Home页面,主体的加载的几个页面和服务器请求数据都是在BaseFragment中去实现
*/
public class HomeFragment extends BaseFragment1 {
private List<AppInfo> appInfos;//获取到app的集合
private List<String> pictures;//获取到图片地址的集合
// 当Fragment挂载的activity创建的时候调用
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
show();
}
public View createSuccessView() {
//使用自定义的ListView,ListView初始化的时候会初始化几个方法
BaseListView listView = new BaseListView(UiUtils.getContext());
//创建一个Holder
HomePictureHolder pictureHolder = new HomePictureHolder();
pictureHolder.setData(pictures);
//获取到holder的view对象
View contentView = pictureHolder.getContentView();
//设置宽和高,方便画图
//contentView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
//把holder里面的view添加到ListView的上面
listView.addHeaderView(contentView);
listView.setAdapter(new HomeAdapter(appInfos, listView));
// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载
// 第三个参数 飞速滑动的时候是否加载图片 true 不加载
listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils, false, true));
bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片
bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片
return listView;
}
private class HomeAdapter extends DefaultAdapter<AppInfo>{
//构造函数,初始化数据
public HomeAdapter(List<AppInfo> appInfos, ListView lv) {
super(appInfos, lv);
// TODO Auto-generated constructor stub
}
@Override
protected BaseHolder<AppInfo> getHolder() {
// TODO Auto-generated method stub
return new ViewHolder();
}
//加载更多数据下拉条的实现
@Override
protected List<AppInfo> onload() {
HomeProtocol protocol = new HomeProtocol();
List<AppInfo> data = protocol.load(appInfos.size());
appInfos.addAll(data);
return data;
}
/**在该方法去处理条目的点击事件*/
@Override
public void onInnerItemClick(int position) {
Toast.makeText(UiUtils.getContext(), "position:"+position, 0).show();
super.onInnerItemClick(position);
AppInfo appInfo = datas.get(position);
//点击以后跳转到详情页
Intent intent = new Intent(UiUtils.getContext(), DetailActivity.class);
//携带参数,点击的是哪一个应用,把包名传递过去
intent.putExtra("packageName", appInfo.getPackageName());
startActivity(intent);
}
}
static class ViewHolder extends BaseHolder<AppInfo>{
ImageView item_icon;
TextView item_title,item_size,item_bottom;
RatingBar item_rating;
//更新界面
@Override
public void refreshView(AppInfo data){
this.item_title.setText(data.getName());// 设置应用程序的名字
String size = Formatter.formatFileSize(UiUtils.getContext(), data.getSize());
this.item_size.setText(size);
this.item_bottom.setText(data.getDes());
float stars = data.getStars();
this.item_rating.setRating(stars); // 设置ratingBar的值
String iconUrl = data.getIconUrl(); //这个地址不全,需要加上apache地址"iconUrl": "app/com.youyuan.yyhl/icon.jpg",
//http://127.0.0.1:8090/image?name=app/com.youyuan.yyhl/icon.jpg
//第一个参数是显示图片的控件,第二个参数是显示图片的url
bitmapUtils.display(this.item_icon, HttpHelper.URL+"image?name="+iconUrl);
// 显示图片的控件
//bitmapUtils.display(holder.item_icon, HttpHelper.URL+"image?name="+iconUrl);
}
@Override
public View initView() {
View contentView = View.inflate(UiUtils.getContext(), R.layout.item_app, null);
this.item_icon = (ImageView) contentView.findViewById(R.id.item_icon);
this.item_title = (TextView) contentView.findViewById(R.id.item_title);
this.item_size = (TextView) contentView.findViewById(R.id.item_size);
this.item_bottom = (TextView) contentView.findViewById(R.id.item_bottom);
this.item_rating = (RatingBar) contentView.findViewById(R.id.item_rating);
return contentView;
}
}
@Override
public LoadResult load() {
HomeProtocol protocol = new HomeProtocol();
//获取到app的信息
appInfos = protocol.load(0);
pictures = protocol.getPictures();
return checkData(appInfos);
}
}
在DetailActivity.java中解析数据,跳转的时候参数也带上了
package com.ldw.market;
/*
* 左侧的详情页
*/
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import com.ldw.market.domain.AppInfo;
import com.ldw.market.fragment.BaseFragment1;
import com.ldw.market.holder.DetailDesHolder;
import com.ldw.market.holder.DetailInfoHolder;
import com.ldw.market.holder.DetailSafeHolder;
import com.ldw.market.holder.DetailScreenHolder;
import com.ldw.market.protocol.DetailProtocol;
import com.ldw.market.utils.UiUtils;
import com.ldw.market.view.LoadingPage;
import com.ldw.market.view.LoadingPage.LoadResult;
public class DetailActivity extends BaseActivity{
private String packageName;
private AppInfo data;
@Override
protected void initView() {
System.out.println("3333" + view);
LoadingPage loadingPage = new LoadingPage(this){
@Override
protected LoadResult load() {
return DetailActivity.this.load();
}
@Override
public View createSuccessView() {
return DetailActivity.this.createSuccessView();
}
};
System.out.println("4444" + view);
loadingPage.show();
setContentView(loadingPage);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
System.out.println("1111" + view);
// 获取到打开当前activity的意图对象
Intent intent = getIntent();
//获取到传递过来的包名
packageName = intent.getStringExtra("packageName");
//再执行父类的方法
super.onCreate(savedInstanceState);
}
private FrameLayout bottom_layout,detail_info,detail_safe,detail_des;
private HorizontalScrollView detail_screen;
private DetailInfoHolder detailInfoHolder;
private DetailScreenHolder screenHolder;
private DetailSafeHolder safeHolder;
private DetailDesHolder desHolder;
private View view;
//加载成功的界面
protected View createSuccessView() {
view = View.inflate(UiUtils.getContext(), R.layout.activity_detail, null);
// 添加信息区域
bottom_layout=(FrameLayout) view.findViewById(R.id.bottom_layout);
// 操作 应用程序信息
detail_info=(FrameLayout) view.findViewById(R.id.detail_info);
detailInfoHolder=new DetailInfoHolder();
detailInfoHolder.setData(data);
detail_info.addView(detailInfoHolder.getContentView());
System.out.println("555555" + view);
/*
//安全标记
detail_safe=(FrameLayout) view.findViewById(R.id.detail_safe);
safeHolder=new DetailSafeHolder();
safeHolder.setData(data);
detail_safe.addView(safeHolder.getContentView());
detail_des=(FrameLayout) view.findViewById(R.id.detail_des);
desHolder=new DetailDesHolder();
desHolder.setData(data);
detail_des.addView(desHolder.getContentView());
// 中间5张图片
detail_screen=(HorizontalScrollView) view.findViewById(R.id.detail_screen);
screenHolder=new DetailScreenHolder();
screenHolder.setData(data);
detail_screen.addView(screenHolder.getContentView());
*/
return view;
}
//请求服务器加载数据
protected LoadResult load() {
//服务器请求包名的数据
DetailProtocol protocol=new DetailProtocol(packageName);
data = protocol.load(0);
System.out.println("555555data" + data);
if(data == null){
return LoadResult.error;
}else{
return LoadResult.success;
}
}
@Override
protected void initActionBar() {
super.initActionBar();
//获取到actionBar,使用getSupportActionBar,getActionBar是android.app下面的getActionBar
ActionBar actionBar = getSupportActionBar();
//图标的显示与隐藏,显示返回按钮
actionBar.setDisplayHomeAsUpEnabled(true);
}
/*
// 处理actionBar菜单条目的点击事件,实现点击图标来隐藏当前的界面
@Override
public boolean onOptionsItemSelected(MenuItem item) {
System.out.println("所有");
//当前点击的条目是search
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
*/
}
DetailProtocol.java解析数据,携带了参数包名,通过构造函数来初始化数据
package com.ldw.market.protocol;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import com.ldw.market.domain.AppInfo;
/*
* 详情页请求服务器数据
*/
public class DetailProtocol extends BaseProtocol<AppInfo> {
String packageName;
//构造函数中携带了参数,包名
public DetailProtocol(String packageName) {
super();
this.packageName = packageName;
}
@Override
public AppInfo parseJson(String json) {
try {
JSONObject object = new JSONObject(json);
long id = object.getLong("id");
String name = object.getString("name");
String packageName = object.getString("packageName");
String iconUrl = object.getString("iconUrl");
float stars = Float.parseFloat(object.getString("stars"));
long size = object.getLong("size");
String downloadUrl = object.getString("downloadUrl");
String des = object.getString("des");
String downloadNum = object.getString("downloadNum");
String version = object.getString("version");
String date = object.getString("date");
String author = object.getString("author");
List<String> screen = new ArrayList<String>();
JSONArray screenArray = object.getJSONArray("screen");
for (int i = 0; i < screenArray.length(); i++) {
screen.add(screenArray.getString(i));
}
List<String> safeUrl = new ArrayList<String>();
List<String> safeDesUrl = new ArrayList<String>();
List<String> safeDes = new ArrayList<String>();
List<Integer> safeDesColor = new ArrayList<Integer>();
JSONArray jsonArray = object.getJSONArray("safe");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
safeUrl.add(jsonObject.getString("safeUrl"));
safeDesUrl.add(jsonObject.getString("safeDesUrl"));
safeDes.add(jsonObject.getString("safeDes"));
safeDesColor.add(jsonObject.getInt("safeDesColor"));
}
AppInfo appInfo = new AppInfo(id, name, packageName, iconUrl,
stars, size, downloadUrl, des, downloadNum, version, date,
author, screen, safeUrl, safeDesUrl, safeDes, safeDesColor);
return appInfo;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public String getKey() {
return "detail";
}
//携带参数去解析,
@Override
protected String getParams() {
return "&packageName=" + packageName;
}
}
BaseProtocol.java请求的数据的基类,请求服务器数据的过程中添加了包名,只有点击条目的时候包名才是不为空
package com.ldw.market.protocol;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.StringWriter;
import com.ldw.market.http.HttpHelper;
import com.ldw.market.http.HttpHelper.HttpResult;
import com.ldw.market.utils.FileUtils;
import com.lidroid.xutils.util.IOUtils;
public abstract class BaseProtocol<T> {
public T load(int index) {
// 加载本地数据
String json = loadLocal(index);
if (json == null) {
// 请求服务器
json = loadServer(index);
if (json != null) {
saveLocal(json, index);
}
}
if (json != null) {
return parseJson(json);
} else {
return null;
}
}
//从服务器请求json数据
private String loadServer(int index) {
//请求地址http://127.0.0.1:8090/home?index=1
HttpResult httpResult = HttpHelper.get(HttpHelper.URL + getKey()
+ "?index=" + index + getParams());
if(httpResult != null){
//得到结果
String json = httpResult.getString();
//System.out.println(json);
return json;
}else
{
return null;
}
}
/**
* 额外带的参数
* @return
*/
protected String getParams() {
return "";
}
//将json保存在本地:方法1把整个json文件写到一个本地文件中,方法2吧每条数据都摘出来保存在数据库中
private void saveLocal(String json, int index) {
//创建一个buffer
BufferedWriter bw = null;
try {
File dir=FileUtils.getCacheDir();
//创建一个文件
File file = new File(dir, getKey() + "_" + index + getParams()); // /mnt/sdcard/market/cache/home_0
FileWriter fw = new FileWriter(file);
bw = new BufferedWriter(fw);
//在第一行写一个过期时间
bw.write(System.currentTimeMillis() + 1000 * 100 + "");
bw.newLine();// 换行
bw.write(json);// 把整个json文件保存起来
bw.flush();
bw.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
IOUtils.closeQuietly(bw);
}
}
//加载本地保存的数据
private String loadLocal(int index) {
// 如果发现时间过期了,就不用本地的缓存
File dir=FileUtils.getCacheDir();// 获取缓存所在的文件夹
//得到缓存文件
File file = new File(dir, getKey() + "_" + index + getParams());
try {
FileReader fr=new FileReader(file);
BufferedReader br=new BufferedReader(fr);
//获取过期时间
long outOfDate = Long.parseLong(br.readLine());
//判断是否过期,
if(System.currentTimeMillis()>outOfDate){
return null;
}else{
String str=null;
StringWriter sw=new StringWriter();
while((str=br.readLine())!=null){
sw.write(str);
}
return sw.toString();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 解析json
* @param json
* @return
*/
public abstract T parseJson(String json);
/**
* 说明了关键字home,subject....
*/
public abstract String getKey();
}
DefaultAdapter.java中触发item的点击事件
package com.ldw.market.Adapter;
import java.util.List;
import com.ldw.market.domain.AppInfo;
import com.ldw.market.holder.BaseHolder;
import com.ldw.market.holder.MoreHolder;
import com.ldw.market.manager.ThreadManager;
import com.ldw.market.utils.UiUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.Toast;
/*
* BaseAdapter的共性方法的封装,使用泛型封装
*/
public abstract class DefaultAdapter<Data> extends BaseAdapter implements OnItemClickListener {
protected List<Data> datas;
private static final int DEFAULT_ITEM = 0;//普通的条目
private static final int MORE_ITEM = 1;//加载更多的条目
private ListView lv;
//get方法
public List<Data> getDatas() {
return datas;
}
//set方法
public void setDatas(List<Data> datas) {
this.datas = datas;
}
//构造函数,初始化数据
public DefaultAdapter(List<Data> datas, ListView lv) {
this.datas = datas;
//ListView添加条目点击事件
lv.setOnItemClickListener(this);
this.lv =lv;
}
// ListView 条目点击事件回调的方法
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
//Toast.makeText(UiUtils.getContext(), "position:"+position, 0).show();
position=position-lv.getHeaderViewsCount();// 获取到顶部条目的数量 位置去掉顶部view的数量
onInnerItemClick(position);
}
/**在该方法去处理条目的点击事件*/
public void onInnerItemClick(int position) {
}
//ListView条目事件的回调方法
@Override
public int getCount() {
// +1是尾部添加一个加载更多
return datas.size() + 1;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return datas.get(position);
}
/** 根据位置 判断当前条目是什么类型 */
@Override
public int getItemViewType(int position) {
if (position == datas.size()) { // 当前是最后一个条目,加载更多
return MORE_ITEM;
}
// 如果不是最后一个条目 返回默认类型
return getInnerItemViewType(position);
}
protected int getInnerItemViewType(int position) {
// 返回默认类型
return DEFAULT_ITEM;
}
/** 当前ListView 有几种不同的条目类型 ,默认只有一种Holder*/
@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return super.getViewTypeCount()+ 1; // 2 有两种不同的类型
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//BaseHolder使用泛型以支持多种数据类型的Holder
BaseHolder holder = null;
//当前是最后的一个位置显示加载更多MoreHolder
switch (getItemViewType(position)) { // 判断当前条目时什么类型
case MORE_ITEM:
//从MoreHolder中获取Holder
if(convertView==null){
//加载更多
holder=getMoreHolder();
}else{
//缓冲中获取
holder=(BaseHolder) convertView.getTag();
}
break;
default:
//从默认中获取Holder
if (convertView == null) {
holder = getHolder();
} else {
holder = (BaseHolder) convertView.getTag();
}
if (position < datas.size()) {
holder.setData(datas.get(position));
}
break;
}
// 如果当前Holder 恰好是MoreHolder 证明MoreHOlder已经显示
return holder.getContentView();
}
private MoreHolder holder;
private BaseHolder getMoreHolder() {
if(holder!=null){
return holder;
}else{
holder=new MoreHolder(this, hasMore());
return holder;
}
}
//默认有额外数据
protected boolean hasMore() {
return true;
}
protected abstract BaseHolder<Data> getHolder();
//当加载更多条目显示的时候 调用该方法
public void loadMore() {
ThreadManager.getInstance().createLongPool().execute(new Runnable() {
@Override
public void run() {
// 在子线程中加载更多
final List<Data> newData = onload();
//主线程刷新界面
UiUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
//链接服务器失败
if(newData==null){
holder.setData(MoreHolder.LOAD_ERROR);
}else if(newData.size()==0){
//没有数据了
holder.setData(MoreHolder.HAS_NO_MORE);
}else{
// 成功了,加载更多数据
holder.setData(MoreHolder.HAS_MORE);
datas.addAll(newData);// 给listView之前的集合添加一个新的集合
notifyDataSetChanged();// 刷新界面
}
}
});
}
});
}
/**
* 加载更多数据
*/
protected abstract List<Data> onload();
}
LoadingPage.java加载页面的方法,显示加载页面的状态,并加载数据
package com.ldw.market.view;
import com.ldw.market.R;
import com.ldw.market.manager.ThreadManager;
import com.ldw.market.utils.UiUtils;
import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
/*
* 创建了自定义帧布局 把baseFragment 一部分代码 抽取到这个类中
*/
public abstract class LoadingPage extends FrameLayout {
public static final int STATE_UNKOWN = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_ERROR = 2;
public static final int STATE_EMPTY = 3;
public static final int STATE_SUCCESS = 4;
public int state = STATE_UNKOWN;
private View loadingView;// 加载中的界面
private View errorView;// 错误界面
private View emptyView;// 空界面
private View successView;// 加载成功的界面
public LoadingPage(Context context) {
super(context);
init();
}
public LoadingPage(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public LoadingPage(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
loadingView = createLoadingView(); // 创建了加载中的界面
if (loadingView != null) {
this.addView(loadingView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
errorView = createErrorView(); // 加载错误界面
if (errorView != null) {
this.addView(errorView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
emptyView = createEmptyView(); // 加载空的界面
if (emptyView != null) {
this.addView(emptyView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
showPage();// 根据不同的状态显示不同的界面
}
// 根据不同的状态显示不同的界面
private void showPage() {
if (loadingView != null) {
loadingView.setVisibility(state == STATE_UNKOWN
|| state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);
}
if (errorView != null) {
errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE
: View.INVISIBLE);
}
if (emptyView != null) {
emptyView.setVisibility(state == STATE_EMPTY ? View.VISIBLE
: View.INVISIBLE);
}
if (state == STATE_SUCCESS) {
if (successView == null) {
successView = createSuccessView();
this.addView(successView, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
successView.setVisibility(View.VISIBLE);
} else {
if (successView != null) {
successView.setVisibility(View.INVISIBLE);
}
}
}
/* 创建了空的界面 */
private View createEmptyView() {
View view = View.inflate(UiUtils.getContext(), R.layout.loadpage_empty,
null);
return view;
}
/* 创建了错误界面 */
private View createErrorView() {
View view = View.inflate(UiUtils.getContext(), R.layout.loadpage_error,
null);
Button page_bt = (Button) view.findViewById(R.id.page_bt);
page_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
show();
}
});
return view;
}
/* 创建加载中的界面 */
private View createLoadingView() {
View view = View.inflate(UiUtils.getContext(),
R.layout.loadpage_loading, null);
return view;
}
public enum LoadResult {
error(2), empty(3), success(4);
int value;
LoadResult(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
// 根据服务器的数据 切换状态
public void show() {
if (state == STATE_ERROR || state == STATE_EMPTY) {
state = STATE_LOADING;
}
// 请求服务器 获取服务器上数据 进行判断
// 请求服务器 返回一个结果
ThreadManager.getInstance().createLongPool().execute(new Runnable() {
@Override
public void run() {
SystemClock.sleep(500);
final LoadResult result = load();
UiUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if (result != null) {
state = result.getValue();
showPage(); // 状态改变了,重新判断当前应该显示哪个界面
}
}
});
}
});
showPage();
}
/***
* 创建成功的界面
*
* @return
*/
public abstract View createSuccessView();
/**
* 请求服务器
*
* @return
*/
protected abstract LoadResult load();
}