美文网首页
Jetpack学习(四)——LiveData&ViewModel

Jetpack学习(四)——LiveData&ViewModel

作者: 岁月静好浅笑安然 | 来源:发表于2020-01-14 18:01 被阅读0次

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&lt;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;
        }
    }
}

相关文章

网友评论

      本文标题:Jetpack学习(四)——LiveData&ViewModel

      本文链接:https://www.haomeiwen.com/subject/tgpaactx.html