198.m1-lsitView显示subject的信息

来源:互联网 发布:网络交易投诉电话 编辑:程序博客网 时间:2024/05/21 18:48

操作的模式和app的显示类似,首先创建一个SubjectProtacal来请求服务器的json资源并解析,然后在SubjectFragment中通过ListView显示

由于HomeProtacal和SubjectProtacal请求中网络请求,保存在本地以及本地资源的加载都是类似的,解析不是类似的,因此现在将共性封装成BaseProtacal,在BaseProtacal.java中通过泛型来初始化相关的数据

同时,图片资源显示的BitmapUtils也是需要每次去创建,可以在BaseFragment中直接去创建避免在HomeFragment和SubjectFragment中重复创建,请求的数据的校检也在BaseFragment中实现,因为每一组数据的请求都会去校检

BaseFragment.java

package com.ldw.market.fragment;import java.util.List;import com.ldw.market.R;import com.ldw.market.domain.AppInfo;import com.ldw.market.manager.ThreadManager;import com.ldw.market.utils.BitmapHelper;import com.ldw.market.utils.ViewUtils;import com.lidroid.xutils.BitmapUtils;import android.os.Bundle;import android.os.SystemClock;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.FrameLayout;import android.widget.FrameLayout.LayoutParams;public abstract class BaseFragment extends Fragment {//初始化页面加载的5种状态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;// 加载成功的界面private FrameLayout frameLayout;protected BitmapUtils bitmapUtils;//创建一个View对象@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {bitmapUtils = BitmapHelper.getBitmapUtils();if(frameLayout == null){frameLayout = new FrameLayout(getActivity());init(); // 在FrameLayout中 添加4种不同的界面:加载中, 加载错误,加载为空 ,加载成功}else{ViewUtils.removeParent(frameLayout);}//show();// 根据服务器的数据 切换状态return frameLayout;}// 在FrameLayout中 添加4种不同的界面:加载中, 加载错误,加载为空 ,加载成功private void init() {// 创建了加载中的界面loadingView = createLoadingView(); if (loadingView != null) {frameLayout.addView(loadingView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));}// 加载错误界面errorView = createErrorView(); if (errorView != null) {frameLayout.addView(errorView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));}// 加载空的界面emptyView = createEmptyView(); if (emptyView != null) {frameLayout.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) {//为空的时候创建ViewsuccessView = createSuccessView();frameLayout.addView(successView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));successView.setVisibility(View.VISIBLE);}}else{//不成功的时候让页面隐藏if(successView != null){successView.setVisibility(View.INVISIBLE);}}}//加载成功的界面public abstract View createSuccessView();/* 创建加载中的界面 */private View createErrorView() {View view = View.inflate(getActivity(), R.layout.loadpage_error, null);//点击按钮重新请求服务器更新界面Button page_bt = (Button) view.findViewById(R.id.page_bt);page_bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {show();}});return view;}/* 加载错误界面 */private View createEmptyView() {View view = View.inflate(getActivity(), R.layout.loadpage_empty, null);return view;}/* 加载空的界面 */private View createLoadingView() {View view = View.inflate(getActivity(), R.layout.loadpage_loading, null);return view;}//更具服务器获取的状态显示界面public void show() {//更新状态,当加载错误以后或者加载了空页面时候需要更新一下状态if (state == STATE_ERROR || state == STATE_EMPTY) {state = STATE_LOADING;}// 请求服务器 获取服务器上数据 进行判断// 请求服务器 返回一个结果//子线程中请求服务器,同时休眠一下//使用线程池管理ThreadManager.getInstance().createLongPool().execute(new Runnable(){@Overridepublic void run() {//休眠2sSystemClock.sleep(2000);final LoadResult result = load();//主线程刷新界面getActivity().runOnUiThread(new Runnable() {@Overridepublic void run() {if(result != null){//更新状态state = result.getValue();//更新界面showPage();}}});}});showPage();}//服务器返回的数据protected abstract LoadResult load();//服务器返回的枚举结果,来显示界面public enum LoadResult{error(2), empty(3), success(4);int value;//获取服务器返回的结果LoadResult(int value) {this.value = value;}//获取到valuepublic int getValue() {return value;}}//校验数据public LoadResult checkData(List datas){if(datas == null){return LoadResult.error;//请求服务器数据失败}else{if(datas.size() == 0){return LoadResult.empty;}else{return LoadResult.success;}}}}
BaseProtocol.java网络请求共性部分抽取出来,json数据的解析各个子类自己实现

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=1HttpResult httpResult = HttpHelper.get(HttpHelper.URL + getKey()+ "?index=" + index); //得到结果String json = httpResult.getString();//System.out.println(json);return json;}//将json保存在本地:方法1把整个json文件写到一个本地文件中,方法2吧每条数据都摘出来保存在数据库中private void saveLocal(String json, int index) {//创建一个bufferBufferedWriter bw = null;try {File dir=FileUtils.getCacheDir();//创建一个文件File file = new File(dir, getKey() + "_" + index); // /mnt/sdcard/market/cache/home_0FileWriter 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); 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();}

SubjectProtocol.java

package com.ldw.market.protocol;import java.util.ArrayList;import java.util.List;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import com.ldw.market.domain.AppInfo;import com.ldw.market.domain.SubjectInfo;/* * SubjectProtocol网络请求 */public class SubjectProtocol extends BaseProtocol <List<SubjectInfo>>{@Overridepublic List<SubjectInfo> parseJson(String json) {List<SubjectInfo> subjectInfos=new ArrayList<SubjectInfo>();try {//[]需要JSONArrayJSONArray jsonArray=new JSONArray(json);for(int i=0;i<jsonArray.length();i++){//大括号需要getJSONObject,获取到大括号对象JSONObject jsonObject = jsonArray.getJSONObject(i);String des=jsonObject.getString("des");String url = jsonObject.getString("url");SubjectInfo info=new SubjectInfo(des, url);subjectInfos.add(info);}return subjectInfos;} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}@Overridepublic String getKey() {return "subject";}}
HomeProtocal.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 java.util.ArrayList;import java.util.List;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import com.ldw.market.domain.AppInfo;import com.ldw.market.http.HttpHelper;import com.ldw.market.http.HttpHelper.HttpResult;import com.ldw.market.utils.FileUtils;import com.lidroid.xutils.HttpUtils;import com.lidroid.xutils.exception.HttpException;import com.lidroid.xutils.http.ResponseStream;import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;import com.lidroid.xutils.util.IOUtils;public class HomeProtocal extends BaseProtocol <List<AppInfo>>{//解析json数据public List<AppInfo> parseJson(String json) {List<AppInfo> appInfos = new ArrayList<AppInfo>();try {JSONObject jsonObject = new JSONObject(json);//获取到中括号的内容JSONArray jsonArray = jsonObject.getJSONArray("list");//遍历list数组,list数组里面又是由大括号构成for(int i = 0; i < jsonArray.length(); i++){JSONObject jsonObj = jsonArray.getJSONObject(i);long id = jsonObj.getLong("id");String name = jsonObj.getString("name");String packageName = jsonObj.getString("packageName");String iconUrl = jsonObj.getString("iconUrl");float stars = Float.parseFloat(jsonObj.getString("stars"));long size = jsonObj.getLong("size");String downloadUrl = jsonObj.getString("downloadUrl");String des = jsonObj.getString("des");//构造函数,创建一个appInfoAppInfo appInfo = new AppInfo(id, name, packageName, iconUrl,stars, size, downloadUrl, des);//往集合中添加对象appInfos.add(appInfo);}return appInfos;} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}@Overridepublic String getKey() {// TODO Auto-generated method stubreturn "home";}}
SubjectFragment.java

package com.ldw.market.fragment;import java.util.List;import com.ldw.market.R;import com.ldw.market.domain.SubjectInfo;import com.ldw.market.fragment.BaseFragment.LoadResult;import com.ldw.market.http.HttpHelper;import com.ldw.market.protocol.SubjectProtocol;import com.ldw.market.utils.BitmapHelper;import com.ldw.market.utils.UiUtils;import com.lidroid.xutils.BitmapUtils;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.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;public class SubjectFragment extends BaseFragment {private List<SubjectInfo> datas;@Overridepublic View createSuccessView() {ListView listView=new ListView(UiUtils.getContext());listView.setAdapter(new SubjectAdapter());return listView;}private class SubjectAdapter extends BaseAdapter{@Overridepublic int getCount() {// TODO Auto-generated method stubreturn datas.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn datas.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view;ViewHolder holder;if(convertView==null){view=View.inflate(UiUtils.getContext(), R.layout.item_subject, null);holder=new ViewHolder();holder.item_icon=(ImageView) view.findViewById(R.id.item_icon);holder.item_txt=(TextView) view.findViewById(R.id.item_txt);view.setTag(holder);}else{view=convertView;holder=(ViewHolder) view.getTag();}SubjectInfo info=datas.get(position);holder.item_txt.setText(info.getDes());bitmapUtils.display(holder.item_icon, HttpHelper.URL+"image?name="+info.getUrl());return view;}}class ViewHolder{ImageView item_icon;TextView item_txt;}@Overrideprotected LoadResult load() {SubjectProtocol protocol=new SubjectProtocol();datas = protocol.load(0);return checkData(datas);}}
subject页面的布局文件item_subject

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"     >    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginLeft="9dip"        android:layout_marginRight="9dip"        android:background="@drawable/list_item_bg" >        <ImageView            android:id="@+id/item_icon"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:scaleType="fitCenter"            android:src="@drawable/ic_default"             android:padding="5dp"/>        <TextView            android:id="@+id/item_txt"            style="@style/TitleStyle"            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:layout_below="@id/item_icon"            android:gravity="center_vertical"            android:paddingBottom="5dp"            android:paddingLeft="5dp"            android:paddingRight="5dp"            android:singleLine="true" />    </RelativeLayout></FrameLayout>
在res/values/styles.xml中添加样式

    <style name="TitleStyle">        <item name="android:textColor">@color/txt_title</item>        <item name="android:textSize">@dimen/list_item_title_size</item>        <item name="android:ellipsize">end</item>        <item name="android:singleLine">true</item>    </style>
res/values/demons.xml中设置大小

<dimen name="list_item_title_size">16dp</dimen>
res/values/colors.xml中设置颜色

<color  name="txt_title">#333333</color>