1166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong/*
2166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * Copyright (C) 2013 The Android Open Source Project
3166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong *
4166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * Licensed under the Apache License, Version 2.0 (the "License");
5166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * you may not use this file except in compliance with the License.
6166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * You may obtain a copy of the License at
7166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong *
8166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong *      http://www.apache.org/licenses/LICENSE-2.0
9166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong *
10166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * Unless required by applicable law or agreed to in writing, software
11166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * distributed under the License is distributed on an "AS IS" BASIS,
12166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * See the License for the specific language governing permissions and
14166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * limitations under the License.
15166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong */
16166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
1701054e922aa547b937a71131ad04c6bd15356240Angus Kongpackage com.android.camera.widget;
18166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
19166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport android.animation.Animator;
20166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport android.animation.ValueAnimator;
21166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport android.content.Context;
2243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kongimport android.graphics.Canvas;
2343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kongimport android.graphics.ColorFilter;
2443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kongimport android.graphics.Paint;
2543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kongimport android.graphics.PixelFormat;
2643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kongimport android.graphics.drawable.Drawable;
275052117cc429d85cf446421ca74859f4365747d3Angus Kongimport android.os.Handler;
285052117cc429d85cf446421ca74859f4365747d3Angus Kongimport android.os.Looper;
29166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport android.util.AttributeSet;
30166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport android.view.MotionEvent;
31166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport android.view.View;
32166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport android.widget.FrameLayout;
33166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
3401054e922aa547b937a71131ad04c6bd15356240Angus Kongimport com.android.camera.filmstrip.FilmstripContentPanel;
35faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kongimport com.android.camera.filmstrip.FilmstripController;
3601054e922aa547b937a71131ad04c6bd15356240Angus Kongimport com.android.camera.ui.FilmstripGestureRecognizer;
37166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kongimport com.android.camera2.R;
38166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
39166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong/**
40166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * A {@link android.widget.FrameLayout} used for the parent layout of a
4101054e922aa547b937a71131ad04c6bd15356240Angus Kong * {@link com.android.camera.widget.FilmstripView} to support animating in/out the
42166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * filmstrip.
43166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong */
4401054e922aa547b937a71131ad04c6bd15356240Angus Kongpublic class FilmstripLayout extends FrameLayout implements FilmstripContentPanel {
455b6502597edfd4658a937de2b5121dabf3510d52Angus Kong
46166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private static final long DEFAULT_DURATION_MS = 200;
47b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong
48b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong    /**
4901054e922aa547b937a71131ad04c6bd15356240Angus Kong     * The layout containing the {@link com.android.camera.widget.FilmstripView}
50b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong     * and other controls.
51b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong     */
52b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong    private FrameLayout mFilmstripContentLayout;
53166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private FilmstripView mFilmstripView;
54166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private FilmstripGestureRecognizer mGestureRecognizer;
55166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private FilmstripGestureRecognizer.Listener mFilmstripGestureListener;
56166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private final ValueAnimator mFilmstripAnimator = ValueAnimator.ofFloat(null);
57166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private int mSwipeTrend;
5843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    private MyBackgroundDrawable mBackgroundDrawable;
595052117cc429d85cf446421ca74859f4365747d3Angus Kong    private Handler mHandler;
606ae724120504967b1e37f7ae045134444013f00eAngus Kong    // We use this to record the current translation position instead of using
616ae724120504967b1e37f7ae045134444013f00eAngus Kong    // the real value because we might set the translation before onMeasure()
626ae724120504967b1e37f7ae045134444013f00eAngus Kong    // thus getMeasuredWidth() can be 0.
636ae724120504967b1e37f7ae045134444013f00eAngus Kong    private float mFilmstripContentTranslationProgress;
6443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
6543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    private Animator.AnimatorListener mFilmstripAnimatorListener = new Animator.AnimatorListener() {
6643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        private boolean mCanceled;
6743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
6843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
6943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void onAnimationStart(Animator animator) {
7043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mCanceled = false;
7143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
7243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
7343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
7443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void onAnimationEnd(Animator animator) {
7543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            if (!mCanceled) {
766ae724120504967b1e37f7ae045134444013f00eAngus Kong                if (mFilmstripContentTranslationProgress != 0f) {
77faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong                    mFilmstripView.getController().goToFilmstrip();
7843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                    setVisibility(INVISIBLE);
7943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                } else {
80faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong                    notifyShown();
8143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                }
8243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            }
8343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
8443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
8543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
8643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void onAnimationCancel(Animator animator) {
8743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mCanceled = true;
8843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
8943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
9043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
9143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void onAnimationRepeat(Animator animator) {
9243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            // Nothing.
9343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
9443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    };
9543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
9643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    private ValueAnimator.AnimatorUpdateListener mFilmstripAnimatorUpdateListener =
9743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            new ValueAnimator.AnimatorUpdateListener() {
9843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                @Override
9943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                public void onAnimationUpdate(ValueAnimator valueAnimator) {
1006ae724120504967b1e37f7ae045134444013f00eAngus Kong                    translateContentLayout((Float) valueAnimator.getAnimatedValue());
101ac53715b1ca6704eff7e1142d2d3896cc91b8424Angus Kong                    mBackgroundDrawable.invalidateSelf();
10243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                }
10343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            };
104faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong    private Listener mListener;
105166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
106166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public FilmstripLayout(Context context) {
107166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        super(context);
108166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        init(context);
109166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
110166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
111166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public FilmstripLayout(Context context, AttributeSet attrs) {
112166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        super(context, attrs);
113166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        init(context);
114166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
115166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
116166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public FilmstripLayout(Context context, AttributeSet attrs, int defStyle) {
117166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        super(context, attrs, defStyle);
118166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        init(context);
119166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
120166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
121166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private void init(Context context) {
122166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        mGestureRecognizer = new FilmstripGestureRecognizer(context, new MyGestureListener());
123166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        mFilmstripAnimator.setDuration(DEFAULT_DURATION_MS);
12443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        mFilmstripAnimator.addUpdateListener(mFilmstripAnimatorUpdateListener);
12543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        mFilmstripAnimator.addListener(mFilmstripAnimatorListener);
1265052117cc429d85cf446421ca74859f4365747d3Angus Kong        mHandler = new Handler(Looper.getMainLooper());
1275052117cc429d85cf446421ca74859f4365747d3Angus Kong        mBackgroundDrawable = new MyBackgroundDrawable();
1285052117cc429d85cf446421ca74859f4365747d3Angus Kong        mBackgroundDrawable.setCallback(new Drawable.Callback() {
1295052117cc429d85cf446421ca74859f4365747d3Angus Kong            @Override
1305052117cc429d85cf446421ca74859f4365747d3Angus Kong            public void invalidateDrawable(Drawable drawable) {
1315052117cc429d85cf446421ca74859f4365747d3Angus Kong                FilmstripLayout.this.invalidate();
1325052117cc429d85cf446421ca74859f4365747d3Angus Kong            }
1335052117cc429d85cf446421ca74859f4365747d3Angus Kong
1345052117cc429d85cf446421ca74859f4365747d3Angus Kong            @Override
1355052117cc429d85cf446421ca74859f4365747d3Angus Kong            public void scheduleDrawable(Drawable drawable, Runnable runnable, long l) {
1365052117cc429d85cf446421ca74859f4365747d3Angus Kong                mHandler.postAtTime(runnable, drawable, l);
1375052117cc429d85cf446421ca74859f4365747d3Angus Kong            }
1385052117cc429d85cf446421ca74859f4365747d3Angus Kong
1395052117cc429d85cf446421ca74859f4365747d3Angus Kong            @Override
1405052117cc429d85cf446421ca74859f4365747d3Angus Kong            public void unscheduleDrawable(Drawable drawable, Runnable runnable) {
1415052117cc429d85cf446421ca74859f4365747d3Angus Kong                mHandler.removeCallbacks(runnable, drawable);
1425052117cc429d85cf446421ca74859f4365747d3Angus Kong            }
1435052117cc429d85cf446421ca74859f4365747d3Angus Kong        });
1445052117cc429d85cf446421ca74859f4365747d3Angus Kong        setBackground(mBackgroundDrawable);
145166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
146166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
14701054e922aa547b937a71131ad04c6bd15356240Angus Kong    @Override
148faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong    public void setFilmstripListener(Listener listener) {
149faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        mListener = listener;
1506ae724120504967b1e37f7ae045134444013f00eAngus Kong        if (getVisibility() == VISIBLE && mFilmstripContentTranslationProgress == 0f) {
151faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong            notifyShown();
152faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        } else {
1535052117cc429d85cf446421ca74859f4365747d3Angus Kong            if (getVisibility() != VISIBLE) {
1545052117cc429d85cf446421ca74859f4365747d3Angus Kong                notifyHidden();
1555052117cc429d85cf446421ca74859f4365747d3Angus Kong            }
156faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        }
157faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        mFilmstripView.getController().setListener(listener);
158faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong    }
159faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong
160faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong    @Override
161b2510252fb020f3ccb88787c870930427377b9dfAngus Kong    public void hide() {
1626ae724120504967b1e37f7ae045134444013f00eAngus Kong        translateContentLayout(1f);
163b2510252fb020f3ccb88787c870930427377b9dfAngus Kong        mFilmstripAnimatorListener.onAnimationEnd(mFilmstripAnimator);
164b2510252fb020f3ccb88787c870930427377b9dfAngus Kong    }
165b2510252fb020f3ccb88787c870930427377b9dfAngus Kong
166b2510252fb020f3ccb88787c870930427377b9dfAngus Kong    @Override
167b2510252fb020f3ccb88787c870930427377b9dfAngus Kong    public void show() {
1686ae724120504967b1e37f7ae045134444013f00eAngus Kong        translateContentLayout(0f);
169b2510252fb020f3ccb88787c870930427377b9dfAngus Kong        mFilmstripAnimatorListener.onAnimationEnd(mFilmstripAnimator);
170b2510252fb020f3ccb88787c870930427377b9dfAngus Kong    }
171b2510252fb020f3ccb88787c870930427377b9dfAngus Kong
172b2510252fb020f3ccb88787c870930427377b9dfAngus Kong    @Override
173b2510252fb020f3ccb88787c870930427377b9dfAngus Kong    public void setVisibility(int visibility) {
174b2510252fb020f3ccb88787c870930427377b9dfAngus Kong        super.setVisibility(visibility);
1755052117cc429d85cf446421ca74859f4365747d3Angus Kong        if (visibility != VISIBLE) {
1765052117cc429d85cf446421ca74859f4365747d3Angus Kong            notifyHidden();
1775052117cc429d85cf446421ca74859f4365747d3Angus Kong        }
178faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong    }
179faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong
1805052117cc429d85cf446421ca74859f4365747d3Angus Kong    private void notifyHidden() {
181faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        if (mListener == null) {
182faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong            return;
183faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        }
1845052117cc429d85cf446421ca74859f4365747d3Angus Kong        mListener.onFilmstripHidden();
185faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong    }
186faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong
187faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong    private void notifyShown() {
188faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        if (mListener == null) {
189faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong            return;
190faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        }
191faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        mListener.onFilmstripShown();
192c8924b2ec3788ca6d0f0af5ca749e5fe7be125ceAndy Huibers        mFilmstripView.zoomAtIndexChanged();
193faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        FilmstripController controller = mFilmstripView.getController();
194faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        int currentId = controller.getCurrentId();
195faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        if (controller.inFilmstrip()) {
196faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong            mListener.onEnterFilmstrip(currentId);
197faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        } else if (controller.inFullScreen()) {
1984567160a43fa5787012bf0b618c216cf18ac0457Angus Kong            mListener.onEnterFullScreenUiShown(currentId);
199faaee012acc80ad369cb03df9c196e48140f1e7bAngus Kong        }
2005b6502597edfd4658a937de2b5121dabf3510d52Angus Kong    }
2015b6502597edfd4658a937de2b5121dabf3510d52Angus Kong
202166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    @Override
203166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public void onLayout(boolean changed, int l, int t, int r, int b) {
204166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        super.onLayout(changed, l, t, r, b);
205166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        if (changed && mFilmstripView != null && getVisibility() == INVISIBLE) {
206b2510252fb020f3ccb88787c870930427377b9dfAngus Kong            hide();
2076ae724120504967b1e37f7ae045134444013f00eAngus Kong        } else {
2086ae724120504967b1e37f7ae045134444013f00eAngus Kong            translateContentLayout(mFilmstripContentTranslationProgress);
209166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
210166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
211166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
212166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    @Override
213166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public boolean onTouchEvent(MotionEvent ev) {
214166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        return mGestureRecognizer.onTouchEvent(ev);
215166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
216166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
217166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    @Override
218166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public boolean onInterceptTouchEvent(MotionEvent ev) {
219166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
220166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            // TODO: Remove this after the touch flow refactor is done in
221166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            // MainAtivityLayout.
222166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            getParent().requestDisallowInterceptTouchEvent(true);
223166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
224166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        return false;
225166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
226166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
227166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    @Override
228166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public void onFinishInflate() {
229166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        mFilmstripView = (FilmstripView) findViewById(R.id.filmstrip_view);
230166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        mFilmstripView.setOnTouchListener(new OnTouchListener() {
23143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
232166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            @Override
233166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            public boolean onTouch(View view, MotionEvent motionEvent) {
23443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                // Adjust the coordinates back since they are relative to the
23543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                // child view.
2366ca4411fd938e935028f713c1f32ed8e274debd4Angus Kong                motionEvent.setLocation(motionEvent.getX() + mFilmstripContentLayout.getX(),
2376ca4411fd938e935028f713c1f32ed8e274debd4Angus Kong                        motionEvent.getY() + mFilmstripContentLayout.getY());
238166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                mGestureRecognizer.onTouchEvent(motionEvent);
239166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return true;
240166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
241166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        });
242166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        mFilmstripGestureListener = mFilmstripView.getGestureListener();
243b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong        mFilmstripContentLayout = (FrameLayout) findViewById(R.id.camera_filmstrip_content_layout);
244166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
245166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
24601054e922aa547b937a71131ad04c6bd15356240Angus Kong    @Override
247166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    public boolean onBackPressed() {
2481f9db2dfe59c33228103c54523281501ef52c9baAngus Kong        return animateHide();
2491f9db2dfe59c33228103c54523281501ef52c9baAngus Kong    }
2501f9db2dfe59c33228103c54523281501ef52c9baAngus Kong
2511f9db2dfe59c33228103c54523281501ef52c9baAngus Kong    @Override
2521f9db2dfe59c33228103c54523281501ef52c9baAngus Kong    public boolean animateHide() {
253166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        if (getVisibility() == VISIBLE) {
254166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            if (!mFilmstripAnimator.isRunning()) {
255166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                hideFilmstrip();
256166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
257166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return true;
258166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
259166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        return false;
260166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
261166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
262623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger    public void hideFilmstrip() {
263b7d0a227fb0f842135dbc92a7e15c571f0e1a946Spike Sprague        // run the same view show/hides and animations
264b7d0a227fb0f842135dbc92a7e15c571f0e1a946Spike Sprague        // that happen with a swipe gesture.
265b7d0a227fb0f842135dbc92a7e15c571f0e1a946Spike Sprague        onSwipeOutBegin();
2666ae724120504967b1e37f7ae045134444013f00eAngus Kong        runAnimation(mFilmstripContentTranslationProgress, 1f);
267166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
268166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
269623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger    public void showFilmstrip() {
270623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger        setVisibility(VISIBLE);
2716ae724120504967b1e37f7ae045134444013f00eAngus Kong        runAnimation(mFilmstripContentTranslationProgress, 0f);
27243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    }
27343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
27443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    private void runAnimation(float begin, float end) {
275166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        if (mFilmstripAnimator.isRunning()) {
27643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            return;
277166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
27843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        if (begin == end) {
27943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            // No need to start animation.
28043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mFilmstripAnimatorListener.onAnimationEnd(mFilmstripAnimator);
28143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            return;
28243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
28343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        mFilmstripAnimator.setFloatValues(begin, end);
284166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        mFilmstripAnimator.start();
285166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
286166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
2876ae724120504967b1e37f7ae045134444013f00eAngus Kong    private void translateContentLayout(float fraction) {
2886ae724120504967b1e37f7ae045134444013f00eAngus Kong        mFilmstripContentTranslationProgress = fraction;
2896ae724120504967b1e37f7ae045134444013f00eAngus Kong        mFilmstripContentLayout.setTranslationX(fraction * getMeasuredWidth());
2906ae724120504967b1e37f7ae045134444013f00eAngus Kong    }
2916ae724120504967b1e37f7ae045134444013f00eAngus Kong
2926ae724120504967b1e37f7ae045134444013f00eAngus Kong    private void translateContentLayoutByPixel(float pixel) {
2936ae724120504967b1e37f7ae045134444013f00eAngus Kong        mFilmstripContentLayout.setTranslationX(pixel);
2946ae724120504967b1e37f7ae045134444013f00eAngus Kong        mFilmstripContentTranslationProgress = pixel / getMeasuredWidth();
2956ae724120504967b1e37f7ae045134444013f00eAngus Kong    }
2966ae724120504967b1e37f7ae045134444013f00eAngus Kong
29773e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong    private void onSwipeOut() {
29873e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong        if (mListener != null) {
29973e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong            mListener.onSwipeOut();
30073e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong        }
30173e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong    }
30273e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong
30373e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong    private void onSwipeOutBegin() {
30473e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong        if (mListener != null) {
30573e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong            mListener.onSwipeOutBegin();
30673e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong        }
30773e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong    }
30873e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong
309166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    /**
310166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong     * A gesture listener which passes all the gestures to the
311166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong     * {@code mFilmstripView} by default and only intercepts scroll gestures
312166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong     * when the {@code mFilmstripView} is not in full-screen.
313166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong     */
314166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    private class MyGestureListener implements FilmstripGestureRecognizer.Listener {
315166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
316166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onScroll(float x, float y, float dx, float dy) {
317ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong            if (mFilmstripView.getController().getCurrentId() == -1) {
318ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong                return true;
319ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong            }
32043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            if (mFilmstripAnimator.isRunning()) {
32143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                return true;
32243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            }
3236ae724120504967b1e37f7ae045134444013f00eAngus Kong            if (mFilmstripContentLayout.getTranslationX() == 0f &&
324166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                    mFilmstripGestureListener.onScroll(x, y, dx, dy)) {
325166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return true;
326166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
32743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mSwipeTrend = (((int) dx) >> 1) + (mSwipeTrend >> 1);
32873e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong            if (dx < 0 && mFilmstripContentLayout.getTranslationX() == 0) {
32929d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd                mBackgroundDrawable.setOffset(0);
330af984b23a3140a16e5b0433dbb9693a076cfcf04Spike Sprague                FilmstripLayout.this.onSwipeOutBegin();
33173e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong            }
33229d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd
33329d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            // When we start translating the filmstrip in, we want the left edge of the
33429d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            // first view to always be at the rightmost edge of the screen so that it
33529d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            // appears instantly, regardless of the view's distance from the edge of the
33629d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            // filmstrip view. To do so, on our first translation, jump the filmstrip view
33729d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            // to the correct position, and then smoothly animate the translation from that
33829d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            // initial point.
33929d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            if (dx > 0 && mFilmstripContentLayout.getTranslationX() == getMeasuredWidth()) {
34029d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd                final int currentItemLeft = mFilmstripView.getCurrentItemLeft();
34129d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd                dx = currentItemLeft;
34229d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd                mBackgroundDrawable.setOffset(currentItemLeft);
34329d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            }
34429d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd
3456ae724120504967b1e37f7ae045134444013f00eAngus Kong            float translate = mFilmstripContentLayout.getTranslationX() - dx;
346166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            if (translate < 0f) {
347166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                translate = 0f;
348166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            } else {
349166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                if (translate > getMeasuredWidth()) {
350166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                    translate = getMeasuredWidth();
351166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                }
352166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
3536ae724120504967b1e37f7ae045134444013f00eAngus Kong            translateContentLayoutByPixel(translate);
35473e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong            if (translate == 0 && dx > 0) {
35573e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong                // This will only happen once since when this condition holds
35673e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong                // the onScroll() callback will be forwarded to the filmstrip
35773e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong                // view.
35873e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong                mFilmstripAnimatorListener.onAnimationEnd(mFilmstripAnimator);
35973e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong            }
360ac53715b1ca6704eff7e1142d2d3896cc91b8424Angus Kong            mBackgroundDrawable.invalidateSelf();
361166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return true;
362166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
363166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
364166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
365166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onSingleTapUp(float x, float y) {
3666ae724120504967b1e37f7ae045134444013f00eAngus Kong            if (mFilmstripContentTranslationProgress == 0f) {
367166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return mFilmstripGestureListener.onSingleTapUp(x, y);
368166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
369166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return false;
370166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
371166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
372166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
373166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onDoubleTap(float x, float y) {
3746ae724120504967b1e37f7ae045134444013f00eAngus Kong            if (mFilmstripContentTranslationProgress == 0f) {
375166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return mFilmstripGestureListener.onDoubleTap(x, y);
376166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
377166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return false;
378166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
379166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
380166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
381166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onFling(float velocityX, float velocityY) {
3826ae724120504967b1e37f7ae045134444013f00eAngus Kong            if (mFilmstripContentTranslationProgress == 0f) {
383166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return mFilmstripGestureListener.onFling(velocityX, velocityY);
384166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
385166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return false;
386166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
387166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
388166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
389166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onScaleBegin(float focusX, float focusY) {
3906ae724120504967b1e37f7ae045134444013f00eAngus Kong            if (mFilmstripContentTranslationProgress == 0f) {
391166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return mFilmstripGestureListener.onScaleBegin(focusX, focusY);
392166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
393166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return false;
394166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
395166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
396166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
397166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onScale(float focusX, float focusY, float scale) {
3986ae724120504967b1e37f7ae045134444013f00eAngus Kong            if (mFilmstripContentTranslationProgress == 0f) {
399166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return mFilmstripGestureListener.onScale(focusX, focusY, scale);
400166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
401166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return false;
402166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
403166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
404166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
405166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onDown(float x, float y) {
406b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong            if (mFilmstripContentLayout.getTranslationX() == 0f) {
407166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return mFilmstripGestureListener.onDown(x, y);
408166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
409166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return false;
410166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
411166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
412166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
413166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        public boolean onUp(float x, float y) {
414b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong            if (mFilmstripContentLayout.getTranslationX() == 0f) {
415166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                return mFilmstripGestureListener.onUp(x, y);
416166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
417166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            if (mSwipeTrend < 0) {
418166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                hideFilmstrip();
41973e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong                onSwipeOut();
420ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong            } else if (mSwipeTrend > 0) {
421166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                showFilmstrip();
422ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong            } else {
423b2510252fb020f3ccb88787c870930427377b9dfAngus Kong                if (mFilmstripContentLayout.getTranslationX() >= getMeasuredWidth() / 2) {
424ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong                    hideFilmstrip();
42573e09f39f7d4075f3c95d20bb229f354211d05c0Angus Kong                    onSwipeOut();
426ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong                } else {
427ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong                    showFilmstrip();
428ec2fb473c094f8dfd1cc0cf5205d470e412d3919Angus Kong                }
429166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
430166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            mSwipeTrend = 0;
431166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            return false;
432166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
433166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong
434166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        @Override
43526795a9258c0815ca2a92d2c660438066f001022Angus Kong        public void onLongPress(float x, float y) {
43626795a9258c0815ca2a92d2c660438066f001022Angus Kong            mFilmstripGestureListener.onLongPress(x, y);
43726795a9258c0815ca2a92d2c660438066f001022Angus Kong        }
43826795a9258c0815ca2a92d2c660438066f001022Angus Kong
43926795a9258c0815ca2a92d2c660438066f001022Angus Kong        @Override
44043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void onScaleEnd() {
441b95699ed89d02a465950c48ea9b6147d90c80389Angus Kong            if (mFilmstripContentLayout.getTranslationX() == 0f) {
442166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong                mFilmstripGestureListener.onScaleEnd();
443166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong            }
444166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong        }
445166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong    }
44643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
44743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    private class MyBackgroundDrawable extends Drawable {
44843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        private Paint mPaint;
44929d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd        private int mOffset;
45043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
45143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public MyBackgroundDrawable() {
45243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mPaint = new Paint();
453919bea1a10464f23aeb090a254ff36169d012e9aSpike Sprague            mPaint.setAntiAlias(true);
454919bea1a10464f23aeb090a254ff36169d012e9aSpike Sprague            mPaint.setColor(getResources().getColor(R.color.filmstrip_background));
45543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mPaint.setAlpha(255);
45643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
45743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
45829d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd        /**
45929d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd         * Adjust the target width and translation calculation when we start translating
46029d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd         * from a point where width != translationX so that alpha scales smoothly.
46129d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd         */
46229d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd        public void setOffset(int offset) {
46329d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            mOffset = offset;
46429d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd        }
46529d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd
46643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
46743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void setAlpha(int i) {
46843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mPaint.setAlpha(i);
46943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
47043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
471919bea1a10464f23aeb090a254ff36169d012e9aSpike Sprague        private void setAlpha(float a) {
472919bea1a10464f23aeb090a254ff36169d012e9aSpike Sprague            setAlpha((int) (a*255.0f));
473919bea1a10464f23aeb090a254ff36169d012e9aSpike Sprague        }
474919bea1a10464f23aeb090a254ff36169d012e9aSpike Sprague
47543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
47643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void setColorFilter(ColorFilter colorFilter) {
47743596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            mPaint.setColorFilter(colorFilter);
47843596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
47943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
48043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
48143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public int getOpacity() {
48243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            return PixelFormat.TRANSLUCENT;
48343596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
48443596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
48543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        @Override
48643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        public void draw(Canvas canvas) {
48729d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            int width = getMeasuredWidth() - mOffset;
48829d9b3cd08a7b31b8ccecf4792d5ae981faa205cSam Judd            float translation = mFilmstripContentLayout.getTranslationX() - mOffset;
48943596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            if (translation == width) {
49043596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong                return;
49143596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong            }
49243596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong
4933088f90d01e169c7b2ee626069a8714f695436f5Spike Sprague            setAlpha(1.0f - mFilmstripContentTranslationProgress);
4943088f90d01e169c7b2ee626069a8714f695436f5Spike Sprague            canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
49543596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong        }
49643596cd34e7020d6a0aafcdc31297237ad98496cAngus Kong    }
497166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong}
498