Android圖片加載的框架Fresco使用

jopen 9年前發布 | 68K 次閱讀 Fresco Android開發 移動開發

       我們接著上文繼續說,上篇博客中我們已經知道了Fresco怎么用,也知道了它的很多屬性,但是很多時候xml文件是不能滿足你的要求的,這就需要你在代碼中動態的改變顯示的內容,今天我們就來探索一下如何在代碼中改變圖片實現的狀態和內容

       前面我們已經使用過SimpleDraweeView這個控件了,顯示圖片的時候直接寫了一個setImageURI(uri),Fresco不僅僅提供了這一個方法來顯示圖片,它還提供了setController(controller)方法加載圖片


DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setUri(uri)
                .build();
        imageView.setController(controller);
    當然如果你想監聽加載的過程,就加一個ControllerListen



ControllerListener listener = new BaseControllerListener(){
            @Override
            public void onFinalImageSet(String id, Object imageInfo, Animatable animatable) {
                super.onFinalImageSet(id, imageInfo, animatable);
            }

            @Override
            public void onFailure(String id, Throwable throwable) {
                super.onFailure(id, throwable);
            }

            @Override
            public void onIntermediateImageFailed(String id, Throwable throwable) {
                super.onIntermediateImageFailed(id, throwable);
            }
        };
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setUri(uri)
                .setControllerListener(listener)
                .build();
        imageView.setController(controller);
    圖片加載成功或者失敗,會執行里面的方法,其中圖片加載成功時會執行onFinalImageSet方法,圖片加載失敗時會執行onFailure方法,如果圖片設置漸進式,onIntermediateImageFailed會被回調


    說完了如何加載uri之后,如何實現在xml中的效果呢?我們繼續在java代碼中實現xml的效果


GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())
                .setFadeDuration(300)
                .setBackground(getDrawable(R.drawable.ic_launcher))
                .setPlaceholderImage(getDrawable(R.drawable.ic_launcher))
                .setFailureImage(getDrawable(R.drawable.ic_launcher))
                .build();
        imageView.setHierarchy(hierarchy);
     方法很多,你在xml中用到的都可以在這里設置,有些在xml中不能設置的在這里也是可以的,例如,我可以設置多張背景圖片,我可以設置多張疊加圖,這里都可以幫你實現,是不是很強大啊,想不想拿到特權了一樣呢!但是DraweeHiererchy創建時比較耗時,所以要多次利用



 GenericDraweeHierarchy hierarchy1 = imageView.getHierarchy();
    這個框架不僅僅是這些東西,它還有很多更牛逼的東西,例如:它提供了漸進式加載圖片,顯示gif動畫圖片等等


    首先是漸進式圖片加載,這方面的功能充分考慮了網絡比較慢的情況下,用戶不至于一致在等,最起碼能看到模糊的照片,這個所謂的漸進式加載就是說用戶從圖片加載之后,圖片會從模糊到清晰的一個漸變過程,當然這個過程僅限于從網絡加載圖片,本地或者緩存等地方的圖片也不需要漸進式加載,沒有意義


ProgressiveJpegConfig config = new ProgressiveJpegConfig() {
            @Override
            public int getNextScanNumberToDecode(int i) {
                return 0;
            }

            @Override
            public QualityInfo getQualityInfo(int i) {
                return null;
            }
        };

        ImagePipelineConfig imagePipelineConfig = ImagePipelineConfig.newBuilder(this)
                .setProgressiveJpegConfig(config)
                .build();
        Fresco.initialize(getApplicationContext(),imagePipelineConfig);
當然你也可以使用ProgressiveJpegConfig config1= new SimpleProgressiveJpegConfig(list,2);
<pre name="code" class="java">FLog.setMinimumLoggingLevel(FLog.VERBOSE);
        Set<RequestListener> listeners = new HashSet<>();
        listeners.add(new RequestLoggingListener());
        ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
                .setRequestListeners(listeners)
                .build();
        Fresco.initialize(this, config);
        setContentView(R.layout.activity_main);

        mProgressiveJpegView = (SimpleDraweeView) findViewById(R.id.my_image_view);

        Uri uri = Uri.parse("http://pooyak.com/p/progjpeg/jpegload.cgi?o=1");
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .setProgressiveRenderingEnabled(true)
                .build();
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setImageRequest(request)
                .build();
        mProgressiveJpegView.setController(controller);

 


ImageRequest request = ImageRequestBuilder
                .newBuilderWithSource(uri)
                .setProgressiveRenderingEnabled(true)
                .build();
        PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
                .setImageRequest(request)
                .setOldController(imageView.getController())
                .build();
        imageView.setController(controller);


   哎吆,不錯哦,可是這個image pipeline這個又是個什么啊?它的來頭比較大,負責圖片的加載工作 

    1.檢查內存緩存,如有,返回

         2.后臺線程開始后續工作

         3.檢查是否在未解碼內存緩存中。如有,解碼,變換,返回,然后緩存到內存緩存中。 

         4.檢查是否在文件緩存中,如果有,變換,返回。緩存到未解碼緩存和內存緩存中。

         5.從網絡或者本地加載。加載完成后,解碼,變換,返回。存到各個緩存中。

          繼續看gif圖片,其實跟顯示圖片沒什么差,主要是動態圖片涉及到的動畫的停止與播放,如果只是單純的試用一下,那就直接在controller里面設置setAutoPlayAnimation為true,如果你想手動監聽就new一個ControllerListener里面手動控制

   當我們要從服務器端下載一張高清圖片,圖片比較大,下載很慢的情況下有些服務器會提供一張縮略圖,同樣的Fresco也支持這種方法,在controller中提供了兩個不同的方法setLowResImageRequest和setImageRequest,看到方法名你應該明白了怎么用

    個人認為這個框架最巧妙的地方,就是把bitmap保存到ashmen,不會啟動gc,使的界面不會因為gc而卡死,Fresco使用三級緩存,第一級緩存就是保存bitmap,第二級緩存保存在內存,但是沒有解碼,使用時需要界面,第三級緩存就是保存在本地文件,同樣文件也未解碼,使用的時候要先解碼啦!

    上面談到的保存的很多內容都未解碼,這也是fresco默認使用3個線程的原因,一個線程用來加載uri,一個線程用來解碼,最后一個你知道它做什么,其余你想了解的東西自己去官網找找

來自:http://blog.csdn.net/elinavampire/article/details/47292085

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!