天天看點

初涉RxAndroid結合Glide實作多圖檔加載操作

轉載請注明出處:王亟亟的大牛之路

本來周末就想發了然後各種拖拉就沒有然後了,那麼就今天早上寫吧,廢話不多開始正題

什麼是RxJava或者RxAndroid我就不多廢話了,理論知識一大堆人給我們做好了,隻要自己肯去看就能了解,我這裡直接給出傳送門:https://github.com/lzyzsd/Awesome-RxJava(很豐富,看完就基本有概念了)

那麼問題來了,人家都解釋完了我幹嘛?實操個簡單的例子吧,正好上周講了篇Glide的那麼這次就實踐下

效果圖:

初涉RxAndroid結合Glide實作多圖檔加載操作

我們點開App然後就是一個RecycleView裡面有一堆圖然後還有文字,文字是本地的,圖是網上下的,邏輯流程很簡單,來說一下怎麼實作的然後引出主角。

包結構:

初涉RxAndroid結合Glide實作多圖檔加載操作

GlideModuleConfig配置Glide

StatusBarCompat沉浸式菜單欄實作(翔哥那扣來的,這個其實可有可無主要預設的顔色太醜)

TestOBJ頁面對象的屬性模型(你也可以不用,個人習慣)

然後就是業務實作的MainActivity和擴充卡DataAdapter了

我們一個一個類看先是GlideModuleConfig

/**
 * Created by jiajiewang on 16/3/25.
 */
public class GlideModuleConfig implements GlideModule {

    //在這裡建立設定内容,之前文章所提及的圖檔品質就可以在這裡設定
    //還可以設定緩存池參數什麼的
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        //設定了預設圖檔格式
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
        //設定了緩存的位置
        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context,"MY_CACHE_LOCATION", **));
    }

    //在這裡注冊ModelLoaders
    @Override
    public void registerComponents(Context context, Glide glide) {

    }
}
           

這裡做一些配置工作,具體幹什麼可以看注釋

TestOBJ用于給RecycleView引用圖檔位址和文字内容

public class TestOBJ {
    public String imageUrl;
    public String content;
}
           

翔哥那個類不解釋了,可以自己去搜搜百度第一條就是,我們再來看看擴充卡

DataAdapter(重要步驟的解釋也在注釋裡了)

public class DataAdapter extends RecyclerView.Adapter {
    Context context;
    List<TestOBJ> testOBJs;

    public DataAdapter(Context context) {
        this.context = context;
    }

    //擷取布局
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new DataViewHolder(view);
    }

    //具體item的加載圖檔填充資料
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        DataViewHolder dataViewHolder = (DataViewHolder) holder;
        TestOBJ obj = testOBJs.get(position);
//先擷取上下文對象,再加載具體的URL然後填充到控件裡去
        Glide.with(holder.itemView.getContext()).load(obj.imageUrl).into(dataViewHolder.imageIV);
        dataViewHolder.contentTV.setText(obj.content);
    }

    @Override
    public int getItemCount() {
        return testOBJs == null ?  : testOBJs.size();
    }

    //控件對象Holder
    static class DataViewHolder extends RecyclerView.ViewHolder {
        ImageView imageIV;
        TextView contentTV;

        public DataViewHolder(View itemView) {
            super(itemView);
            imageIV = (ImageView) itemView.findViewById(R.id.imageIV);
            contentTV = (TextView) itemView.findViewById(R.id.contentTV);
        }
    }

    //重新整理資料用
    public void updateData(List<TestOBJ> testOBJs) {
        this.testOBJs = testOBJs;
        notifyDataSetChanged();
    }
}
           

資料層已經OK了,我們來看看業務層

public class MainActivity extends AppCompatActivity {
    Toolbar toolBar;
    RecyclerView recycleView;
    DataAdapter dataAdapter;
    //URL資料源
    String data[] = {"http://hiphotos.baidu.com/zhixin/abpic/item/4651a712c8fcc3cea97dbce49045d688d53f206c.jpg"
            , "http://pic.5442.com/2014/0930/06/5442.jpg",
            "http://img5q.duitang.com/uploads/item/201410/22/20141022214043_5EEKH.thumb.224_0.jpeg",
            "http://img5.duitang.com/uploads/item/201512/08/20151208163159_HGEM2.thumb.224_0.png",
            "http://img4.duitang.com/uploads/item/201510/29/20151029224537_ijEKF.thumb.224_0.jpeg",
            "http://img5.imgtn.bdimg.com/it/u=1230273521,1023320328&fm=21&gp=0.jpg"
    };

    //被觀察者
    Observable observable = Observable.create(new Observable.OnSubscribe<List<TestOBJ>>() {
        @Override
        public void call(Subscriber<? super List<TestOBJ>> subscriber) {
            subscriber.onNext(makeData());
            subscriber.onCompleted();
        }
    });

    //觀察者
    Observer<List<TestOBJ>> observer = new Observer<List<TestOBJ>>() {

        @Override
        public void onCompleted() {
            LogUtils.d("--->onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            Toast.makeText(MainActivity.this, "加載失敗", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onNext(List<TestOBJ> testOBJs) {
            testOBJs.size();
            LogUtils.d("--->onNext  testOBJs.size() " + testOBJs.size());
            //重新整理資料
            dataAdapter.updateData(testOBJs);
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
        logic();
        setSupportActionBar(toolBar);
        StatusBarCompat.compat(this, getResources().getColor(R.color.status_bar_color));
        StatusBarCompat.compat(this);
    }

    private void init() {
        LogUtils.d("--->init");
        toolBar = (Toolbar) findViewById(R.id.toolBar);
        recycleView = (RecyclerView) findViewById(R.id.recycleView);

        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);

    }

    private void logic() {
        LogUtils.d("--->logic");
        dataAdapter = new DataAdapter(MainActivity.this);
        recycleView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        recycleView.setAdapter(dataAdapter);

        LogUtils.d("--->Glide.getPhotoCacheDir " + Glide.getPhotoCacheDir(MainActivity.this, "MY_CACHE_LOCATION"));

    }

    //制造資料
    private List<TestOBJ> makeData() {
        List<TestOBJ> list = new ArrayList<>();
        TestOBJ testOBJ;
        for (int k = ; k < ; k++) {
            testOBJ = new TestOBJ();
            testOBJ.content = "标題啊,你服不服 " + k + " 個 ";
            testOBJ.imageUrl = data[k];
            list.add(testOBJ);
        }
        LogUtils.d("--->list的長度等于 " + list.size());
        return list;
    }

    @Override
    protected void onPause() {
        super.onPause();
        //清除請求
        Glide.clear(recycleView);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LogUtils.d("--->onDestroy");
        //必須主線程使用
        Glide.get(this).clearMemory();
        //Glide.get(this).clearDiskCache(); 非主線程
    }
}
           

解釋:

我們定義了一個觀察者和一個被觀察者然後自從

observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
           

注冊的行為開始後,隻咬被觀察者一有風吹草動,觀察者的相關回調就會被觸發,我們來看下Log的列印順序

初涉RxAndroid結合Glide實作多圖檔加載操作

還是在一堆的Activity生命周期裡先跑在我們資料摸你的過程中看了可能我們Glide緩存的目錄,跟我們的預設一緻,接着就執行了 onNext再是onCompleted,因為沒出什麼意外也就沒刷出onError

源碼位址:https://github.com/ddwhan0123/RxAndroidDemo