使用到
- Okhttp网络请求
- Glide图片加载库
- Json解析之Gson
OKHttp网络请求的封装:我用的是Okhttputils按道理是应该封装的,但是okhttputils已经满足大部分项目需求所以才没有封装 http://www.jianshu.com/p/96f55f19c1e4
Glide使用简单并且功能十分强大
优点:
1,缓存图片和imageView尺寸图片相同 Picasso缓存的是全尺寸图片
2,加载速度快
3,加载GIF图片 Glide加载GIF图并不需要编写什么额外的代码,Glide内部会自动判断图片格式
缺点:
1,Glide加载的图片质量要差于Picasso ,因为Glide默认的Bitmap格式是RGB_565 , Picasso默认格式是ARGB_8888,
使用:
1,导入依赖 compile 'com.github.bumptech.glide:glide:3.8.0';
Glide.with(this)
.load(url)
.asBitmap()//指定图片的格式 只允许加载静态图片
.placeholder(R.drawable.oxv)//加载图片占位符
.error(R.drawable.error)//加载图片失败
.diskCacheStrategy(DiskCacheStrategy.NONE)//禁用掉Glide的缓存功能。
.override(100, 100)//指定图片大小 而不会管你的ImageView的大小是多少了。
.into(imageView); //让图片显示在哪个ImageView上
with()方法可以接收Context、Activity或者Fragment类型的参数。也就是说我们选择的范围非常广,不管是在Activity还是Fragment中调用with()方法,都可以直接传this。那如果调用的地方既不在Activity中也不在Fragment中呢?也没关系,我们可以获取当前应用程序的ApplicationContext,传入到with()方法当中。注意with()方法中传入的实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。
load()方法,这个方法用于指定待加载的图片资源。
Glide支持加载各种各样的图片资源,包括网络图片、本地图片、应用资源、二进制流、Uri对象等等。因此load()方法也有很多个方法重载,除了我们刚才使用的加载一个字符串网址之外,你还可以这样使用load()方法:
// 加载本地图片
File file = new File(getExternalCacheDir() + "/image.jpg");
Glide.with(this).load(file).into(imageView);
// 加载应用资源
int resource = R.drawable.image;
Glide.with(this).load(resource).into(imageView);
// 加载二进制流
byte[] image = getImageBytes();
Glide.with(this).load(image).into(imageView);
// 加载Uri对象
Uri imageUri = getImageUri();
Glide.with(this).load(imageUri).into(imageView);
可以点击这里Android图片加载框架最全解析(一),Glide的基本用法学习
如果你想深入的话可以看郭霖大神的 Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程
Json解析 :
使用google提供的gson解析 在Android下载GsonFormat插件 ;
1,导入Json依赖;
2,需要一个bean Text类 ,然后鼠标放在Test类后面 Alt+Ins 键 选择GsonFormat 把你需要的数据放进去就ok了;
3,实现序列化 Parcelable;
下面看代码怎么实现 拿新闻页面为例吧 布局代码就不给出了:
首先看Bean吧:
public class News implements Parcelable {
private String uniquekey;
private String title;
private String date;
private String category;
private String author_name;
private String url;
private String thumbnail_pic_s;
private String thumbnail_pic_s02;
private String thumbnail_pic_s03;
public News() {
}
public String getUniquekey() {
return uniquekey;
}
public void setUniquekey(String uniquekey) {
this.uniquekey = uniquekey;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getAuthor_name() {
return author_name;
}
public void setAuthor_name(String author_name) {
this.author_name = author_name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getThumbnail_pic_s() {
return thumbnail_pic_s;
}
public void setThumbnail_pic_s(String thumbnail_pic_s) {
this.thumbnail_pic_s = thumbnail_pic_s;
}
public String getThumbnail_pic_s02() {
return thumbnail_pic_s02;
}
public void setThumbnail_pic_s02(String thumbnail_pic_s02) {
this.thumbnail_pic_s02 = thumbnail_pic_s02;
}
public String getThumbnail_pic_s03() {
return thumbnail_pic_s03;
}
public void setThumbnail_pic_s03(String thumbnail_pic_s03) {
this.thumbnail_pic_s03 = thumbnail_pic_s03;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.uniquekey);
dest.writeString(this.title);
dest.writeString(this.date);
dest.writeString(this.category);
dest.writeString(this.author_name);
dest.writeString(this.url);
dest.writeString(this.thumbnail_pic_s);
dest.writeString(this.thumbnail_pic_s02);
dest.writeString(this.thumbnail_pic_s03);
}
protected News(Parcel in) {
this.uniquekey = in.readString();
this.title = in.readString();
this.date = in.readString();
this.category = in.readString();
this.author_name = in.readString();
this.url = in.readString();
this.thumbnail_pic_s = in.readString();
this.thumbnail_pic_s02 = in.readString();
this.thumbnail_pic_s03 = in.readString();
}
public static final Creator<News> CREATOR = new Creator<News>() {
@Override
public News createFromParcel(Parcel source) {
return new News(source);
}
@Override
public News[] newArray(int size) {
return new News[size];
}
};
}
NewsAdapter:
public class NewsAdapter extends BaseAdapter {
private viewHolder holder;
private List<News> data;
public NewsAdapter(List<News> data) {
this.data = data;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
if (convertView == null){
convertView= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_news,null);
holder = new viewHolder(convertView);
convertView.setTag(holder);
}else {
holder = (viewHolder) convertView.getTag();
}
Glide.with(parent.getContext())
.load(data.get(position).getThumbnail_pic_s())
.placeholder(R.drawable.load)
.error(R.drawable.load_failure)
.into(holder.img_news);
holder.tv_title.setText(data.get(position).getTitle());
convertView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
new AlertDialog.Builder(parent.getContext())
.setTitle("收藏")
.setMessage("是否收藏?")
.setPositiveButton("收藏", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Account account = BmobUser.getCurrentUser(BaseApplication.getInstance(),Account.class);
if(account != null) {
Collection collectionBean = new Collection();
collectionBean.setPicUrl(data.get(position).getThumbnail_pic_s());
collectionBean.setuId(account.getObjectId());
collectionBean.setUrl(data.get(position).getUrl());
collectionBean.setTitle(data.get(position).getTitle());
collectionBean.setType(Constants.COLLECTION_TYPE_NEWS);
collectionBean.save(parent.getContext(), new SaveListener() {
@Override
public void onSuccess() {
Toast.makeText(parent.getContext(), "收藏成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int i, String s) {
Toast.makeText(parent.getContext(), "收藏失败", Toast.LENGTH_SHORT).show();
}
});
}
}
})
.setNegativeButton("取消",null)
.create()
.show();
return false;
}
});
return convertView;
}
class viewHolder{
ImageView img_news;
TextView tv_title;
public viewHolder(View convertView) {
img_news = (ImageView) convertView.findViewById(R.id.img_news);
tv_title = (TextView) convertView.findViewById(R.id.tv_title);
}
}
//下拉刷新
public void setNewData(List<News> newData) {
data.clear();
data.addAll(newData);
notifyDataSetChanged();
}
//加载更多
public void setMoreData(List<News> newData) {
data.addAll(newData);
notifyDataSetChanged();
}
}
这里也用到了Bmob收藏,用的是AlertDialog弹出框来确定你是否收藏
NewsFragment:
public class NewsFragment extends Fragment {
public static final int TYPE_REFRESH = 0x01;
public static final int TYPE_LOADMORE = 0x02;
@BindView(R.id.lv_news)
PullToRefreshListView lvNews;
private List<News> data = new ArrayList<>();
private NewsAdapter newsAdapter;
Unbinder unbinder;
private View view;
private static int page = 1;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_news, container, false);
unbinder = ButterKnife.bind(this, view);
initView();
return view;
}
private void initView() {
//设置列表刷新加载
// lvNews.setMode(PullToRefreshBase.Mode.BOTH);
//初始化适配器
newsAdapter = new NewsAdapter(data);
//绑定适配器
lvNews.setAdapter(newsAdapter);
//添加监听事件
lvNews.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getActivity(), NewsDataActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("news", data.get(position - 1));
intent.putExtras(bundle);
NewsFragment.this.startActivity(intent);
}
});
lvNews.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
//下拉刷新,先清空数据,在加载新数据,更新UI
page = 1;
getAsyncData(1, TYPE_REFRESH);
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
//加载更多:加载下一页数据,请求page++,新数据添加在后面
getAsyncData(page++,TYPE_LOADMORE);
}
});
}
@Override
public void onResume() {
super.onResume();
initData();
}
private void initData() {
getAsyncData(1, TYPE_REFRESH);
}
//获取异步请求的数值
private void getAsyncData(int page, final int type) {
OkHttpUtils
.get()
.url(ServerConfig.JUHE_NEWS_URL)
.addParams("key", Constant.API_NEWS_KEY)
.addParams("type", "top")
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
lvNews.onRefreshComplete();
Toast.makeText(getActivity(), "请求数据失败", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(String response, int id) {
//停止刷新
lvNews.onRefreshComplete();
//解析数据 把返回的结果JSON数据字符串转为json对象
JSONObject jsonObject = JSONObject.parseObject(response);
JSONArray jsonArray = jsonObject.getJSONObject("result").getJSONArray("data");
switch (type) {
case TYPE_REFRESH:
newsAdapter.setNewData(JSONArray.parseArray(jsonArray.toJSONString(), News.class));
break;
case TYPE_LOADMORE:
newsAdapter.setMoreData(JSONArray.parseArray(jsonObject.toJSONString(), News.class));
break;
}
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
- url获取到新闻数据地址
- addParams获取新闻Key值
- 初始化OkHttpClient以及创建一个Request,然后再调用OkHttpClinet的newCall方法,创建出一个RealCall对象。对于同步请求,是调用RealCall的execute方法;而异步请求,则是调用RealCall的enqueue方法实现。