MediaItemView.java revision f6b29b560e55392015caebeffbe76f8a1d1ddeb4
1ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi/* 2f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * Copyright (C) 2011 The Android Open Source Project 3ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 4ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Licensed under the Apache License, Version 2.0 (the "License"); 5ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * you may not use this file except in compliance with the License. 6ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * You may obtain a copy of the License at 7ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 8ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * http://www.apache.org/licenses/LICENSE-2.0 9ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 10ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Unless required by applicable law or agreed to in writing, software 11ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * distributed under the License is distributed on an "AS IS" BASIS, 12ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * See the License for the specific language governing permissions and 14ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * limitations under the License. 15ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 16ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 1781393d6dc5767f7784a00958095614a37bf1a91aGil Dobjanschipackage com.android.videoeditor.widgets; 18ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 1981393d6dc5767f7784a00958095614a37bf1a91aGil Dobjanschiimport com.android.videoeditor.service.ApiService; 2081393d6dc5767f7784a00958095614a37bf1a91aGil Dobjanschiimport com.android.videoeditor.service.MovieMediaItem; 2181393d6dc5767f7784a00958095614a37bf1a91aGil Dobjanschiimport com.android.videoeditor.R; 22ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 23ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.content.Context; 24ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.graphics.Bitmap; 25ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.graphics.Canvas; 26ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.graphics.Point; 27ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.graphics.Rect; 28ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.graphics.drawable.Drawable; 29ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.util.AttributeSet; 30ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.util.DisplayMetrics; 31ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.util.Log; 32f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Changimport android.util.LruCache; 33ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.Display; 34ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.GestureDetector; 35ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.MotionEvent; 36ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.View; 37ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.WindowManager; 38ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 39f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Changimport java.util.ArrayList; 40f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Changimport java.util.HashSet; 41f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Changimport java.util.Map; 42f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 43ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi/** 44ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Media item preview view 45ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 46ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschipublic class MediaItemView extends View { 47ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private static final String TAG = "MediaItemView"; 48ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 49f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Static variables 50f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private static Drawable sAddTransitionDrawable; 51f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private static Drawable sEmptyFrameDrawable; 52f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private static ThumbnailCache sThumbnailCache; 53ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 54ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Instance variables 55ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private final GestureDetector mGestureDetector; 56ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private final ScrollViewListener mScrollListener; 57ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private final Rect mProgressDestRect; 58ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 59ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private boolean mIsScrolling; 60ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private boolean mIsTrimming; 61ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private boolean mIsPlaying; 62f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int mProgress; // -1: not in progress, 0-100: in progress 63ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 64f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private static int mScreenWidth; 65f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int mScrollX; 66ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 67f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private String mProjectPath; 68f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private MovieMediaItem mMediaItem; 69f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private ItemSimpleGestureListener mGestureListener; 70f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int[] mLeftState, mRightState; 71ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 72f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int mThumbnailWidth, mThumbnailHeight; 73f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int mNumberOfThumbnails; 74f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private long mBeginTimeMs, mEndTimeMs; 75ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 76f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int mGeneration; 77f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private HashSet<Integer> mPending; 78f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private ArrayList<Integer> mWantThumbnails; 79ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 80f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public MediaItemView(Context context, AttributeSet attrs) { 81f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang this(context, attrs, 0); 82f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 83ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 84f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public MediaItemView(Context context) { 85f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang this(context, null, 0); 86ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 87ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 88ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public MediaItemView(Context context, AttributeSet attrs, int defStyle) { 89ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi super(context, attrs, defStyle); 90ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 91f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Initialize static data 92f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (sAddTransitionDrawable == null) { 93f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable = getResources().getDrawable( 94f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang R.drawable.add_transition_selector); 95f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sEmptyFrameDrawable = getResources().getDrawable( 96f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang R.drawable.timeline_loading); 97ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 98f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Initialize the thumbnail cache, limit the memory usage to 3MB 99f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sThumbnailCache = new ThumbnailCache(3*1024*1024); 100f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 101ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 102f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Get the screen width 103f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang final Display display = ((WindowManager)context.getSystemService( 104f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Context.WINDOW_SERVICE)).getDefaultDisplay(); 105f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang final DisplayMetrics metrics = new DisplayMetrics(); 106f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang display.getMetrics(metrics); 107f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mScreenWidth = metrics.widthPixels; 10877a3d89eaf839df50c2f3b4ddb0819ed974726b6Gil Dobjanschi 109f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Setup our gesture detector and scroll listener 110f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mGestureDetector = new GestureDetector(context, new MyGestureListener()); 111f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mScrollListener = new MyScrollViewListener(); 112ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 113f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Prepare the progress bar rectangles 114ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi final ProgressBar progressBar = ProgressBar.getProgressBar(context); 115f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang final int layoutHeight = (int)( 116f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang getResources().getDimension(R.dimen.media_layout_height) - 117f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang getResources().getDimension(R.dimen.media_layout_padding)); 118ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mProgressDestRect = new Rect(getPaddingLeft(), 119ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi layoutHeight - progressBar.getHeight() - getPaddingBottom(), 0, 120ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi layoutHeight - getPaddingBottom()); 121ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 122ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Initialize the progress value 123ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mProgress = -1; 124ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 125f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Initialize the "Add transition" indicators state 126f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mLeftState = View.EMPTY_STATE_SET; 127f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mRightState = View.EMPTY_STATE_SET; 128ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 129f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Initialize the thumbnail indices we want to request 130f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mWantThumbnails = new ArrayList<Integer>(); 13177a3d89eaf839df50c2f3b4ddb0819ed974726b6Gil Dobjanschi 132f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Initialize the set of indices we are waiting 133f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mPending = new HashSet<Integer>(); 134f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 135ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 136f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { 137f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 138f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public boolean onSingleTapConfirmed(MotionEvent e) { 139f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (mGestureListener == null) { 140f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return false; 141f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 142ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 143f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int tappedArea = ItemSimpleGestureListener.CENTER_AREA; 144f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 145f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (hasAddTransition()) { 146f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (mMediaItem.getBeginTransition() == null && 147f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang e.getX() < sAddTransitionDrawable.getIntrinsicWidth() + 148f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang getPaddingLeft()) { 149f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang tappedArea = ItemSimpleGestureListener.LEFT_AREA; 150f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } else if (mMediaItem.getEndTransition() == null && 151f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang e.getX() >= getWidth() - getPaddingRight() - 152f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.getIntrinsicWidth()) { 153f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang tappedArea = ItemSimpleGestureListener.RIGHT_AREA; 154f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 155f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 156f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return mGestureListener.onSingleTapConfirmed( 157f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang MediaItemView.this, tappedArea, e); 158f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 159ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 160f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 161f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void onLongPress(MotionEvent e) { 162f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (mGestureListener != null) { 163f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mGestureListener.onLongPress(MediaItemView.this, e); 164f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 165f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 166ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 167ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 168f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private class MyScrollViewListener implements ScrollViewListener { 169f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 170f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void onScrollBegin(View view, int scrollX, int scrollY, boolean appScroll) { 171f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mIsScrolling = true; 172f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 173f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 174f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 175f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void onScrollProgress(View view, int scrollX, int scrollY, boolean appScroll) { 176f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mScrollX = scrollX; 177f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang invalidate(); 178f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 179f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 180f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 181f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void onScrollEnd(View view, int scrollX, int scrollY, boolean appScroll) { 182f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mIsScrolling = false; 183f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mScrollX = scrollX; 184f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang invalidate(); 185f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 186ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 187ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 188ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi @Override 189ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi protected void onAttachedToWindow() { 190f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mMediaItem = (MovieMediaItem)getTag(); 191ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Add the horizontal scroll view listener 192ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi final TimelineHorizontalScrollView scrollView = 193ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi (TimelineHorizontalScrollView)((View)((View)getParent()).getParent()).getParent(); 194f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mScrollX = scrollView.getScrollX(); 195ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi scrollView.addScrollListener(mScrollListener); 196ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 197ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 198ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi @Override 199ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi protected void onDetachedFromWindow() { 200ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi final TimelineHorizontalScrollView scrollView = 201f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang (TimelineHorizontalScrollView)((View)((View)getParent()).getParent()).getParent(); 202ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi scrollView.removeScrollListener(mScrollListener); 203ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 204f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Release the cached bitmaps 205f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang releaseBitmapsAndClear(); 206ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 207ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 208ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 209ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @return The shadow builder 210ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 211ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public DragShadowBuilder getShadowBuilder() { 212ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return new MediaItemShadowBuilder(this); 213ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 214ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 215ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 216f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * Shadow builder for the media item 217f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang */ 218f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private class MediaItemShadowBuilder extends DragShadowBuilder { 219f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private final Drawable mFrame; 220f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 221f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public MediaItemShadowBuilder(View view) { 222f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang super(view); 223f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mFrame = view.getContext().getResources().getDrawable( 224f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang R.drawable.timeline_item_pressed); 225f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 226f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 227f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 228f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) { 229f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang shadowSize.set(getShadowWidth(), getShadowHeight()); 230f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y); 231f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 232f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 233f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 234f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void onDrawShadow(Canvas canvas) { 235f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mFrame.setBounds(0, 0, getShadowWidth(), getShadowHeight()); 236f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mFrame.draw(canvas); 237f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 238f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Bitmap bitmap = getOneThumbnail(); 239f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (bitmap != null) { 240f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang final View view = getView(); 241f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang canvas.drawBitmap(bitmap, view.getPaddingLeft(), 242f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang view.getPaddingTop(), null); 243f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 244f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 245f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 246f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 247f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang /** 248ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @return The shadow width 249ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 250f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int getShadowWidth() { 251ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi final int thumbnailHeight = getHeight() - getPaddingTop() - getPaddingBottom(); 252f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang final int thumbnailWidth = (thumbnailHeight * mMediaItem.getWidth()) / 253f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mMediaItem.getHeight(); 254ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return thumbnailWidth + getPaddingLeft() + getPaddingRight(); 255ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 256ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 257ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 258ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @return The shadow height 259ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 260f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private int getShadowHeight() { 261ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return getHeight(); 262ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 263ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 264f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private Bitmap getOneThumbnail() { 265f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang ThumbnailKey key = new ThumbnailKey(); 266f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang key.mediaItemId = mMediaItem.getId(); 267f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 268f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Find any one cached thumbnail 269f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang for (int i = 0; i < mNumberOfThumbnails; i++) { 270f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang key.index = i; 271f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Bitmap bitmap = sThumbnailCache.get(key); 272f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (bitmap != null) { 273f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return bitmap; 274f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 275f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 276f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 277f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return null; 278f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 279f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 280ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 281ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param projectPath The project path 282ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 283ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void setProjectPath(String projectPath) { 284ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mProjectPath = projectPath; 285ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 286ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 287ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 288ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param listener The gesture listener 289ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 290ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void setGestureListener(ItemSimpleGestureListener listener) { 291ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mGestureListener = listener; 292ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 293ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 294ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 295f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * A view enters or exits the playback mode 29603699548e6f627af79aac4fd0d233f10e53841d0Gil Dobjanschi * 297f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * @param playback true if playback is in progress 298ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 299f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void setPlaybackMode(boolean playback) { 300f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mIsPlaying = playback; 301f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang invalidate(); 302f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 303ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 304f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang /** 305f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * A view enters or exits the trimming mode 306f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * 307f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * @param trimmingView The view which is being trimmed 308f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * @param trimming true if trimming 309f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang */ 310f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void setTrimMode(View trimmingView, boolean trimming) { 311f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mIsTrimming = trimming; 312f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Redraw the control to hide the "Add transition" areas 313f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang invalidate(); 314ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 315ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 316ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 317ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param progress The progress 318ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 319ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void setProgress(int progress) { 320ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (progress == 0) { 321ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mProgress = progress; 322ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Release the current set of bitmaps. New content is being generated. 323ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi releaseBitmapsAndClear(); 324ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else if (progress == 100) { 325ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mProgress = -1; 326ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else { 327ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mProgress = progress; 328ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 329ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 330ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi invalidate(); 331ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 332ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 333ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 334f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * The view has been layout out 335ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 336f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * @param oldLeft The old left position 337f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * @param oldRight The old right position 338ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 339f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public void onLayoutPerformed(int oldLeft, int oldRight) { 340f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Compute the thumbnail width and height 341f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mThumbnailHeight = getHeight() - getPaddingTop() - getPaddingBottom(); 342f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mThumbnailWidth = (mThumbnailHeight * mMediaItem.getWidth()) / mMediaItem.getHeight(); 343ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 344f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int usableWidth = getWidth() - getPaddingLeft() - getPaddingRight(); 345f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mNumberOfThumbnails = (usableWidth + mThumbnailWidth - 1) / mThumbnailWidth; 346f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mBeginTimeMs = mMediaItem.getAppBoundaryBeginTime(); 347f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mEndTimeMs = mMediaItem.getAppBoundaryEndTime(); 348ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 349f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang releaseBitmapsAndClear(); 350f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang invalidate(); 351ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 352ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 353ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 354f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * @return True if generation is in progress 355ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 356f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public boolean isInProgress() { 357f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return (mProgress >= 0); 358f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 359ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 360f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public boolean setBitmap(Bitmap bitmap, int index, int token) { 361f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Ignore results from previous requests 362f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (token != mGeneration) { 363ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return false; 364f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 365f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (!mPending.contains(index)) { 366f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Log.e(TAG, "received unasked bitmap, index = " + index); 367ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return false; 368ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 369f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (bitmap == null) { 370f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Log.w(TAG, "receive null bitmap for index = " + index); 371f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // We keep this request in mPending, so we won't request it again. 372f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return false; 373ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 374f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mPending.remove(index); 375f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang ThumbnailKey key = new ThumbnailKey(mMediaItem.getId(), index); 376f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sThumbnailCache.put(key, bitmap); 377ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 378ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi invalidate(); 379ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return true; 380ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 381ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 382ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi @Override 383ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi protected void onDraw(Canvas canvas) { 384ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi super.onDraw(canvas); 385ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (mProgress >= 0) { 386f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang ProgressBar.getProgressBar(getContext()).draw( 387f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang canvas, mProgress, mProgressDestRect, 388f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang getPaddingLeft(), getWidth() - getPaddingRight()); 389f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } else { 390ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Do not draw in the padding area 391f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang canvas.clipRect(getPaddingLeft(), getPaddingTop(), 392f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang getWidth() - getPaddingRight(), 393ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi getHeight() - getPaddingBottom()); 394ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 395f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Draw thumbnails 396f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang drawThumbnails(canvas); 397ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 398f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Draw the "Add transition" indicators 399ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (isSelected()) { 400ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi drawAddTransitions(canvas); 401ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 402ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 403f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Request thumbnails if things are not moving 404f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang boolean isBusy = mIsPlaying || mIsTrimming || mIsScrolling; 405f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (!isBusy && !mWantThumbnails.isEmpty()) { 406f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang requestThumbnails(); 407ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 408ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 409ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 410ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 411f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Draws the thumbnails, also put unavailable thumbnail indices in 412f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // mWantThumbnails. 41377a3d89eaf839df50c2f3b4ddb0819ed974726b6Gil Dobjanschi private void drawThumbnails(Canvas canvas) { 414f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mWantThumbnails.clear(); 415f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 416f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // The screen coordinate of the left edge of the usable area. 417f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int left = getLeft() + getPaddingLeft() - mScrollX; 418f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // The screen coordinate of the right edge of the usable area. 419f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int right = getRight() - getPaddingRight() - mScrollX; 420f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Return if the usable area is not on screen. 421f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (left >= mScreenWidth || right <= 0 || left >= right) { 422ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return; 423ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 424ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 425f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Map [0, mScreenWidth - 1] to the indices of the thumbnail. 426f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int startIdx = (0 - left) / mThumbnailWidth; 427f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int endIdx = (mScreenWidth - 1 - left) / mThumbnailWidth; 428ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 429f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang startIdx = clamp(startIdx, 0, mNumberOfThumbnails - 1); 430f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang endIdx = clamp(endIdx, 0, mNumberOfThumbnails - 1); 431ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 432f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Prepare variables used in the loop 433f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang ThumbnailKey key = new ThumbnailKey(); 434f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang key.mediaItemId = mMediaItem.getId(); 435f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int x = getPaddingLeft() + startIdx * mThumbnailWidth; 436f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int y = getPaddingTop(); 43777a3d89eaf839df50c2f3b4ddb0819ed974726b6Gil Dobjanschi 438f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Loop through the thumbnails on screen and draw it 439f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang for (int i = startIdx; i <= endIdx; i++) { 440f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang key.index = i; 441f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Bitmap bitmap = sThumbnailCache.get(key); 442f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (bitmap == null) { 44377a3d89eaf839df50c2f3b4ddb0819ed974726b6Gil Dobjanschi // Draw a frame placeholder 444f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sEmptyFrameDrawable.setBounds( 445f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang x, y, x + mThumbnailWidth, y + mThumbnailHeight); 446f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sEmptyFrameDrawable.draw(canvas); 447f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (!mPending.contains(i)) { 448f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mWantThumbnails.add(Integer.valueOf(i)); 44977a3d89eaf839df50c2f3b4ddb0819ed974726b6Gil Dobjanschi } 450f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } else { 451f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang canvas.drawBitmap(bitmap, x, y, null); 45277a3d89eaf839df50c2f3b4ddb0819ed974726b6Gil Dobjanschi } 453f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang x += mThumbnailWidth; 454ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 455ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 456ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 457ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 458f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang * Draw the "Add transition" area at the beginning and end of the media item 459ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 460ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param canvas Draw on this canvas 461ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 462ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private void drawAddTransitions(Canvas canvas) { 463ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (hasAddTransition()) { 464f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (mMediaItem.getBeginTransition() == null) { 465f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.setState(mLeftState); 466f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.setBounds(getPaddingLeft(), getPaddingTop(), 467f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.getIntrinsicWidth() + getPaddingLeft(), 468f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang getPaddingTop() + sAddTransitionDrawable.getIntrinsicHeight()); 469f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.draw(canvas); 470ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 471ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 472f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (mMediaItem.getEndTransition() == null) { 473f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.setState(mRightState); 474f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.setBounds( 475ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi getWidth() - getPaddingRight() - 476f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.getIntrinsicWidth(), 477ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi getPaddingTop(), getWidth() - getPaddingRight(), 478f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang getPaddingTop() + sAddTransitionDrawable.getIntrinsicHeight()); 479f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.draw(canvas); 480ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 481ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 482ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 483ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 484ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 485ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @return true if the "Add transition" areas exist 486ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 487ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private boolean hasAddTransition() { 488ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (mIsTrimming) { 489ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return false; 490ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 491ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 492ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return (getWidth() - getPaddingLeft() - getPaddingRight() >= 493f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 2 * sAddTransitionDrawable.getIntrinsicWidth()); 494f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 495f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 496f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // clamp the input value v to the range [low, high] 497f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private static int clamp(int v, int low, int high) { 498f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return Math.min(Math.max(v, low), high); 499f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 500f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 501f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Requests the thumbnails in mWantThumbnails (which is filled by onDraw) 502f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private void requestThumbnails() { 503f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Copy mWantThumbnails to an array 504f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang int indices[] = new int[mWantThumbnails.size()]; 505f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang for (int i = 0; i < mWantThumbnails.size(); i++) { 506f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang indices[i] = mWantThumbnails.get(i); 507f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 508f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 509f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang // Put them in the pending set 510f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mPending.addAll(mWantThumbnails); 511f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang 512f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang ApiService.getMediaItemThumbnails(getContext(), mProjectPath, 513f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mMediaItem.getId(), mThumbnailWidth, mThumbnailHeight, 514f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mBeginTimeMs, mEndTimeMs, mNumberOfThumbnails, mGeneration, 515f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang indices); 516ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 517ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 518ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi @Override 519ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public boolean onTouchEvent(MotionEvent ev) { 520ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Let the gesture detector inspect all events. 521ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mGestureDetector.onTouchEvent(ev); 522ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi super.onTouchEvent(ev); 523ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 524ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi switch (ev.getAction()) { 525ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi case MotionEvent.ACTION_DOWN: { 526f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mLeftState = View.EMPTY_STATE_SET; 527f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mRightState = View.EMPTY_STATE_SET; 528ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (isSelected() && hasAddTransition()) { 529f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (ev.getX() < sAddTransitionDrawable.getIntrinsicWidth() + 530ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi getPaddingLeft()) { 531f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (mMediaItem.getBeginTransition() == null) { 532ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mLeftState = View.PRESSED_WINDOW_FOCUSED_STATE_SET; 533ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 534ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else if (ev.getX() >= getWidth() - getPaddingRight() - 535f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sAddTransitionDrawable.getIntrinsicWidth()) { 536f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (mMediaItem.getEndTransition() == null) { 537ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mRightState = View.PRESSED_WINDOW_FOCUSED_STATE_SET; 538ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 539ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 540ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 541ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi invalidate(); 542ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi break; 543ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 544ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 545ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi case MotionEvent.ACTION_UP: 546ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi case MotionEvent.ACTION_CANCEL: { 547ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mRightState = View.EMPTY_STATE_SET; 548ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mLeftState = View.EMPTY_STATE_SET; 549ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi invalidate(); 550ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi break; 551ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 552ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 553ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi default: { 554ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi break; 555ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 556ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 557ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 558ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return true; 559ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 560ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 561f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private void releaseBitmapsAndClear() { 562f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang sThumbnailCache.clearForMediaItemId(mMediaItem.getId()); 563f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mPending.clear(); 564f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mGeneration++; 565f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 566f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang} 567ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 568f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Changclass ThumbnailKey { 569f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public String mediaItemId; 570f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public int index; 571ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 572f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public ThumbnailKey() { 573f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 574ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 575f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public ThumbnailKey(String id, int idx) { 576f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mediaItemId = id; 577f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang index = idx; 578f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 579ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 580f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 581f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public boolean equals(Object o) { 582f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (!(o instanceof ThumbnailKey)) { 583f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return false; 584ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 585f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang ThumbnailKey key = (ThumbnailKey) o; 586f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return index == key.index && mediaItemId.equals(key.mediaItemId); 587f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 588ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 589f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang @Override 590f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public int hashCode() { 591f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return mediaItemId.hashCode() ^ index; 592f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 593f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang} 594ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 595f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Changclass ThumbnailCache { 596f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang private LruCache<ThumbnailKey, Bitmap> mCache; 597ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 598f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang public ThumbnailCache(int size) { 599f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mCache = new LruCache(size) { 600f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang protected int sizeOf(ThumbnailKey key, Bitmap value) { 601f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return value.getByteCount(); 602ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 603f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang }; 604ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 605ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 606f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang void put(ThumbnailKey key, Bitmap value) { 607f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mCache.put(key, value); 608ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 609ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 610f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Bitmap get(ThumbnailKey key) { 611f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang return mCache.get(key); 612f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang } 613ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 614f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang void clearForMediaItemId(String id) { 615f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang Map<ThumbnailKey, Bitmap> map = mCache.snapshot(); 616f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang for (ThumbnailKey key : map.keySet()) { 617f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang if (key.mediaItemId.equals(id)) { 618f6b29b560e55392015caebeffbe76f8a1d1ddeb4Chih-Chung Chang mCache.remove(key); 619ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 620ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 621ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 622ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi} 623