本例子主要实现从网络中获取JPEG的图片,并且在listview中显示出来,主要涉及到用OKHTTP从网络中获取JSon数据,拿到URL之后利用Picasso来做图片显示,然后把所有的图片放到一个ListView中的例子,涉及到OKHTTP的基本用法,Picasso的基本用法和ListView的优化等内容。
首先,建立主页面的相关布局。
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tongseng.listviewbitmapoptimize.MainActivity">
<ListView
android:id="@+id/listview_bitmap"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
以及ListView中每一个item的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/itemImage"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher"
/>
<TextView
android:id="@+id/bitmap_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="start|center_vertical"
android:text="@string/app_name"
android:textSize="30sp"/>
</LinearLayout>
下面我们开始建立每个ListView必须的adapter
package com.tongseng.listviewbitmapoptimize;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Transformation;
import java.util.List;
import java.util.Map;
/**
* com.tongseng.listviewbitmapoptimize
*
* @author Administrator
* @date 2018/3/16
*/
public class ListViewAdapter extends BaseAdapter {
private Context mContext;
List<Map<String,String>> descs;
ViewHolder viewHolder = null;
public ListViewAdapter(Context context, List<Map<String,String>> datas) {
mContext = context;
this.descs = datas;
}
@Override
public int getCount() {
return descs.size();
}
@Override
public Object getItem(int position) {
return descs.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null){
view = View.inflate(mContext,R.layout.listview_bitmap_item,null);
viewHolder = new ViewHolder();
viewHolder.bitmap = view.findViewById(R.id.itemImage);
viewHolder.name = view.findViewById(R.id.bitmap_name);
view.setTag(viewHolder);
}else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.bitmap.setTag(descs.get(position).get("url"));
Picasso.get()
.load(descs.get(position).get("url"))
.tag(descs.get(position).get("url"))
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher_round)
.resize(300,300)
.centerCrop()
//.transform(transformation)
.into(viewHolder.bitmap);
viewHolder.name.setText(descs.get(position).get("name"));
return view;
}
Transformation transformation = new Transformation() {
@Override
public Bitmap transform(Bitmap source) {
/**
* if your ImageView has absolution width,use
* targetWidth = viewHolder.bitmap.getWidth()
* to get absolution width.
*/
//int targetWidth = viewHolder.bitmap.getWidth();
int targetWidth = 300;
if (source.getWidth() == 0){
return source;
}
if (source.getWidth() < targetWidth){
return source;
}else {
double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
int targetHeight = (int) (targetWidth * aspectRatio);
if (targetHeight != 0 && targetWidth != 0){
Bitmap result = Bitmap.createScaledBitmap(source,targetWidth,targetHeight,false);
if (result != source){
source.recycle();
}
return result;
}else {
return source;
}
}
}
@Override
public String key() {
return "transformation" + "desiredWidth";
}
};
public class ViewHolder{
private ImageView bitmap;
private TextView name;
}
}
其中主要是在getview中对ListView的优化,包括convertview和viewHolder,主要从布局和控件两方面对ListView进行优化.
而在主activity中,我们通过OKHTTP去获取到网页的json数据,从而parsing到URL数据,存到List数据中。有关OKHTTP我引用了张鸿洋大神对OKHTTP做了二次封装的第三方框架okhttputils。当然还包括对json进行解析的fastjson。
package com.tongseng.listviewbitmapoptimize;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Call;
/**
* @author Administrator
* @date
*/
public class MainActivity extends Activity {
/**
* url = http://gank.io/api/random/data/%E7%A6%8F%E5%88%A9/20
*/
private static final String url = "http://gank.io/api/random/data/%E7%A6%8F%E5%88%A9/20";
private ListView listView;
private ListViewAdapter listViewAdapter;
private List<Map<String,String>> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listview_bitmap);
data = new ArrayList<>();
}
@Override
protected void onResume() {
super.onResume();
OkHttpUtils.get()
.url(url)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
}
@Override
public void onResponse(String response, int id) {
parseResponse(response);
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
private void parseResponse(String response){
JSONObject result = JSONObject.parseObject(response);
JSONArray jsonArray = result.getJSONArray("results");
int length = jsonArray.size();
Map<String,String> map;
for (int i = 0;i < length;i++){
JSONObject tmp = jsonArray.getJSONObject(i);
map = new HashMap<>();
map.put("url",tmp.getString("url"));
map.put("name",tmp.getString("who"));
data.add(map);
}
listViewAdapter = new ListViewAdapter(this, data);
listView.setAdapter(listViewAdapter);
// listViewAdapter.notifyDataSetChanged();
}
@Override
protected void onDestroy() {
super.onDestroy();
listView.setAdapter(null);
}
}
当然,okhttputils需要在application中进行初始化:
package com.tongseng.listviewbitmapoptimize.Application;
import android.app.Application;
import android.content.res.Configuration;
import com.franmontiel.persistentcookiejar.ClearableCookieJar;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.https.HttpsUtils;
import com.zhy.http.okhttp.log.LoggerInterceptor;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import okhttp3.OkHttpClient;
/**
* com.tongseng.listviewbitmapoptimize.Application
*
* @author Administrator
* @date 2018/3/16
*/
public class ListViewApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ClearableCookieJar cookieJar1 = new PersistentCookieJar(new SetCookieCache(),
new SharedPrefsCookiePersistor(getApplicationContext()));
HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10000L, TimeUnit.MILLISECONDS)
.readTimeout(10000L, TimeUnit.MILLISECONDS)
.addInterceptor(new LoggerInterceptor("TAG"))
.cookieJar(cookieJar1)
.hostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
})
.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
.build();
OkHttpUtils.initClient(okHttpClient);
}
@Override
public void onTerminate() {
super.onTerminate();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
下面看下相关gradle的部分内容:
implementation 'com.zhy:okhttputils:2.6.2'
implementation 'com.alibaba:fastjson:1.2.46'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
其中涉及Picasso的基本用法可以参看如下文章系列: