private Resource<Bitmap> getTransformedFrame(Bitmap currentFrame, Transformation<Bitmap> transformation, GifDrawable drawable) { // TODO: what if current frame is null? Resource<Bitmap> bitmapResource = factory.buildFrameResource(currentFrame, bitmapPool); Resource<Bitmap> transformedResource = transformation.transform( context, bitmapResource, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); if (!bitmapResource.equals(transformedResource)) { bitmapResource.recycle(); } return transformedResource; }
@Test public void testLoopsASingleTimeIfLoopCountIsSetToOne() { final int loopCount = 1; final int frameCount = 2; when(frameLoader.getFrameCount()).thenReturn(frameCount); drawable.setLoopCount(loopCount); drawable.setVisible(true, true); drawable.start(); runLoops(loopCount, frameCount); verifyRanLoops(loopCount, frameCount); assertFalse("drawable should be stopped after loop is completed", drawable.isRunning()); }
@Override public void initialize() { drawable.getFirstFrame().prepareToDraw(); } }
@Override public void onFrameReady() { if (findCallback() == null) { stop(); invalidateSelf(); return; } invalidateSelf(); if (getFrameIndex() == getFrameCount() - 1) { loopCount++; } if (maxLoopCount != LOOP_FOREVER && loopCount >= maxLoopCount) { notifyAnimationEndToListeners(); stop(); } }
@Override public void draw(@NonNull Canvas canvas) { if (isRecycled) { return; } if (applyGravity) { Gravity.apply(GRAVITY, getIntrinsicWidth(), getIntrinsicHeight(), getBounds(), getDestRect()); applyGravity = false; } Bitmap currentFrame = state.frameLoader.getCurrentFrame(); canvas.drawBitmap(currentFrame, null, getDestRect(), getPaint()); }
@Test @SuppressWarnings("unchecked") public void testSetsTransformationAsFrameTransformation() { Resource<GifDrawable> resource = mockResource(); GifDrawable gifDrawable = mock(GifDrawable.class); Transformation<Bitmap> unitTransformation = UnitTransformation.get(); when(gifDrawable.getFrameTransformation()).thenReturn(unitTransformation); when(gifDrawable.getIntrinsicWidth()).thenReturn(500); when(gifDrawable.getIntrinsicHeight()).thenReturn(500); when(resource.get()).thenReturn(gifDrawable); Bitmap firstFrame = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); when(gifDrawable.getFirstFrame()).thenReturn(firstFrame); final int width = 123; final int height = 456; Bitmap expectedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Resource<Bitmap> expectedResource = mockResource(); when(expectedResource.get()).thenReturn(expectedBitmap); when(wrapped.transform(any(Context.class), Util.<Bitmap>anyResource(), anyInt(), anyInt())) .thenReturn(expectedResource); transformation.transform(context, resource, width, height); verify(gifDrawable).setFrameTransformation(isA(Transformation.class), eq(expectedBitmap)); }
@Override public void onResourceReady(GifDrawable resource, GlideAnimation<? super GifDrawable> glideAnimation) { int w = MeasureUtil.getScreenSize(mContext).x; int hh=resource.getIntrinsicHeight(); int ww=resource.getIntrinsicWidth() ; int high = hh * (w - 50)/ww; Rect rect = new Rect(20, 20,w-30,high); resource.setBounds(rect); urlDrawable.setBounds(rect); urlDrawable.setDrawable(resource); gifDrawables.add(resource); resource.setCallback(mTextView); resource.start(); resource.setLoopCount(GlideDrawable.LOOP_FOREVER); mTextView.setText(mTextView.getText()); mTextView.invalidate(); } }
@Test public void testStartsOnSetVisibleTrueIfRunning() { drawable.start(); drawable.setVisible(false, false); drawable.setVisible(true, true); assertTrue(drawable.isRunning()); }
@Override public void onClick(View view) { ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("giphy_url", result.images.original.url); clipboard.setPrimaryClip(clip); if (gifDrawable != null) { if (gifDrawable.isRunning()) { gifDrawable.stop(); } else { gifDrawable.start(); } } } });
@Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { Log.i(TAG, "onResourceReady: " + resource); mPlaceHolderDrawable.setDrawable(resource); if (resource instanceof GifDrawable) { ((GifDrawable) resource).setLoopCount(GifDrawable.LOOP_FOREVER); ((GifDrawable) resource).start(); } mPlaceHolderDrawable.invalidateSelf(); }
@Test public void testWritesTransformedBitmaps() { final Bitmap frame = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); when(decoder.getFrameCount()).thenReturn(1); when(decoder.getNextFrame()).thenReturn(frame); when(gifEncoder.start(any(OutputStream.class))).thenReturn(true); int expectedWidth = 123; int expectedHeight = 456; when(gifDrawable.getIntrinsicWidth()).thenReturn(expectedWidth); when(gifDrawable.getIntrinsicHeight()).thenReturn(expectedHeight); Bitmap transformedFrame = Bitmap.createBitmap(200, 200, Bitmap.Config.RGB_565); when(transformedResource.get()).thenReturn(transformedFrame); when(frameTransformation.transform( anyContext(), eq(frameResource), eq(expectedWidth), eq(expectedHeight))) .thenReturn(transformedResource); when(gifDrawable.getFrameTransformation()).thenReturn(frameTransformation); encoder.encode(resource, file, options); verify(gifEncoder).addFrame(eq(transformedFrame)); }
@Test public void testShouldNotScheduleItselfIfAlreadyRunning() { drawable.setVisible(true, true); drawable.start(); drawable.start(); verify(frameLoader, times(1)).subscribe(eq(drawable)); }
@Test public void testDoesNotStartOnSetVisibleIfStartedAndStopped() { drawable.start(); drawable.stop(); drawable.setVisible(true, true); assertFalse(drawable.isRunning()); }
@Test public void onFrameReady_whenAttachedToDrawableCallbackButNotViewCallback_stops() { TransitionDrawable topLevel = new TransitionDrawable(new Drawable[] { drawable }); drawable.setCallback(topLevel); topLevel.setCallback(null); drawable.start(); drawable.onFrameReady(); assertThat(drawable.isRunning()).isFalse(); }
@Override public void draw(Canvas canvas) { if (isRecycled) { return; } if (applyGravity) { Gravity.apply(GifState.GRAVITY, getIntrinsicWidth(), getIntrinsicHeight(), getBounds(), destRect); applyGravity = false; } Bitmap currentFrame = frameLoader.getCurrentFrame(); Bitmap toDraw = currentFrame != null ? currentFrame : state.firstFrame; canvas.drawBitmap(toDraw, null, destRect, paint); }
@Override public boolean encode(@NonNull Resource<GifDrawable> resource, @NonNull File file, @NonNull Options options) { GifDrawable drawable = resource.get(); Transformation<Bitmap> transformation = drawable.getFrameTransformation(); boolean isTransformed = !(transformation instanceof UnitTransformation); if (isTransformed && options.get(ENCODE_TRANSFORMATION)) { return encodeTransformedToFile(drawable, file); } else { return writeDataDirect(drawable.getBuffer(), file); } }
@Override public void run() { // Make sure a frame is loaded while the drawable is stopped. GifState gifState = (GifState) Preconditions.checkNotNull(gifDrawable.getConstantState()); gifState.frameLoader.setOnEveryFrameReadyListener(new OnEveryFrameListener() { @Override public void onFrameReady() { waitForGifFrame.countDown(); } }); gifDrawable.start(); gifDrawable.stop(); } });
@Test public void testDoesNotDrawFrameAfterRecycle() { Bitmap bitmap = Bitmap.createBitmap(100, 112341, Bitmap.Config.RGB_565); drawable.setVisible(true, true); drawable.start(); when(frameLoader.getCurrentFrame()).thenReturn(bitmap); drawable.onFrameReady(); drawable.recycle(); Canvas canvas = mock(Canvas.class); drawable.draw(canvas); verify(canvas, never()).drawBitmap(eq(bitmap), isARect(), isARect(), isAPaint()); }
/** * Starts the animation from the first frame. Can only be called while animation is not running. */ // Public API. @SuppressWarnings("unused") public void startFromFirstFrame() { Preconditions.checkArgument(!isRunning, "You cannot restart a currently running animation."); state.frameLoader.setNextStartFromFirstFrame(); start(); }