//ShopAdapter
public class ShopAdapter extends BaseAdapter {
private Context context;
private List<Shop.DataBean> dataBeanList;
public ShopAdapter(Context context, List<Shop.DataBean> dataBeanList) {
this.context = context;
this.dataBeanList = dataBeanList;
}
@Override
public int getCount() {
return dataBeanList == null ? 0 : dataBeanList.size();
}
@Override
public Shop.DataBean getItem(int position) {
return dataBeanList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 1, 使用ViewHolder减少FindViewById的次数;2. ConvertView缓存对象
ShopViewHolder holder = null;
if (convertView == null) {
holder = new ShopViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.shop_list_item, null, false);
holder.ivIcon = convertView.findViewById(R.id.iv_image);
holder.tvShopName = convertView.findViewById(R.id.tv_shop_name);
convertView.setTag(holder);
} else {
holder = (ShopViewHolder) convertView.getTag();
}
ImageLoader.getInstance().displayImage(dataBeanList.get(position).getPic_url(), holder.ivIcon);
holder.tvShopName.setText(dataBeanList.get(position).getName());
return convertView;
}
class ShopViewHolder {
ImageView ivIcon;
TextView tvShopName;
}
}
//MyApplication
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
initImageLoader();
}
/**
* 初始化ImageLoader
*/
private void initImageLoader() {
// DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
// See the sample project how to use ImageLoader correctly.
File cacheDir = StorageUtils.getCacheDirectory(getApplicationContext());
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions
.diskCacheExtraOptions(480, 800, null)
.threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 2) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))
.memoryCacheSize(2 * 1024 * 1024)
.memoryCacheSizePercentage(13) // default
.diskCache(new UnlimitedDiskCache(cacheDir)) // default
.diskCacheSize(50 * 1024 * 1024)
.diskCacheFileCount(100)
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.defaultDisplayImageOptions(createDisplayOption()) // default
.writeDebugLogs()
.build();
ImageLoader.getInstance().init(config);
}
private DisplayImageOptions createDisplayOption() {
// DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
// See the sample project how to use ImageLoader correctly.
DisplayImageOptions options = new DisplayImageOptions.Builder()
/*.showImageOnLoading(R.drawable.ic_stub) // resource or drawable
.showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable
.showImageOnFail(R.drawable.ic_error) // resource or drawable*/
.resetViewBeforeLoading(false) // default
.delayBeforeLoading(1000)
.cacheInMemory(false) // default
.cacheOnDisk(false) // default
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
.bitmapConfig(Bitmap.Config.RGB_565) // default
.displayer(new RoundedBitmapDisplayer(20)) // default
.build();
return options;
}
}
//到包
public class ShopDao {
private ShopOpenHelper helper;
private SQLiteDatabase db;
public ShopDao(Context context) {
helper = new ShopOpenHelper(context);
//this.helper = helper;
db = helper.getWritableDatabase();
}
/**
* 执行插入
*
* @param bean
*/
public void insert(DbShopBean bean) {
ContentValues values = new ContentValues();
values.put("url", bean.url);
values.put("json", bean.json);
//db.insert("shop", null, values);
db.replace("shop", null, values);
}
/**
* 查询
*
* @param url
* @return
*/
public DbShopBean query(String url) {
DbShopBean bean = null;
Cursor cursor = db.rawQuery("select * from shop where url = ?", new String[]{url});
if (cursor.moveToNext()) {
bean = new DbShopBean();
// 读取字段
bean._id = cursor.getInt(cursor.getColumnIndex("_id"));
bean.url = cursor.getString(cursor.getColumnIndex("url"));
bean.json = cursor.getString(cursor.getColumnIndex("json"));
}
return bean;
}
}
//ShopOpenHelper
public class ShopOpenHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "shop.db";
private static final int DB_VERSION = 1;
public ShopOpenHelper(@Nullable Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table shop(_id Integer primary key autoincrement, url varchar(200), json TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
//DbShopBean
public class DbShopBean {
public Integer _id;
public String url;
public String json;
public DbShopBean() {
}
public DbShopBean(String url, String json) {
this.url = url;
this.json = json;
}
@Override
public String toString() {
return "DbShopBean{" +
"_id=" + _id +
", url='" + url + '\'' +
", json='" + json + '\'' +
'}';
}
}
//httputils
public class HttpUtils {
private static HttpUtils instance = new HttpUtils();
private HttpUtils() {
}
public static HttpUtils getInstance() {
if (instance == null) {
instance = new HttpUtils();
}
return instance;
}
}
//HttpUtils v2
public class HttpUtils_v2 {
private static final HttpUtils_v2 ourInstance = new HttpUtils_v2();
public static HttpUtils_v2 getInstance() {
return ourInstance;
}
private HttpUtils_v2() {
}
/**
* 从服务加载数据
*
* @param url 请求地址
*/
public void loadDataFromServer(String url, NetCallBack callBack) {
// 创建异步任务获取数据(1. 使用Thread 2. 使用AsyncTask)
// 开启异步任务去请求数据
new LodaDataTask(callBack).execute(url);
}
/**
* 异步请求网络任务类
*/
class LodaDataTask extends AsyncTask<String, Void, String> {
private NetCallBack netCallBack;
public LodaDataTask() {
}
public LodaDataTask(NetCallBack netCallBack) {
this.netCallBack = netCallBack;
}
@Override
protected String doInBackground(String... strings) {
// 请求网络
// 1. 创建Url对象
HttpURLConnection connection = null;
try {
URL url = new URL(strings[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// 获取流转换成字符串
InputStream inputStream = connection.getInputStream();
return inputStream2String(inputStream);
}
} catch (Exception e) {
netCallBack.onError(e.getMessage());
} finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}
@Override
protected void onPostExecute(String s) {
if (TextUtils.isEmpty(s)) {
netCallBack.onError("没有请求到数据");
} else {
netCallBack.onSuccess(s);
}
}
}
/**
* 流转换成字符串
*
* @param inputStream
* @return
* @throws IOException
*/
@NonNull
private String inputStream2String(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int len = -1;
byte[] b = new byte[1024];
while ((len = inputStream.read(b)) != -1) {
outputStream.write(b, 0, len);
}
return new String(outputStream.toByteArray());
}
/**
* 定义网络处理接口
*/
public interface NetCallBack {
void onSuccess(String result);
void onError(String errorMsg);
}
}
//mainactivity
public class MainActivity extends AppCompatActivity implements HttpUtils_v2.NetCallBack {
private static final String TAG = MainActivity.class.getSimpleName();
private String url = "http://39.108.3.12:3000/v1/restaurants?offset=0&limit=5&lng=116.29845&lat=39.95933";
private PullToRefreshListView pullToRefreshListView;
private ShopAdapter adapter;
private List<Shop.DataBean> dataBeans;
private ShopDao shopDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pullToRefreshListView = findViewById(R.id.main_refresh_list_view);
pullToRefreshListView.setMode(PullToRefreshBase.Mode.BOTH);
pullToRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
}
});
dataBeans = new ArrayList<>();
adapter = new ShopAdapter(this, dataBeans);
pullToRefreshListView.setAdapter(adapter);
// 先去读取数据库,判读本地是否存在 存在直接展示 不存在 去网络读取
shopDao = new ShopDao(this);
DbShopBean shopBean = shopDao.query(url);
if (shopBean != null) {
// 解析数据
Shop shop = parseJson(shopBean.json);
dataBeans.addAll(shop.getData());
adapter.notifyDataSetChanged();
} else {
HttpUtils_v2.getInstance().loadDataFromServer(url, this);
}
}
@Override
public void onSuccess(String result) {
Log.i(TAG, "result:" + result);
// 插入数据库
shopDao.insert(new DbShopBean(url, result));
// 在列表中展示数据
Shop shop = parseJson(result);
dataBeans.addAll(shop.getData());
adapter.notifyDataSetChanged();
Log.i(TAG, "商店数量:" + shop.getData().size());
}
private Shop parseJson(String result) {
Gson gson = new Gson();
return gson.fromJson(result, Shop.class);
}
@Override
public void onError(String errorMsg) {
Log.i(TAG, "error:" + errorMsg);
}
}
///main.xml
<com.handmark.pulltorefresh.library.PullToRefreshListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_refresh_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
//展示xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<ImageView
android:id="@+id/iv_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_shop_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iv_image"
android:padding="10dp"
android:text="商店名称" />
</RelativeLayout>