198.m1-lsitView显示subject的信息

本文介绍了一种在Android应用中实现统一加载界面的方法,通过BaseFragment抽象类实现了不同状态下的界面展示,包括加载中、加载错误、加载为空及加载成功等状态,并详细解释了BaseProtocol类如何处理网络请求及本地缓存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

操作的模式和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对象
		@Override
		public 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) {
					//为空的时候创建View
					successView = 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() {

				@Override
				public 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(){

				@Override
				public void run() {
					//休眠2s
					SystemClock.sleep(2000);
					final LoadResult result = load();
						//主线程刷新界面
						getActivity().runOnUiThread(new Runnable() {
		
							@Override
							public 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;
			}

			//获取到value
			public 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=1
		HttpResult 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) {
		//创建一个buffer
		BufferedWriter bw = null;
		try {
			File dir=FileUtils.getCacheDir();
			//创建一个文件
			File file = new File(dir, getKey() + "_" + index); // /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); 
		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();
}

SubjectBean.java这里是subject的bean

package com.ldw.market.domain;

public class SubjectInfo {
	private String des;
	private String url;
	public String getDes() {
		return des;
	}
	public void setDes(String des) {
		this.des = des;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	@Override
	public String toString() {
		return "SubjectInfo [des=" + des + ", url=" + url + "]";
	}
	public SubjectInfo() {
		super();
	}
	public SubjectInfo(String des, String url) {
		super();
		this.des = des;
		this.url = url;
	}
	
}

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>>{

	@Override
	public List<SubjectInfo> parseJson(String json) {
		List<SubjectInfo> subjectInfos=new ArrayList<SubjectInfo>();
		try {
			//[]需要JSONArray
			JSONArray 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 block
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public 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");
				
				//构造函数,创建一个appInfo
				AppInfo appInfo = new AppInfo(id, name, packageName, iconUrl,
						stars, size, downloadUrl, des);
				//往集合中添加对象
				appInfos.add(appInfo);
			}
			return appInfos;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		
	}

	@Override
	public String getKey() {
		// TODO Auto-generated method stub
		return "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;
	@Override
	public View createSuccessView() {
		ListView listView=new ListView(UiUtils.getContext());
		listView.setAdapter(new SubjectAdapter());
		return listView;
	}
	
	private class SubjectAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return datas.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return datas.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public 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;
	}

	@Override
	protected 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>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值