效果图:
需要添加的依赖有:
HttpClient依赖
useLibrary 'org.apache.http.legacy'
limageloader远程依赖
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
Tablayout远程依赖
compile'com.android.support:design:26+'
pull-to-refresh远程依赖
compile 'com.github.userswlwork:pull-to-refresh:1.0.0'
需要添加的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
用到的字符串网址:
http://api.expoon.com/AppNews/getNewsList/type/1/p/1
MainActivity类:
public class MainActivity extends AppCompatActivity {
private PullToRefreshListView ptr;
List<Product.DataBean> list = new ArrayList<Product.DataBean>();
int page;
private ImageLoader instance;
static String urlString = "http://api.expoon.com/AppNews/getNewsList/type/1/p/";
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
//插入数据
String ss = (String) msg.obj;
dao.insertData(urlString + page, ss);
Gson gson = new GsonBuilder().create();
Product dataBeans = gson.fromJson(ss, Product.class);
List<Product.DataBean> data = dataBeans.getData();
list.addAll(data);
//刷新适配器
adapter.notifyDataSetChanged();
//UI同步
ptr.onRefreshComplete();
}
}
};
private MyAdapter adapter;
private SqlDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找控件
ptr = (PullToRefreshListView) findViewById(R.id.pul);
//设置模式
ptr.setMode(PullToRefreshBase.Mode.BOTH);
dao = new SqlDao(MainActivity.this);
//设置适配器
adapter = new MyAdapter();
ptr.setAdapter(adapter);
//获取数据
getDatas(0);
//ImageLoader实体类
instance = ImageLoader.getInstance();
//刷新监听
ptr.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> pullToRefreshBase) {
list.clear();
getDatas(0);
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> pullToRefreshBase) {
page++;
getDatas(page);
}
});
}
//数据....
private void getDatas(int page) {
//数据接口
final String umrl = urlString + page;
//判断网络
if (NetUtilType.getNetType(MainActivity.this) != -1) {
Toast.makeText(MainActivity.this, "有网啦!", Toast.LENGTH_SHORT).show();
//子线程
new Thread() {
@Override
public void run() {
super.run();
// 请求数据
String httpUrl = NetUtil.getHttpClientJson(umrl);
Message msg = new Message();
msg.what = 0;
msg.obj = httpUrl;
handler.sendMessage(msg);
}
}.start();
// new MyAsyncTask().execute(umrl);
} else {
Toast.makeText(MainActivity.this, "无网络,请重试!", Toast.LENGTH_SHORT).show();
//查询
String s = dao.queryData(umrl);
if (!s.isEmpty()) {
Gson gson = new GsonBuilder().create();
Product dataBeans = gson.fromJson(s, Product.class);
List<Product.DataBean> data = dataBeans.getData();
list.addAll(data);
adapter.notifyDataSetChanged();
ptr.onRefreshComplete();
}
}
}
//适配器...
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
view = View.inflate(MainActivity.this, R.layout.item, null);
holder = new ViewHolder();
holder.text = view.findViewById(R.id.text);
holder.image = view.findViewById(R.id.image);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
//赋值
holder.text.setText(list.get(i).getNews_summary());
DisplayImageOptions options = Imageloager.getDisplayImageOptions();
instance.displayImage(list.get(i).getPic_url(), holder.image, options);
return view;
}
}
class ViewHolder {
private TextView text;
private ImageView image;
}
}
ImageLoager类:
public class Imageloager {
public static DisplayImageOptions getDisplayImageOptions(){
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.mipmap.ic_launcher) //设置图片在下载期间显示的图片
.showImageForEmptyUri(R.mipmap.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.mipmap.ic_launcher) //设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true)//设置下载的图片是否缓存在内存中
.cacheOnDisk(true)//是否缓存到sd卡
.considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示
.bitmapConfig(Bitmap.Config.ARGB_8888)//设置图片的解码类型//
.displayer(new SimpleBitmapDisplayer()) //配置圆角图片
.displayer(new RoundedBitmapDisplayer(20))//是否设置为圆角,弧度为多少
// .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间
.build();//构建完成
return options;
}
}
MyApp类:
public class MyApp extends Application {
//配置imageloader缓存目录缓存到img目录下;自定义缓存目录
File cacheFile=new File(Environment.getExternalStorageDirectory()+"/img");
@Override
public void onCreate() {
super.onCreate();
//初始化组件,链式开发思想,整个框架的参数初始化配置
//imageLoader的全局框架配置
ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this)
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions 内存缓存文件的最大长宽
.diskCacheExtraOptions(480, 800, null) // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现
.memoryCacheSize(2 * 1024 * 1024) // 内存缓存的最大值
.memoryCacheSizePercentage(13) // default
.diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值
.diskCacheFileCount(100) // 可以缓存的文件数量
.diskCache(new UnlimitedDiskCache(cacheFile))//自定义缓存目录*******
// default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.writeDebugLogs() // 打印debug log
.build();
//初始化
ImageLoader.getInstance().init(configuration);
}
}
SqlDao类:
public class SqlDao {
private final SQLiteDatabase rd;
public SqlDao(Context context) {
Sqlite myHelper = new Sqlite(context);
rd = myHelper.getReadableDatabase();
}
//先删除再添加
public void insertData(String url, String json) {
rd.delete("user", "url=?", new String[]{url});
ContentValues values = new ContentValues();
values.put("url", url);
values.put("json", json);
rd.insert("user", null, values);
}
//查询
public String queryData(String url) {
String json = "";
Cursor cursor = rd.query("user", null, "url=?", new String[]{url}, null, null, null);
while (cursor.moveToNext()) {
json = cursor.getString(cursor.getColumnIndex("json"));
}
return json;
}
}
Sqlite类:
public class Sqlite extends SQLiteOpenHelper {
public Sqlite(Context context) {
super(context, "User.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table user(id integer primary key autoincrement,url text not null,json text not null)");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
NetUtil类:
public class NetUtil {
//使用HttpClient网络请求json
public static String getHttpClientJson(String urlString){
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(urlString);
try {
HttpResponse response = defaultHttpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode==200){
HttpEntity entity = response.getEntity();
String string = EntityUtils.toString(entity);
// Log.e("11-json",string);
return string;
}else {
Log.e("11",statusCode+"");
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
//网络请求json
public static String getNetJson(String urlString){
try {
URL url = new URL(urlString);//专门处理网络请求的一个类,把接口包装成url对象
HttpURLConnection urlConnection= (HttpURLConnection) url.openConnection();
// urlConnection.setConnectTimeout(8000);
int responseCode = urlConnection.getResponseCode();//获取请求网络的状态码
if (responseCode==200){
InputStream inputStream = urlConnection.getInputStream();//得到服务器返回的数据流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer stringBuffer = new StringBuffer();//可拼接字符串
String len="";
while ((len=reader.readLine())!=null) {
stringBuffer.append(len);
}
String string = stringBuffer.toString();
// Log.e("11--result", string);
return string;
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.e("11", e.toString());
} catch (IOException e) {
e.printStackTrace();
Log.e("11", e.toString());
}
return "";
}
//网络请求图片
public static Bitmap getNetBitmap(String urlBitmap) {
try {
URL url = new URL(urlBitmap);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// urlConnection.setConnectTimeout(8000);
int responseCode = urlConnection.getResponseCode();
if (responseCode==200){
InputStream inputStream = urlConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}else {
//do nothing
Log.e("11","请求图片状态码"+responseCode);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
NetUtilType类:
public class NetUtilType {
public static int getNetType(Context context){
int state=-1;//无网络
ConnectivityManager connectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
if (activeNetworkInfo==null){
return state;
}
int type = activeNetworkInfo.getType();
if (type==connectivityManager.TYPE_WIFI){
state=1;//WiFi网
}else if (type==connectivityManager.TYPE_MOBILE){
state=0;//蜂窝网络
}
return state;
}
}
用到的XML布局:
<com.handmark.pulltorefresh.library.PullToRefreshListView android:id="@+id/pul" android:layout_width="match_parent" android:layout_height="match_parent"> </com.handmark.pulltorefresh.library.PullToRefreshListView>
<ImageView android:id="@+id/image" android:layout_width="92dp" android:layout_height="105dp" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/text" android:layout_width="298dp" android:layout_height="105dp" android:text="123456789" />