本工程实现了下拉刷新以及当没有网络时从本地读取和对MD5加密的应用。
用到的接口:http://www.93.gov.cn/93app/data.do?channelId=0&startNum=0
XLIstView是谷歌提供的下拉刷新控件
原码地址:https://github.com/Maxwin-z/XListView-Android
由于谷歌已经不再维护所以用起来比较麻烦,在使用之前:
- 可以新建一个Moudle或者导入Moudle
- 把原码中的XListview,XListViewFooter,XListViewHeader三个java文件放到下面
- 把三个文件所对应的布局文件也放到下面
- 然后在ProjectStructure下面然APP关联一下它的Moudle
下面就可以使用并进行具体操作了
用到的权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
布局:me.maxwin.view.XListView当引用成功时就可以加载该布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.mylistview.MainActivity">
<me.maxwin.view.XListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
网络读取文件的代码:其实这里和普通的网络并无不同但是由于要实现本地缓存所以使用了Md5加密
MD5的原因:由于每次有网刷新时我们会得到跟多的数据,并且根据接口的来命名(接口是不符合命名规则的)所以我们用MD5加密来实现
package com.example.administrator.mylistview;
import android.content.Context;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
/**
* 作 者:
* 创作时间:2017/6/20
* 项目名称:MYListView
*/
public class Utils {
public static String getUrlConnect(Context context, String urlPath){
try {
//创建URL
URL url = new URL(urlPath);
//由URL的openConnection方法得到一个HttpURLConnection(需要强转)
HttpURLConnection httpURLConnection =
(HttpURLConnection) url.openConnection();
//设置连接
httpURLConnection.connect();
//判断响应码 200 代表成功
if(httpURLConnection.getResponseCode()==200){
//由HttpURLConnection拿到输入流
InputStream in=httpURLConnection.getInputStream();
//创建要存入本地的文件
File file=new File(context.getExternalCacheDir(),getMD5(urlPath));
FileOutputStream fos=new FileOutputStream(file);
StringBuffer sb=new StringBuffer();
//根据输入流做一些IO操作
byte [] buff =new byte[1024];
int len=-1;
while((len=in.read(buff))!=-1){
//在从网络读取Json的同时我们保存到本地
fos.write(buff,0,len);
sb.append(new String(buff,0,len,"utf-8"));
}
fos.flush();
fos.close();
in.close();
httpURLConnection.disconnect();
return sb.toString();
}else{
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 使用MD5加密
public static String getMD5(String str){
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes());
// digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
return new BigInteger(1, md.digest()).toString(16);
} catch (Exception e) {
return str;
}
}
}
在MainActivity里面
package com.example.administrator.mylistview;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import me.maxwin.view.XListView;
//下拉刷新
public class MainActivity extends AppCompatActivity implements XListView.IXListViewListener {
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Data data = new Gson().fromJson(msg.obj.toString(), Data.class);
list.addAll(data.getData());
adapter.notifyDataSetChanged();
stopXList();
}
};
private List<Data.DataBean> list;
private XListView listView;
private BaseAda adapter;
private int startNum=0;
private final String url="http://www.93.gov.cn/93app/data.do?channelId=0&startNum=";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView= (XListView) findViewById(R.id.list);
// 设置可以下拉刷新
listView.setPullLoadEnable(true);
// 设置可以加载更多
listView.setXListViewListener(this);
list=new ArrayList<>();
adapter = new BaseAda(list, MainActivity.this);
listView.setAdapter(adapter);
loadDate();
}
private void loadDate() {
// 实现简单的数据展示
//进行逻辑判断是从本地读取还是网络请求可以根据之前创建的文件夹是否存在
final String path = url+startNum;
File file = new File(getExternalCacheDir(), Utils.getMD5(path));
if (file.exists()){
Toast.makeText(MainActivity.this, "从本地获取", Toast.LENGTH_SHORT).show();
try {
//用BufferedReader从本地读取
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
StringBuffer sb=new StringBuffer();
String line="";
while((line=br.readLine())!=null){
sb.append(line);
}
br.close();
//这里是主线程发送主线程给handler里面的gson解析
Message msg=Message.obtain();
msg.what=1;
msg.obj=sb.toString();
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
}else {
//网络请求
new Thread(){
@Override
public void run() {
super.run();
String con = Utils.getUrlConnect(MainActivity.this,path);
Message msg=Message.obtain();
msg.what=1;
msg.obj=con;
handler.sendMessage(msg);
}
}.start();
}
}
// 下拉刷新后的结果
private void stopXList(){
listView.stopRefresh();
listView.stopLoadMore();
listView.setRefreshTime("刚刚");
}
//这个是下拉刷新,当你刷新是默认回到加载的最 初始
@Override
public void onRefresh() {
// 如果是刷新的话清空显示默认的第0页
startNum=0;
list.clear();
loadDate();
}
//加载更多每次点击刷新时加载更多
@Override
public void onLoadMore() {
startNum++;
Log.e("TAG", "onLoadMore: "+list.size() );
loadDate();
}
}
补充一点当使用XListView是他们的布局对用的位置要增加头上布局和底部布局所以此时的点击条目监听应该这样写:
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position>0&&position<mlist.size()){
Toast.makeText(MainActivity.this,"位置不对"+mlist.get(position-1).getTitle(),Toast.LENGTH_LONG).show();
}
}
});