1 /*
2  * Copyright (C) 2014 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  */
16 
17 package com.example.android.wearable.gridviewpager;
18 
19 import android.app.Fragment;
20 import android.app.FragmentManager;
21 import android.content.Context;
22 import android.content.res.Resources;
23 import android.graphics.Point;
24 import android.graphics.drawable.ColorDrawable;
25 import android.graphics.drawable.Drawable;
26 import android.graphics.drawable.TransitionDrawable;
27 import android.os.AsyncTask;
28 import android.support.v4.util.LruCache;
29 import android.support.wearable.view.CardFragment;
30 import android.support.wearable.view.FragmentGridPagerAdapter;
31 import android.support.wearable.view.GridPagerAdapter;
32 import android.util.Log;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 /**
38  * Constructs fragments as requested by the GridViewPager. For each row a different background is
39  * provided.
40  * <p>
41  * Always avoid loading resources from the main thread. In this sample, the background images are
42  * loaded from an background task and then updated using {@link #notifyRowBackgroundChanged(int)}
43  * and {@link #notifyPageBackgroundChanged(int, int)}.
44  */
45 public class SampleGridPagerAdapter extends FragmentGridPagerAdapter {
46     private static final int TRANSITION_DURATION_MILLIS = 100;
47 
48     private final Context mContext;
49     private List<Row> mRows;
50     private ColorDrawable mDefaultBg;
51 
52     private ColorDrawable mClearBg;
53 
SampleGridPagerAdapter(Context ctx, FragmentManager fm)54     public SampleGridPagerAdapter(Context ctx, FragmentManager fm) {
55         super(fm);
56         mContext = ctx;
57 
58         mRows = new ArrayList<SampleGridPagerAdapter.Row>();
59 
60         mRows.add(new Row(cardFragment(R.string.welcome_title, R.string.welcome_text)));
61         mRows.add(new Row(cardFragment(R.string.about_title, R.string.about_text)));
62         mRows.add(new Row(
63                 cardFragment(R.string.cards_title, R.string.cards_text),
64                 cardFragment(R.string.expansion_title, R.string.expansion_text)));
65         mRows.add(new Row(
66                 cardFragment(R.string.backgrounds_title, R.string.backgrounds_text),
67                 cardFragment(R.string.columns_title, R.string.columns_text)));
68         mRows.add(new Row(new CustomFragment()));
69         mRows.add(new Row(cardFragment(R.string.dismiss_title, R.string.dismiss_text)));
70         mDefaultBg = new ColorDrawable(R.color.dark_grey);
71         mClearBg = new ColorDrawable(android.R.color.transparent);
72     }
73 
74     LruCache<Integer, Drawable> mRowBackgrounds = new LruCache<Integer, Drawable>(3) {
75         @Override
76         protected Drawable create(final Integer row) {
77             int resid = BG_IMAGES[row % BG_IMAGES.length];
78             new DrawableLoadingTask(mContext) {
79                 @Override
80                 protected void onPostExecute(Drawable result) {
81                     TransitionDrawable background = new TransitionDrawable(new Drawable[] {
82                             mDefaultBg,
83                             result
84                     });
85                     mRowBackgrounds.put(row, background);
86                     notifyRowBackgroundChanged(row);
87                     background.startTransition(TRANSITION_DURATION_MILLIS);
88                 }
89             }.execute(resid);
90             return mDefaultBg;
91         }
92     };
93 
94     LruCache<Point, Drawable> mPageBackgrounds = new LruCache<Point, Drawable>(3) {
95         @Override
96         protected Drawable create(final Point page) {
97             // place bugdroid as the background at row 2, column 1
98             if (page.y == 2 && page.x == 1) {
99                 int resid = R.drawable.bugdroid_large;
100                 new DrawableLoadingTask(mContext) {
101                     @Override
102                     protected void onPostExecute(Drawable result) {
103                         TransitionDrawable background = new TransitionDrawable(new Drawable[] {
104                                 mClearBg,
105                                 result
106                         });
107                         mPageBackgrounds.put(page, background);
108                         notifyPageBackgroundChanged(page.y, page.x);
109                         background.startTransition(TRANSITION_DURATION_MILLIS);
110                     }
111                 }.execute(resid);
112             }
113             return GridPagerAdapter.BACKGROUND_NONE;
114         }
115     };
116 
cardFragment(int titleRes, int textRes)117     private Fragment cardFragment(int titleRes, int textRes) {
118         Resources res = mContext.getResources();
119         CardFragment fragment =
120                 CardFragment.create(res.getText(titleRes), res.getText(textRes));
121         // Add some extra bottom margin to leave room for the page indicator
122         fragment.setCardMarginBottom(
123                 res.getDimensionPixelSize(R.dimen.card_margin_bottom));
124         return fragment;
125     }
126 
127     static final int[] BG_IMAGES = new int[] {
128             R.drawable.debug_background_1,
129             R.drawable.debug_background_2,
130             R.drawable.debug_background_3,
131             R.drawable.debug_background_4,
132             R.drawable.debug_background_5
133     };
134 
135     /** A convenient container for a row of fragments. */
136     private class Row {
137         final List<Fragment> columns = new ArrayList<Fragment>();
138 
Row(Fragment... fragments)139         public Row(Fragment... fragments) {
140             for (Fragment f : fragments) {
141                 add(f);
142             }
143         }
144 
add(Fragment f)145         public void add(Fragment f) {
146             columns.add(f);
147         }
148 
getColumn(int i)149         Fragment getColumn(int i) {
150             return columns.get(i);
151         }
152 
getColumnCount()153         public int getColumnCount() {
154             return columns.size();
155         }
156     }
157 
158     @Override
getFragment(int row, int col)159     public Fragment getFragment(int row, int col) {
160         Row adapterRow = mRows.get(row);
161         return adapterRow.getColumn(col);
162     }
163 
164     @Override
getBackgroundForRow(final int row)165     public Drawable getBackgroundForRow(final int row) {
166         return mRowBackgrounds.get(row);
167     }
168 
169     @Override
getBackgroundForPage(final int row, final int column)170     public Drawable getBackgroundForPage(final int row, final int column) {
171         return mPageBackgrounds.get(new Point(column, row));
172     }
173 
174     @Override
getRowCount()175     public int getRowCount() {
176         return mRows.size();
177     }
178 
179     @Override
getColumnCount(int rowNum)180     public int getColumnCount(int rowNum) {
181         return mRows.get(rowNum).getColumnCount();
182     }
183 
184     class DrawableLoadingTask extends AsyncTask<Integer, Void, Drawable> {
185         private static final String TAG = "Loader";
186         private Context context;
187 
DrawableLoadingTask(Context context)188         DrawableLoadingTask(Context context) {
189             this.context = context;
190         }
191 
192         @Override
doInBackground(Integer... params)193         protected Drawable doInBackground(Integer... params) {
194             Log.d(TAG, "Loading asset 0x" + Integer.toHexString(params[0]));
195             return context.getResources().getDrawable(params[0]);
196         }
197     }
198 }
199