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 android.graphics.Bitmap;
20ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.net.Uri;
21ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.os.Bundle;
22ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.Menu;
23ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.MenuItem;
24ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.View;
25ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.view.ViewGroup;
26ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.AdapterView;
27ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.BaseAdapter;
28ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.GridView;
29ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.ImageView;
30ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport android.widget.Toast;
31ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
32def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.appcompat.app.AppCompatActivity;
33def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.palette.graphics.Palette;
34def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikas
35def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport com.example.android.supportv7.R;
36def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikas
37ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banesimport java.util.List;
38ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
39ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes/**
40ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Activity which displays the more details about a generated {@link Palette} for a specific
41ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * {@link android.provider.MediaStore} image.
42ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *
43ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Displays the full generated palette of colors in a grid, which allows clicking on an palette item
44ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * to display more information in a {@link Toast}.
45ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes *
46ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * Also allows the customization of the number of colors used in the palette generation for
47ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes * demonstration purposes.
48ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes */
4944d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class PaletteDetailActivity extends AppCompatActivity {
50ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
51ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private ImageView mImageView;
52ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private GridView mGridView;
53ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private SwatchesPalette mSwatchesPalette;
54ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
55ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private Uri mImageUri;
56ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
57ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private Toast mCurrentToast;
58ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
59ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    @Override
60ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    protected void onCreate(Bundle savedInstanceState) {
61ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        super.onCreate(savedInstanceState);
62ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setContentView(R.layout.palette_activity_detail);
63ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
64ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mImageUri = getIntent().getData();
65ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
66fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mImageView = findViewById(R.id.image);
67fa2e2acf79d791a90410025daad438968550d18cAlan Viverette        mGridView = findViewById(R.id.palette);
68ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mSwatchesPalette = new SwatchesPalette();
69ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mGridView.setAdapter(mSwatchesPalette);
70ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
71ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        // Set an OnItemClickListener to display a information Toast when a Palette item is clicked
72ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
73ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            @Override
74ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) {
75ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                // Cancel the current Toast if there is already one being displayed
76ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                if (mCurrentToast != null) {
77ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                    mCurrentToast.cancel();
78ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                }
79ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
80ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                final Palette.Swatch item = (Palette.Swatch) adapterView.getItemAtPosition(pos);
81ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                mCurrentToast = Toast.makeText(PaletteDetailActivity.this,
82ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                        item.toString(), Toast.LENGTH_LONG);
83ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                mCurrentToast.show();
84ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            }
85ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        });
86ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
87ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        // Load the image with a default number of colors
88ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        loadImage(16);
89ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
90ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
91ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    @Override
92ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    public boolean onCreateOptionsMenu(Menu menu) {
93ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        getMenuInflater().inflate(R.menu.sample_palette_actions, menu);
94ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        return true;
95ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
96ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
97ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    @Override
98ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    public boolean onOptionsItemSelected(MenuItem item) {
99ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        switch (item.getItemId()) {
100ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_8:
101ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(8);
102ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
103ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
104ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_12:
105ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(12);
106ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
107ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
108ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_16:
109ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(16);
110ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
111ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
112ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_24:
113ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(24);
114ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
115ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
116ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            case R.id.menu_num_colors_32:
117ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                loadImage(32);
118ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                item.setChecked(true);
119ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                return true;
120ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
121ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        return super.onOptionsItemSelected(item);
122ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
123ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
124ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private void loadImage(final int numColors) {
125ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        final int id = Integer.parseInt(mImageUri.getLastPathSegment());
126ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
127ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        ImageLoader.loadMediaStoreThumbnail(mImageView, id, new ImageLoader.Listener() {
128ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            @Override
129ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            public void onImageLoaded(Bitmap bitmap) {
130e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                new Palette.Builder(bitmap).maximumColorCount(numColors).generate(
131e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                        new Palette.PaletteAsyncListener() {
132e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                            @Override
133e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                            public void onGenerated(Palette palette) {
134e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                                populatePalette(palette);
135e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                            }
136e8e0eae2600001c8b1e9d5a9f0331cf045193746Aurimas Liutikas                        });
137ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            }
138ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        });
139ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
140ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
141ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private class SwatchesPalette extends BaseAdapter {
142ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
143ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        private List<Palette.Swatch> mSwatches;
144ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
145ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
146ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public int getCount() {
147ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return mSwatches != null ? mSwatches.size() : 0;
148ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
149ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
150ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
151ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public Palette.Swatch getItem(int position) {
152ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return mSwatches.get(position);
153ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
154ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
155ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
156ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public long getItemId(int position) {
157ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return position;
158ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
159ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
160ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        void setSwatches(List<Palette.Swatch> palette) {
161ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            mSwatches = palette;
162ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            notifyDataSetChanged();
163ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
164ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
165ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        @Override
166ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        public View getView(int position, View view, ViewGroup parent) {
167ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            if (view == null) {
168ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes                view = getLayoutInflater().inflate(R.layout.palette_grid_item, parent, false);
169ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            }
170ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            setBackgroundColor(view, getItem(position));
171ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            return view;
172ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
173ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
174ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
175ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private void populatePalette(Palette palette) {
176ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        mSwatchesPalette.setSwatches(palette.getSwatches());
177ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
178ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_vibrant), palette.getVibrantSwatch());
179ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_muted), palette.getMutedSwatch());
180ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_light_vibrant), palette.getLightVibrantSwatch());
181ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_light_muted), palette.getLightMutedSwatch());
182ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_dark_vibrant), palette.getDarkVibrantSwatch());
183ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        setBackgroundColor(findViewById(R.id.text_dark_muted), palette.getDarkMutedSwatch());
184ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
185ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
186ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    private void setBackgroundColor(View view, Palette.Swatch swatch) {
187ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        if (view != null && swatch != null) {
188ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes            view.setBackgroundColor(swatch.getRgb());
189ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes        }
190ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes    }
191ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes
192ef3b66039ff877b61bbc823921f6033d777cd3c8Chris Banes}