jaredrummler / ColorPicker

A highly customizable color picker for Android
Apache License 2.0
795 stars 172 forks source link

Save custom selections in presets #15

Open bizzguy opened 7 years ago

bizzguy commented 7 years ago

Here's the use case

I'd like custom colors to stay in the presets (bumping off the least used color).

Is something like this possible?

jaredrummler commented 7 years ago

This would be neat. You could do this by setting the presets yourself.

Example:

import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import com.jaredrummler.android.colorpicker.ColorPickerDialog;
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

public class PresetsActivity extends AppCompatActivity implements ColorPickerDialogListener {

  private SharedPreferences preferences;
  private int selectedColor;

  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    preferences = PreferenceManager.getDefaultSharedPreferences(this);
  }

  @Override public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(0, Menu.FIRST, 0, "Show Dialog");
    return super.onCreateOptionsMenu(menu);
  }

  @Override public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == Menu.FIRST) {
      showColorPickerDialog();
      return true;
    }
    return super.onOptionsItemSelected(item);
  }

  @Override public void onColorSelected(int dialogId, @ColorInt int color) {
    selectedColor = color;

    if (!arrayContains(ColorPickerDialog.MATERIAL_COLORS, color)) {
      // add the custom color to shared preferences so we can use it in the presets later
      Set<String> presets = preferences.getStringSet("custom_colors", null);
      if (presets == null) {
        presets = new LinkedHashSet<>();
      }
      presets.add(toHex(color));
      preferences.edit().putStringSet("custom_colors", presets).apply();
    }
  }

  @Override public void onDialogDismissed(int dialogId) {

  }

  private void showColorPickerDialog() {
    // colors used in presets
    int[] colors = ColorPickerDialog.MATERIAL_COLORS;

    // replace any custom colors
    Set<String> customColors = preferences.getStringSet("custom_colors", null);
    if (customColors != null) {
      int index = 0;

      // reverse order
      List<String> list = new ArrayList<>(customColors);
      Collections.sort(list, Collections.<String>reverseOrder());
      customColors = new LinkedHashSet<>(list);

      for (String hex : customColors) {
        colors[index++] = Color.parseColor(hex);
        if (index >= colors.length) break;
      }
    }

    // show the dialog
    ColorPickerDialog.newBuilder().setPresets(colors).setShowAlphaSlider(true).setColor(selectedColor).show(this);
  }

  private String toHex(int color) {
    if (Color.alpha(color) != 255) {
      return "#" + Integer.toHexString(color).toUpperCase(Locale.US);
    } else {
      return "#" + String.format("%06X", 0xFFFFFF & color).toUpperCase(Locale.US);
    }
  }

  private boolean arrayContains(int[] array, int value) {
    if (array != null) {
      int length = array.length;
      for (int i = 0; i < length; i++) {
        if (array[i] == value) {
          return true;
        }
      }
    }
    return false;
  }
}

My example will replace the first colors. I'm sure it could be improved on. I am always accepting pull requests if you want to add this feature to the library.