PreviewPagerAdapter.java revision 74df3ec00247ea18ccf43c466e26dfe1a4622162
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.settings;
17
18import android.content.Context;
19import android.content.res.Configuration;
20import android.support.v4.view.PagerAdapter;
21import android.view.LayoutInflater;
22import android.view.View;
23import android.view.ViewGroup;
24import android.view.animation.AccelerateInterpolator;
25import android.view.animation.DecelerateInterpolator;
26import android.view.animation.Interpolator;
27import android.widget.FrameLayout;
28import android.widget.LinearLayout;
29import android.widget.ScrollView;
30
31/**
32 * A PagerAdapter used by PreviewSeekBarPreferenceFragment that for showing multiple preview screen
33 * regarding a single setting and allowing the user to swipe across them.
34 */
35public class PreviewPagerAdapter extends PagerAdapter {
36
37    private FrameLayout[] mPreviewFrames;
38
39    /** Duration to use when cross-fading between previews. */
40    private static final long CROSS_FADE_DURATION_MS = 400;
41
42    /** Interpolator to use when cross-fading between previews. */
43    private static final Interpolator FADE_IN_INTERPOLATOR = new DecelerateInterpolator();
44
45    /** Interpolator to use when cross-fading between previews. */
46    private static final Interpolator FADE_OUT_INTERPOLATOR = new AccelerateInterpolator();
47
48    public PreviewPagerAdapter(Context context, int[] previewSampleResIds,
49                               Configuration[] configurations) {
50        mPreviewFrames = new FrameLayout[previewSampleResIds.length];
51
52        // We need to get the copy of the original configuration before we call
53        // createConfigurationContext() as that call changes the current configuration for the App.
54        final Configuration origConfig = context.getResources().getConfiguration();
55
56        for (int i = 0; i < previewSampleResIds.length; ++i) {
57            mPreviewFrames[i] = new FrameLayout(context);
58            mPreviewFrames[i].setLayoutParams(new LinearLayout.LayoutParams(
59                    LinearLayout.LayoutParams.MATCH_PARENT,
60                    LinearLayout.LayoutParams.MATCH_PARENT));
61            mPreviewFrames[i].setContentDescription(
62                    context.getString(R.string.preview_page_indicator_content_description, i + 1,
63                            previewSampleResIds.length));
64
65            for (Configuration configuration : configurations) {
66                // Create a new configuration for the specified value. It won't
67                // have any theme set, so manually apply the current theme.
68                final Context configContext = context.createConfigurationContext(configuration);
69                configContext.setTheme(context.getThemeResId());
70
71                final LayoutInflater configInflater = LayoutInflater.from(configContext);
72                final View sampleView = configInflater.inflate(previewSampleResIds[i],
73                        mPreviewFrames[i], false);
74                sampleView.setAlpha(0);
75                sampleView.setVisibility(View.INVISIBLE);
76                mPreviewFrames[i].addView(sampleView);
77            }
78        }
79
80        // Create a context with the original App configuration since the last configuration passed
81        // to createConfigurationContext() becomes the configuration for any new views inflated.
82        context.createConfigurationContext(origConfig);
83    }
84
85    @Override
86    public void destroyItem (ViewGroup container, int position, Object object) {
87        container.removeView((View) object);
88    }
89
90    @Override
91    public int getCount() {
92        return mPreviewFrames.length;
93    }
94
95    @Override
96    public Object instantiateItem(ViewGroup container, int position) {
97        container.addView(mPreviewFrames[position]);
98        return mPreviewFrames[position];
99    }
100
101    @Override
102    public boolean isViewFromObject(View view, Object object) {
103        return (view == object);
104    }
105
106    void setPreviewLayer(int newIndex, int currentIndex, int currentItem, boolean animate) {
107        for (FrameLayout previewFrame : mPreviewFrames) {
108            if (currentIndex >= 0) {
109                final View lastLayer = previewFrame.getChildAt(currentIndex);
110                if (animate && previewFrame == mPreviewFrames[currentItem]) {
111                    lastLayer.animate()
112                            .alpha(0)
113                            .setInterpolator(FADE_OUT_INTERPOLATOR)
114                            .setDuration(CROSS_FADE_DURATION_MS)
115                            .withEndAction(new Runnable() {
116                                @Override
117                                public void run() {
118                                    lastLayer.setVisibility(View.INVISIBLE);
119                                }
120                            });
121                } else {
122                    lastLayer.setAlpha(0);
123                    lastLayer.setVisibility(View.INVISIBLE);
124                }
125            }
126
127            final View nextLayer = previewFrame.getChildAt(newIndex);
128            if (animate && previewFrame == mPreviewFrames[currentItem]) {
129                nextLayer.animate()
130                        .alpha(1)
131                        .setInterpolator(FADE_IN_INTERPOLATOR)
132                        .setDuration(CROSS_FADE_DURATION_MS)
133                        .withStartAction(new Runnable() {
134                            @Override
135                            public void run() {
136                                nextLayer.setVisibility(View.VISIBLE);
137                            }
138                        });
139            } else {
140                nextLayer.setVisibility(View.VISIBLE);
141                nextLayer.setAlpha(1);
142            }
143        }
144    }
145}
146