Material design color palette
While working on project Cyanea I was interested in programmatically computing a color palette which produced the same color codes as Google’s 2014 Material Design color palettes. I asked for help on StackOverflow.com and was answered that it was impossible. However, I did manage to generate a color palette similar to the material design palette.
Question
Google has designed a color palette. Given a color, I want to dynamically create the palette in Android.
There was a similar question in the Graphic Design site and an open source javascript solution which generates a similar color palette. The factors for each color are found here and the function used to create the color is found in this stackoverflow answer.
I used that answer and project to generate a palette that is similar to Google’s. However, I want an algorithm that would return the exact values which Google has generated (see the first link).
Question: How does Google calculate the palette colors for material design?
What I have tried so far:
Based off the information above, I created this example to show how I generated a similar palette. Again, I want the exact values.
import android.app.Activity;
import android.app.AlertDialog;
import android.graphics.Color;
import android.os.AsyncTask;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
/**
* @author Jared Rummler <[email protected]>
*/
public class PaletteTask extends AsyncTask<Integer, Void, List<PaletteTask.Shade>> {
private static int shadeColor(int color, double percent) {
return shadeColor(String.format("#%06X", (0xFFFFFF & color)), percent);
}
private static int shadeColor(String color, double percent) {
long f = Long.parseLong(color.substring(1), 16);
double t = percent < 0 ? 0 : 255;
double p = percent < 0 ? percent * -1 : percent;
long R = f >> 16;
long G = f >> 8 & 0x00FF;
long B = f & 0x0000FF;
int red = (int) (Math.round((t - R) * p) + R);
int green = (int) (Math.round((t - G) * p) + G);
int blue = (int) (Math.round((t - B) * p) + B);
return Color.rgb(red, green, blue);
}
private final WeakReference<Activity> activityWeakReference;
private final List<Shade> shades = new LinkedList<>();
{
shades.add(new Shade(0.9, "50"));
shades.add(new Shade(0.7, "100"));
shades.add(new Shade(0.5, "200"));
shades.add(new Shade(0.333, "300"));
shades.add(new Shade(0.166, "400"));
shades.add(new Shade(0, "500"));
shades.add(new Shade(-0.125, "600"));
shades.add(new Shade(-0.25, "700"));
shades.add(new Shade(-0.375, "800"));
shades.add(new Shade(-0.5, "900"));
shades.add(new Shade(0.7, "A100"));
shades.add(new Shade(0.5, "A200"));
shades.add(new Shade(0.166, "A400"));
shades.add(new Shade(-0.25, "A700"));
}
public PaletteTask(Activity activity) {
activityWeakReference = new WeakReference<>(activity);
}
@Override protected List<Shade> doInBackground(Integer... colors) {
for (Shade shade : shades) {
shade.color = shadeColor(colors[0], shade.percent);
}
return shades;
}
@Override protected void onPostExecute(List<Shade> shades) {
Activity activity = activityWeakReference.get();
if (activity == null || activity.isFinishing()) {
return;
}
// Create a dialog that shows our generated colors:
ScrollView scrollView = new ScrollView(activity);
LinearLayout linearLayout = new LinearLayout(activity);
linearLayout.setOrientation(LinearLayout.VERTICAL);
int width, height;
width = LinearLayout.LayoutParams.MATCH_PARENT;
height = (int) (30/*dp*/ * (activity.getResources().getDisplayMetrics().densityDpi / 160f));
// add each color
for (Shade shade : shades) {
LinearLayout layoutColor = new LinearLayout(activity);
TextView textView = new TextView(activity);
layoutColor.setLayoutParams(new LinearLayout.LayoutParams(width, height));
layoutColor.setBackgroundColor(shade.color);
layoutColor.setGravity(Gravity.CENTER);
textView.setText(shade.name + " " + String.format("#%06X", (0xFFFFFF & shade.color)));
layoutColor.addView(textView);
linearLayout.addView(layoutColor);
}
scrollView.addView(linearLayout);
new AlertDialog.Builder(activity).setView(scrollView).show();
}
public static class Shade {
final double percent;
final String name;
int color;
public Shade(double percent, String name) {
this.percent = percent;
this.name = name;
}
}
}
Invoking the AsynTask
:
int materialRed500 = 0xFFF44336;
new PaletteTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, materialRed500);
Dialog created from the above code:
Answer
Mikel Bitson gave the answer that it was impossible.