jetpack学习(四)——LiveData&ViewModel&DataBinding综合使用示例(转)
运行效果1.接口地址
https://cn.bing.com/HPImageArchive.aspx?format=js&idx=1&n=1
{
"images": [
{
"startdate": "20200112",
"fullstartdate": "202001121600",
"enddate": "20200113",
"url": "/th?id=OHR.SeventeenSolstice_ZH-CN4901756341_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp",
"urlbase": "/th?id=OHR.SeventeenSolstice_ZH-CN4901756341",
"copyright": "北京颐和园昆明湖上的十七孔桥,中国 (© Jia Wang/Getty Images)",
"copyrightlink": "https://www.bing.com/search?q=%E5%8D%81%E4%B8%83%E5%AD%94%E6%A1%A5&form=hpcapt&mkt=zh-cn",
"title": "",
"quiz": "/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20200112_SeventeenSolstice%22&FORM=HPQUIZ",
"wp": true,
"hsh": "1ce556e2436538e9de7b6ff4404a8191",
"drk": 1,
"top": 1,
"bot": 1,
"hs": []
}
],
"tooltips": {
"loading": "正在加载...",
"previous": "上一个图像",
"next": "下一个图像",
"walle": "此图片不能下载用作壁纸。",
"walls": "下载今日美图。仅限用作桌面壁纸。"
}
}
接口返回一个Json对象,其中images为一个图片信息列表。图片信息中,我们关心的是"url",和"copyright"这两个属性。其中url返回的字符串在首部拼接上"https://www.bing.com/"就是图片的url,copyright是图片的描述信息。
2.实体类,推荐使用GsonFormat插件
public class BingImgBean {
/**
* images : [{"startdate":"20200112","fullstartdate":"202001121600","enddate":"20200113","url":"/th?id=OHR.SeventeenSolstice_ZH-CN4901756341_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp","urlbase":"/th?id=OHR.SeventeenSolstice_ZH-CN4901756341","copyright":"北京颐和园昆明湖上的十七孔桥,中国 (© Jia Wang/Getty Images)","copyrightlink":"https://www.bing.com/search?q=%E5%8D%81%E4%B8%83%E5%AD%94%E6%A1%A5&form=hpcapt&mkt=zh-cn","title":"","quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20200112_SeventeenSolstice%22&FORM=HPQUIZ","wp":true,"hsh":"1ce556e2436538e9de7b6ff4404a8191","drk":1,"top":1,"bot":1,"hs":[]}]
* tooltips : {"loading":"正在加载...","previous":"上一个图像","next":"下一个图像","walle":"此图片不能下载用作壁纸。","walls":"下载今日美图。仅限用作桌面壁纸。"}
*/
private TooltipsBean tooltips;
private List<ImagesBean> images;
public TooltipsBean getTooltips() {
return tooltips;
}
public void setTooltips(TooltipsBean tooltips) {
this.tooltips = tooltips;
}
public List<ImagesBean> getImages() {
return images;
}
public void setImages(List<ImagesBean> images) {
this.images = images;
}
public static class TooltipsBean {
/**
* loading : 正在加载...
* previous : 上一个图像
* next : 下一个图像
* walle : 此图片不能下载用作壁纸。
* walls : 下载今日美图。仅限用作桌面壁纸。
*/
private String loading;
private String previous;
private String next;
private String walle;
private String walls;
public String getLoading() {
return loading;
}
public void setLoading(String loading) {
this.loading = loading;
}
public String getPrevious() {
return previous;
}
public void setPrevious(String previous) {
this.previous = previous;
}
public String getNext() {
return next;
}
public void setNext(String next) {
this.next = next;
}
public String getWalle() {
return walle;
}
public void setWalle(String walle) {
this.walle = walle;
}
public String getWalls() {
return walls;
}
public void setWalls(String walls) {
this.walls = walls;
}
}
public static class ImagesBean {
/**
* startdate : 20200112
* fullstartdate : 202001121600
* enddate : 20200113
* url : /th?id=OHR.SeventeenSolstice_ZH-CN4901756341_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp
* urlbase : /th?id=OHR.SeventeenSolstice_ZH-CN4901756341
* copyright : 北京颐和园昆明湖上的十七孔桥,中国 (© Jia Wang/Getty Images)
* copyrightlink : https://www.bing.com/search?q=%E5%8D%81%E4%B8%83%E5%AD%94%E6%A1%A5&form=hpcapt&mkt=zh-cn
* title :
* quiz : /search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20200112_SeventeenSolstice%22&FORM=HPQUIZ
* wp : true
* hsh : 1ce556e2436538e9de7b6ff4404a8191
* drk : 1
* top : 1
* bot : 1
* hs : []
*/
private String startdate;
private String fullstartdate;
private String enddate;
private String url;
private String urlbase;
private String copyright;
private String copyrightlink;
private String title;
private String quiz;
private boolean wp;
private String hsh;
private int drk;
private int top;
private int bot;
private List<?> hs;
public String getStartdate() {
return startdate;
}
public void setStartdate(String startdate) {
this.startdate = startdate;
}
public String getFullstartdate() {
return fullstartdate;
}
public void setFullstartdate(String fullstartdate) {
this.fullstartdate = fullstartdate;
}
public String getEnddate() {
return enddate;
}
public void setEnddate(String enddate) {
this.enddate = enddate;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlbase() {
return urlbase;
}
public void setUrlbase(String urlbase) {
this.urlbase = urlbase;
}
public String getCopyright() {
return copyright;
}
public void setCopyright(String copyright) {
this.copyright = copyright;
}
public String getCopyrightlink() {
return copyrightlink;
}
public void setCopyrightlink(String copyrightlink) {
this.copyrightlink = copyrightlink;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getQuiz() {
return quiz;
}
public void setQuiz(String quiz) {
this.quiz = quiz;
}
public boolean isWp() {
return wp;
}
public void setWp(boolean wp) {
this.wp = wp;
}
public String getHsh() {
return hsh;
}
public void setHsh(String hsh) {
this.hsh = hsh;
}
public int getDrk() {
return drk;
}
public void setDrk(int drk) {
this.drk = drk;
}
public int getTop() {
return top;
}
public void setTop(int top) {
this.top = top;
}
public int getBot() {
return bot;
}
public void setBot(int bot) {
this.bot = bot;
}
public List<?> getHs() {
return hs;
}
public void setHs(List<?> hs) {
this.hs = hs;
}
}
}
3.包装类,此类有多种包装方法,我这里直接包装返回的str数据,转载原文包装为如下,我ide一直报错,无法创建T类型
public class Data {
private T mData;
private String mErrorMsg;
...
}
BingDataBean .java
public class BingDataBean {
private String result;
private String error;
public BingDataBean() {
}
public BingDataBean(String data, String error) {
this.result = data;
this.error = error;
}
public String getData() {
return result;
}
public void setData(String data) {
this.result = data;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
4.ViewModel类,此处我使用的是EasyHttp为网络请求框架
public class BingImgViewModel extends ViewModel {
public MutableLiveData<BingDataBean> getImg() {
return liveData;
}
private MutableLiveData<BingDataBean> liveData;
int index;
public BingImgViewModel() {
index=0;
liveData=new MutableLiveData<>();
}
String str;
public void loadImg(){
ToastUtils.showShort("我到这里了");
str="https://cn.bing.com/HPImageArchive.aspx?format=js&idx="+index+"&n=1";
EasyHttp.get(str)
.accessToken(true)
.timeStamp(true)
.execute(new SimpleCallBack<String>() {
@Override
public void onError(ApiException e) {
ToastUtils.showShort(e.getMessage());
liveData.setValue(new BingDataBean(null,e.getMessage()));
}
@Override
public void onSuccess(String result) {
Logger.json(result);
ToastUtils.showShort(result);
liveData.setValue(new BingDataBean(result,null));
}
});
}
public void nextImage(){
index++;
str="https://cn.bing.com/HPImageArchive.aspx?format=js&idx="+index+"&n=1";
EasyHttp.get(str)
.accessToken(true)
.timeStamp(true)
.execute(new SimpleCallBack<String>() {
@Override
public void onError(ApiException e) {
liveData.setValue(new BingDataBean(null,e.getMessage()));
index--;
}
@Override
public void onSuccess(String result) {
liveData.setValue(new BingDataBean(result,null));
}
});
}
public void previousImage() {
index--;
if(index<=0){
liveData.setValue(new BingDataBean(null,"已经是第一张了"));
return;
}
str="https://cn.bing.com/HPImageArchive.aspx?format=js&idx="+index+"&n=1";
EasyHttp.post(str)
.accessToken(true)
.timeStamp(true)
.execute(new SimpleCallBack<String>() {
@Override
public void onError(ApiException e) {
liveData.setValue(new BingDataBean(null,e.getMessage()));
index++;
}
@Override
public void onSuccess(String result) {
liveData.setValue(new BingDataBean(result,null));
}
});
}
}
5.activity_bing_img.xml布局文件
注意 此处app:imageUrl="@{imgUrl}"
为ObservableField
修饰,因为我在写这个demo的时候,之前有写了相关的工具类,懒得做修改,其实只是String
就可以了,也可以是直接使用viewmodel
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View.OnClickListener"/>
<import type="androidx.databinding.ObservableField"/>
<variable
name="myClick"
type="OnClickListener" />
<variable
name="imgUrl"
type="ObservableField<String>" />
<variable
name="model"
type="com.hwp.databindingdemo.viewmodel.BingImgViewModel" />
<variable
name="error"
type="android.graphics.drawable.Drawable" />
<variable
name="placeholder"
type="android.graphics.drawable.Drawable" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.BingImgActivity">
<!--app:image2Url="@{model}"-->
<ImageView
app:imageUrl="@{imgUrl}"
app:error="@{error}"
app:placeHolder="@{placeholder}"
android:id="@+id/iv_show"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="0dp" />
<Button
android:onClick="@{myClick}"
android:text="上一页"
app:layout_constraintRight_toLeftOf="@+id/btn_load"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_show"
android:id="@+id/btn_previous"
android:layout_width="0dp"
android:layout_height="60dp" />
<Button
android:onClick="@{myClick}"
android:text="加载"
app:layout_constraintRight_toLeftOf="@+id/btn_next"
app:layout_constraintLeft_toRightOf="@+id/btn_previous"
app:layout_constraintTop_toBottomOf="@+id/iv_show"
android:id="@+id/btn_load"
android:layout_width="0dp"
android:layout_height="60dp" />
<Button
android:onClick="@{myClick}"
android:text="下一页"
app:layout_constraintLeft_toRightOf="@+id/btn_load"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/btn_next"
app:layout_constraintTop_toBottomOf="@+id/iv_show"
android:layout_width="0dp"
android:layout_height="60dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
6.BindingAdapter类,封装图片加载
public class BindingAdapters {
//注意此处有几个参数,相关地方需要写全几个参数
@BindingAdapter({"app:imageUrl", "app:placeHolder", "app:error"})
public static void loadImage(ImageView imageView, String url,Drawable placeholder,Drawable error) {
Glide.with(imageView.getContext())
.load(url)
.placeholder(placeholder)
.error(error)
.into(imageView);
}
}
7.BingImgActivity类
public class BingImgActivity extends AppCompatActivity implements View.OnClickListener {
private ActivityBingImgBinding bingImgBinding;
BingImgViewModel bingImgViewModel;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bingImgBinding= DataBindingUtil.setContentView(this,R.layout.activity_bing_img);
bingImgBinding.setMyClick(this);
bingImgBinding.setError(getDrawable(R.mipmap.pic_error));
bingImgBinding.setPlaceholder(getDrawable(R.mipmap.pic_loading));
bingImgViewModel = new ViewModelProvider(
this, new ViewModelProvider.AndroidViewModelFactory(getApplication())
).get(BingImgViewModel.class);
// bingImgViewModel= ViewModelProviders.of(this).get(BingImgViewModel.class);
bingImgViewModel.getImg().observe(this, new Observer<BingDataBean>() {
@Override
public void onChanged(BingDataBean bingDataBean) {
if(bingDataBean.getError()!=null){
ToastUtils.showShort("加载错误");
return;
}
BingImgBean bingImgBean=new Gson().fromJson(bingDataBean.getData(),BingImgBean.class);
bingImgBinding.setImgUrl(new ObservableField<String>("https://www.bing.com/"+bingImgBean.getImages().get(0).getUrl()));
ToastUtils.showShort("https://www.bing.com/"+bingImgBean.getImages().get(0).getUrl());
}
});
bingImgBinding.setModel(bingImgViewModel);
bingImgViewModel.loadImg();
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_load:
bingImgViewModel.loadImg();
break;
case R.id.btn_previous:
bingImgViewModel.previousImage();
break;
case R. id.btn_next:
bingImgViewModel.nextImage();
break;
}
}
}
网友评论