1ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes/*
2ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Copyright (C) 2014 The Android Open Source Project
3ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *
4ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
5ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * you may not use this file except in compliance with the License.
6ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * You may obtain a copy of the License at
7ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *
8ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
9ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *
10ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Unless required by applicable law or agreed to in writing, software
11ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
12ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * See the License for the specific language governing permissions and
14ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * limitations under the License.
15ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes */
16ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
17ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banespackage com.example.android.supportv7.graphics;
18ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
19ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport com.example.android.supportv7.R;
2044d25261c2a38c81f1eea123de3986b453b9afeeChris Banes
21ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.graphics.Bitmap;
22ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.net.Uri;
23ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.os.Bundle;
2444d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.app.AppCompatActivity;
25ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.support.v7.graphics.Palette;
26ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.Menu;
27ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.MenuItem;
28ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.View;
29ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.ViewGroup;
30ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.AdapterView;
31ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.BaseAdapter;
32ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.GridView;
33ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.ImageView;
34ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.Toast;
35ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
36ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport java.util.List;
37ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
38ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes/**
39ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Activity which displays the more details about a generated {@link Palette} for a specific
40ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * {@link android.provider.MediaStore} image.
41ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *
42ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Displays the full generated palette of colors in a grid, which allows clicking on an palette item
43ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * to display more information in a {@link Toast}.
44ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *
45ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Also allows the customization of the number of colors used in the palette generation for
46ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * demonstration purposes.
47ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes */
4844d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class PaletteDetailActivity extends AppCompatActivity {
49ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
50ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private ImageView mImageView;
51ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private GridView mGridView;
52ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private SwatchesPalette mSwatchesPalette;
53ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
54ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private Uri mImageUri;
55ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
56ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private Toast mCurrentToast;
57ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
58ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    @Override
59ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    protected void onCreate(Bundle savedInstanceState) {
60ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        super.onCreate(savedInstanceState);
61ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setContentView(R.layout.palette_activity_detail);
62ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
63ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mImageUri = getIntent().getData();
64ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
65ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mImageView = (ImageView) findViewById(R.id.image);
66ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mGridView = (GridView) findViewById(R.id.palette);
67ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mSwatchesPalette = new SwatchesPalette();
68ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mGridView.setAdapter(mSwatchesPalette);
69ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
70ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        // Set an OnItemClickListener to display a information Toast when a Palette item is clicked
71ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
72ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            @Override
73ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) {
74ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                // Cancel the current Toast if there is already one being displayed
75ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                if (mCurrentToast != null) {
76ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                    mCurrentToast.cancel();
77ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                }
78ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
79ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                final Palette.Swatch item = (Palette.Swatch) adapterView.getItemAtPosition(pos);
80ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                mCurrentToast = Toast.makeText(PaletteDetailActivity.this,
81ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                        item.toString(), Toast.LENGTH_LONG);
82ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                mCurrentToast.show();
83ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            }
84ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        });
85ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
86ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        // Load the image with a default number of colors
87ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        loadImage(16);
88ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
89ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
90ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    @Override
91ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    public boolean onCreateOptionsMenu(Menu menu) {
92ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        getMenuInflater().inflate(R.menu.sample_palette_actions, menu);
93ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        return true;
94ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
95ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
96ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    @Override
97ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    public boolean onOptionsItemSelected(MenuItem item) {
98ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        switch (item.getItemId()) {
99ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_8:
100ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(8);
101ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
102ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
103ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_12:
104ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(12);
105ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
106ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
107ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_16:
108ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(16);
109ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
110ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
111ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_24:
112ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(24);
113ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
114ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
115ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_32:
116ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(32);
117ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
118ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
119ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
120ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        return super.onOptionsItemSelected(item);
121ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
122ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
123ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private void loadImage(final int numColors) {
124ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        final int id = Integer.parseInt(mImageUri.getLastPathSegment());
125ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
126ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        ImageLoader.loadMediaStoreThumbnail(mImageView, id, new ImageLoader.Listener() {
127ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            @Override
128ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            public void onImageLoaded(Bitmap bitmap) {
129e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                new Palette.Builder(bitmap).maximumColorCount(numColors).generate(
130e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                        new Palette.PaletteAsyncListener() {
131e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                            @Override
132e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                            public void onGenerated(Palette palette) {
133e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                                populatePalette(palette);
134e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                            }
135e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                        });
136ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            }
137ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        });
138ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
139ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
140ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private class SwatchesPalette extends BaseAdapter {
141ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
142ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        private List<Palette.Swatch> mSwatches;
143ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
144ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
145ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public int getCount() {
146ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return mSwatches != null ? mSwatches.size() : 0;
147ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
148ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
149ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
150ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public Palette.Swatch getItem(int position) {
151ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return mSwatches.get(position);
152ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
153ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
154ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
155ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public long getItemId(int position) {
156ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return position;
157ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
158ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
159ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        void setSwatches(List<Palette.Swatch> palette) {
160ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            mSwatches = palette;
161ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            notifyDataSetChanged();
162ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
163ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
164ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
165ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public View getView(int position, View view, ViewGroup parent) {
166ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            if (view == null) {
167ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                view = getLayoutInflater().inflate(R.layout.palette_grid_item, parent, false);
168ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            }
169ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            setBackgroundColor(view, getItem(position));
170ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return view;
171ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
172ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
173ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
174ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private void populatePalette(Palette palette) {
175ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mSwatchesPalette.setSwatches(palette.getSwatches());
176ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
177ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_vibrant), palette.getVibrantSwatch());
178ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_muted), palette.getMutedSwatch());
179ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_light_vibrant), palette.getLightVibrantSwatch());
180ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_light_muted), palette.getLightMutedSwatch());
181ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_dark_vibrant), palette.getDarkVibrantSwatch());
182ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_dark_muted), palette.getDarkMutedSwatch());
183ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
184ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
185ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private void setBackgroundColor(View view, Palette.Swatch swatch) {
186ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        if (view != null && swatch != null) {
187ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            view.setBackgroundColor(swatch.getRgb());
188ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
189ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
190ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
191ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes}