AdapterViewAnimator.java revision 3db40678d33c2b5f90c380966d36b3e10ed11f05
13db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen/*
23db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Copyright (C) 2010 The Android Open Source Project
33db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
43db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Licensed under the Apache License, Version 2.0 (the "License");
53db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * you may not use this file except in compliance with the License.
63db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * You may obtain a copy of the License at
73db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
83db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *      http://www.apache.org/licenses/LICENSE-2.0
93db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Unless required by applicable law or agreed to in writing, software
113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * distributed under the License is distributed on an "AS IS" BASIS,
123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * See the License for the specific language governing permissions and
143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * limitations under the License.
153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen */
163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenpackage android.widget;
183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.Context;
203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.Intent;
213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.content.res.TypedArray;
223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.os.Handler;
233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.os.Looper;
243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.util.AttributeSet;
253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.util.Log;
263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.view.View;
273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.view.animation.Animation;
283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenimport android.view.animation.AnimationUtils;
293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen/**
313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * Base class for a {@link AdapterView} that will perform animations
323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * when switching between its views.
333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen *
343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewAnimator_inAnimation
353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewAnimator_outAnimation
363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen * @attr ref android.R.styleable#AdapterViewAnimator_animateFirstView
373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen */
383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohenpublic class AdapterViewAnimator extends AdapterView<Adapter> implements RemoteViewsAdapter.RemoteAdapterConnectionCallback{
393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private static final String TAG = "RemoteViewAnimator";
403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    int mWhichChild = 0;
423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    boolean mFirstTime = true;
433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    boolean mAnimateFirstTime = true;
443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    AdapterDataSetObserver mDataSetObserver;
463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    View mPreviousView;
483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    View mCurrentView;
493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    Animation mInAnimation;
513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    Animation mOutAnimation;
523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    Adapter mAdapter;
533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    RemoteViewsAdapter mRemoteViewsAdapter;
543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private Handler mMainQueue;
553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewAnimator(Context context) {
573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super(context);
583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        initViewAnimator(context, null);
593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public AdapterViewAnimator(Context context, AttributeSet attrs) {
623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        super(context, attrs);
633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ViewAnimator);
653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        int resource = a.getResourceId(com.android.internal.R.styleable.ViewAnimator_inAnimation, 0);
663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (resource > 0) {
673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            setInAnimation(context, resource);
683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        resource = a.getResourceId(com.android.internal.R.styleable.ViewAnimator_outAnimation, 0);
713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (resource > 0) {
723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            setOutAnimation(context, resource);
733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        boolean flag = a.getBoolean(com.android.internal.R.styleable.ViewAnimator_animateFirstView, true);
763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        setAnimateFirstView(flag);
773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        a.recycle();
793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        initViewAnimator(context, attrs);
813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Initialize this {@link AdapterViewAnimator}
853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private void initViewAnimator(Context context, AttributeSet attrs) {
873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mMainQueue = new Handler(Looper.myLooper());
883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Sets which child view will be displayed.
923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param whichChild the index of the child view to display
943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setDisplayedChild(int whichChild) {
963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mAdapter != null) {
973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mWhichChild = whichChild;
983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (whichChild >= mAdapter.getCount()) {
993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mWhichChild = 0;
1003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else if (whichChild < 0) {
1013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mWhichChild = mAdapter.getCount() - 1;
1023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
1033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            boolean hasFocus = getFocusedChild() != null;
1053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // This will clear old focus if we had it
1063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            showOnly(mWhichChild);
1073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (hasFocus) {
1083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // Try to retake focus if we had it
1093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                requestFocus(FOCUS_FORWARD);
1103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
1113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
1123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Return default inAnimation. To be overriden by subclasses.
1163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public Animation getDefaultInAnimation() {
1183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return null;
1193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Return default outAnimation. To be overriden by subclasses.
1233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public Animation getDefaultOutAnimation() {
1253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return null;
1263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns the index of the currently displayed child view.
1303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public int getDisplayedChild() {
1323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mWhichChild;
1333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Manually shows the next child.
1373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void showNext() {
1393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        setDisplayedChild(mWhichChild + 1);
1403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Manually shows the previous child.
1443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void showPrevious() {
1463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        setDisplayedChild(mWhichChild - 1);
1473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
1503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Shows only the specified child. The other displays Views exit the screen,
1513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * optionally with the with the {@link #getOutAnimation() out animation} and
1523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * the specified child enters the screen, optionally with the
1533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * {@link #getInAnimation() in animation}.
1543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
1553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param childIndex The index of the child to be shown.
1563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param animate Whether or not to use the in and out animations, defaults
1573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *            to true.
1583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
1593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    void showOnly(int childIndex, boolean animate) {
1603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        showOnly(childIndex, animate, false);
1613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    private LayoutParams makeLayoutParams() {
1643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        int width = mMeasuredWidth - mPaddingLeft - mPaddingRight;
1653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        int height = mMeasuredHeight - mPaddingTop - mPaddingBottom;
1663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return new LayoutParams(width, height);
1673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
1683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void showOnly(int childIndex, boolean animate, boolean onLayout) {
1703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mAdapter != null) {
1713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // The previous view should be removed from the ViewGroup
1723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (mPreviousView != null) {
1733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mPreviousView.clearAnimation();
1743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // TODO: this is where we would store the the view for
1763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // recycling
1773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                removeViewInLayout(mPreviousView);
1783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
1793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // If the current view is still being animated, we should
1813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // force the animation to end
1823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (mCurrentView != null) {
1833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mCurrentView.clearAnimation();
1843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
1853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // load the new mCurrentView from our adapter
1873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mPreviousView = mCurrentView;
1883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mCurrentView = mAdapter.getView(childIndex, null, this);
1893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (mPreviousView != mCurrentView) {
1903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                addViewInLayout(mCurrentView, 0, makeLayoutParams(), true);
1913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mCurrentView.bringToFront();
1923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
1933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
1963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // Animate as necessary
1973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (mPreviousView != null && mPreviousView != mCurrentView) {
1983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                if (animate && mOutAnimation != null) {
1993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    mPreviousView.startAnimation(mOutAnimation);
2003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                }
2013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // This line results in the view becoming invisible *after*
2023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // the above animation is complete, or, if there is no animation
2033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // then it becomes invisble immediately
2043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mPreviousView.setVisibility(View.GONE);
2053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (mCurrentView != null && animate && mInAnimation != null) {
2083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mCurrentView.startAnimation(mInAnimation);
2093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mFirstTime = false;
2123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (!onLayout) {
2133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                requestLayout();
2143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                invalidate();
2153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            } else {
2163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // If the Adapter tries to layout the current view when we get it using getView above
2173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // the layout will end up being ignored since we are currently laying out, so
2183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                // we post a delayed requestLayout and invalidate
2193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mMainQueue.post(new Runnable() {
2203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    @Override
2213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    public void run() {
2223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                        mCurrentView.requestLayout();
2233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                        mCurrentView.invalidate();
2243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    }
2253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                });
2263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
2273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
2313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
2323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        boolean dataChanged = mDataChanged;
2333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (dataChanged) {
2343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            handleDataChanged();
2353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // if the data changes, mWhichChild might be out of the bounds of the adapter
2373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            // in this case, we reset mWhichChild to the beginning
2383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (mWhichChild >= mAdapter.getCount())
2393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mWhichChild = 0;
2403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            showOnly(mWhichChild, true, true);
2423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        final int childCount = getChildCount();
2453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        for (int i = 0; i < childCount; i++) {
2463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            final View child = getChildAt(i);
2473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            int childRight = mPaddingLeft + child.getMeasuredWidth();
2493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            int childBottom = mPaddingTop + child.getMeasuredHeight();
2503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            child.layout(mPaddingLeft, mPaddingTop, childRight, childBottom);
2523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mDataChanged = false;
2553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
2583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
2593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        final int count = getChildCount();
2603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
2623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
2633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        Log.v(TAG, "onMeasure");
2653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        for (int i = 0; i < count; i++) {
2673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            final View child = getChildAt(i);
2683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
2703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            lp.width = widthSpecSize - mPaddingLeft - mPaddingRight;
2723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            lp.height = heightSpecSize - mPaddingTop - mPaddingBottom;
2733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width,
2753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    MeasureSpec.EXACTLY);
2763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
2773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                    MeasureSpec.EXACTLY);
2783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            child.measure(childWidthMeasureSpec, childheightMeasureSpec);
2803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
2813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        setMeasuredDimension(widthSpecSize, heightSpecSize);
2833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Shows only the specified child. The other displays Views exit the screen
2873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * with the {@link #getOutAnimation() out animation} and the specified child
2883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * enters the screen with the {@link #getInAnimation() in animation}.
2893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
2903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param childIndex The index of the child to be shown.
2913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
2923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    void showOnly(int childIndex) {
2933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        final boolean animate = (!mFirstTime || mAnimateFirstTime);
2943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        showOnly(childIndex, animate);
2953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
2963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
2973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
2983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns the View corresponding to the currently displayed child.
2993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @return The View currently displayed.
3013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #getDisplayedChild()
3033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public View getCurrentView() {
3053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mCurrentView;
3063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
3093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns the current animation used to animate a View that enters the screen.
3103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @return An Animation or null if none is set.
3123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setInAnimation(android.view.animation.Animation)
3143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setInAnimation(android.content.Context, int)
3153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public Animation getInAnimation() {
3173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mInAnimation;
3183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
3213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Specifies the animation used to animate a View that enters the screen.
3223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param inAnimation The animation started when a View enters the screen.
3243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #getInAnimation()
3263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setInAnimation(android.content.Context, int)
3273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setInAnimation(Animation inAnimation) {
3293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mInAnimation = inAnimation;
3303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
3333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Returns the current animation used to animate a View that exits the screen.
3343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @return An Animation or null if none is set.
3363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setOutAnimation(android.view.animation.Animation)
3383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setOutAnimation(android.content.Context, int)
3393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public Animation getOutAnimation() {
3413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mOutAnimation;
3423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
3453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Specifies the animation used to animate a View that exit the screen.
3463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param outAnimation The animation started when a View exit the screen.
3483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #getOutAnimation()
3503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setOutAnimation(android.content.Context, int)
3513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setOutAnimation(Animation outAnimation) {
3533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mOutAnimation = outAnimation;
3543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3563db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
3573db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Specifies the animation used to animate a View that enters the screen.
3583db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3593db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param context The application's environment.
3603db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param resourceID The resource id of the animation.
3613db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3623db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #getInAnimation()
3633db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setInAnimation(android.view.animation.Animation)
3643db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3653db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setInAnimation(Context context, int resourceID) {
3663db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        setInAnimation(AnimationUtils.loadAnimation(context, resourceID));
3673db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3683db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3693db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
3703db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Specifies the animation used to animate a View that exit the screen.
3713db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3723db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param context The application's environment.
3733db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param resourceID The resource id of the animation.
3743db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3753db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #getOutAnimation()
3763db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @see #setOutAnimation(android.view.animation.Animation)
3773db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3783db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setOutAnimation(Context context, int resourceID) {
3793db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        setOutAnimation(AnimationUtils.loadAnimation(context, resourceID));
3803db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3813db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3823db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
3833db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Indicates whether the current View should be animated the first time
3843db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * the ViewAnimation is displayed.
3853db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *
3863db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param animate True to animate the current View the first time it is displayed,
3873db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     *                false otherwise.
3883db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
3893db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAnimateFirstView(boolean animate) {
3903db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAnimateFirstTime = animate;
3913db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3923db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3933db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
3943db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public int getBaseline() {
3953db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return (getCurrentView() != null) ? getCurrentView().getBaseline() : super.getBaseline();
3963db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
3973db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
3983db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
3993db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public Adapter getAdapter() {
4003db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mAdapter;
4013db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
4023db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4033db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
4043db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setAdapter(Adapter adapter) {
4053db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mAdapter = adapter;
4063db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4073db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mAdapter != null) {
4083db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            if (mDataSetObserver != null) {
4093db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen                mAdapter.unregisterDataSetObserver(mDataSetObserver);
4103db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            }
4113db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4123db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mDataSetObserver = new AdapterDataSetObserver();
4133db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mAdapter.registerDataSetObserver(mDataSetObserver);
4143db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
4153db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
4163db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4173db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
4183db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Sets up this AdapterViewAnimator to use a remote views adapter which connects to a RemoteViewsService
4193db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * through the specified intent.
4203db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
4213db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
4223db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @android.view.RemotableViewMethod
4233db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setRemoteViewsAdapter(Intent intent) {
4243db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        mRemoteViewsAdapter = new RemoteViewsAdapter(getContext(), intent, this);
4253db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
4263db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4273db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
4283db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void setSelection(int position) {
4293db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        setDisplayedChild(position);
4303db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
4313db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4323db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    @Override
4333db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public View getSelectedView() {
4343db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        return mCurrentView;
4353db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
4363db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4373db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
4383db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Called back when the adapter connects to the RemoteViewsService.
4393db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
4403db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void onRemoteAdapterConnected() {
4413db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mRemoteViewsAdapter != mAdapter) {
4423db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            setAdapter(mRemoteViewsAdapter);
4433db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
4443db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
4453db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen
4463db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    /**
4473db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     * Called back when the adapter disconnects from the RemoteViewsService.
4483db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen     */
4493db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    public void onRemoteAdapterDisconnected() {
4503db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        if (mRemoteViewsAdapter != mAdapter) {
4513db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            mRemoteViewsAdapter = null;
4523db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen            setAdapter(mRemoteViewsAdapter);
4533db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen        }
4543db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen    }
4553db40678d33c2b5f90c380966d36b3e10ed11f05Adam Cohen}
456