From 587dfccd32fadcf402f128da08bd9859b1dac06e Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Fri, 20 Mar 2020 17:03:49 +0800 Subject: [PATCH] Add a color picker. --- .../Activity/CustomizeThemeActivity.java | 15 +- .../CustomizeThemeRecyclerViewAdapter.java | 11 +- .../CustomView/ColorPickerDialog.java | 151 +++++++++++++++++ app/src/main/res/layout/color_picker.xml | 156 ++++++++++++++++++ app/src/main/res/values/strings.xml | 3 + 5 files changed, 333 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java create mode 100644 app/src/main/res/layout/color_picker.xml diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java index b6e45b8a..e345cc8f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java @@ -3,7 +3,9 @@ package ml.docilealligator.infinityforreddit.Activity; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; +import android.view.MenuItem; +import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModelProvider; @@ -69,7 +71,7 @@ public class CustomizeThemeActivity extends BaseActivity { setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - adapter = new CustomizeThemeRecyclerViewAdapter(); + adapter = new CustomizeThemeRecyclerViewAdapter(this); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); @@ -134,6 +136,17 @@ public class CustomizeThemeActivity extends BaseActivity { } } + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + + return false; + } + @Override protected SharedPreferences getSharedPreferences() { return sharedPreferences; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java index 398042de..69fa7ee5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java @@ -8,6 +8,7 @@ import android.widget.Switch; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; @@ -15,14 +16,17 @@ import java.util.ArrayList; import butterknife.BindView; import butterknife.ButterKnife; import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeSettingsItem; +import ml.docilealligator.infinityforreddit.CustomView.ColorPickerDialog; import ml.docilealligator.infinityforreddit.R; public class CustomizeThemeRecyclerViewAdapter extends RecyclerView.Adapter { private static final int VIEW_TYPE_COLOR = 1; private static final int VIEW_TYPE_SWITCH = 2; + private AppCompatActivity activity; private ArrayList customThemeSettingsItems; - public CustomizeThemeRecyclerViewAdapter() { + public CustomizeThemeRecyclerViewAdapter(AppCompatActivity activity) { + this.activity = activity; customThemeSettingsItems = new ArrayList<>(); } @@ -53,7 +57,10 @@ public class CustomizeThemeRecyclerViewAdapter extends RecyclerView.Adapter { - + new ColorPickerDialog(activity, customThemeSettingsItem.colorValue, color -> { + customThemeSettingsItem.colorValue = color; + ((ThemeColorItemViewHolder) holder).colorImageView.setBackgroundTintList(ColorStateList.valueOf(color)); + }).show(); }); } else if (holder instanceof ThemeSwitchItemViewHolder) { CustomThemeSettingsItem customThemeSettingsItem = customThemeSettingsItems.get(position); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java new file mode 100644 index 00000000..a60a38da --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java @@ -0,0 +1,151 @@ +package ml.docilealligator.infinityforreddit.CustomView; + +import android.content.Context; +import android.graphics.Color; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.SeekBar; +import android.widget.Toast; + +import androidx.appcompat.app.AlertDialog; + +import ml.docilealligator.infinityforreddit.R; + +public class ColorPickerDialog extends AlertDialog { + private View colorView; + private EditText colorValueEditText; + private SeekBar seekBarA; + private SeekBar seekBarR; + private SeekBar seekBarG; + private SeekBar seekBarB; + private Button cancelButton; + private Button okButton; + private int colorValue; + private boolean changeColorValueEditText = true; + private ColorPickerListener colorPickerListener; + + public interface ColorPickerListener { + void onColorPicked(int color); + } + + public ColorPickerDialog(Context context, int color, ColorPickerListener colorPickerListener) { + super(context); + + View rootView = getLayoutInflater().inflate(R.layout.color_picker, null); + colorView = rootView.findViewById(R.id.color_view_color_picker); + colorValueEditText = rootView.findViewById(R.id.color_edit_text_color_picker); + seekBarA = rootView.findViewById(R.id.a_seek_bar_color_picker); + seekBarR = rootView.findViewById(R.id.r_seek_bar_color_picker); + seekBarG = rootView.findViewById(R.id.g_seek_bar_color_picker); + seekBarB = rootView.findViewById(R.id.b_seek_bar_color_picker); + cancelButton = rootView.findViewById(R.id.cancel_button_color_picker); + okButton = rootView.findViewById(R.id.ok_button_color_picker); + + colorView.setBackgroundColor(color); + colorValueEditText.setText(Integer.toHexString(color).toUpperCase()); + colorValueEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + String s = editable.toString(); + if (s.length() == 6) { + try { + changeColorValueEditText = false; + colorValue = Color.parseColor("#" + s); + seekBarA.setProgress(255); + seekBarR.setProgress(Integer.parseInt(s.substring(0, 2), 16)); + seekBarG.setProgress(Integer.parseInt(s.substring(2, 4), 16)); + seekBarB.setProgress(Integer.parseInt(s.substring(4, 6), 16)); + changeColorValueEditText = true; + } catch (IllegalArgumentException ignored) { + + } + } else if (s.length() == 8) { + try { + changeColorValueEditText = false; + colorValue = Color.parseColor("#" + s); + seekBarA.setProgress(Integer.parseInt(s.substring(0, 2), 16)); + seekBarR.setProgress(Integer.parseInt(s.substring(2, 4), 16)); + seekBarG.setProgress(Integer.parseInt(s.substring(4, 6), 16)); + seekBarB.setProgress(Integer.parseInt(s.substring(6, 8), 16)); + changeColorValueEditText = true; + } catch (IllegalArgumentException ignored) { + + } + } + } + }); + + String colorHex = Integer.toHexString(color); + if (colorHex.length() == 8) { + colorValue = Color.parseColor("#" + colorHex); + seekBarA.setProgress(Integer.parseInt(colorHex.substring(0, 2), 16)); + seekBarR.setProgress(Integer.parseInt(colorHex.substring(2, 4), 16)); + seekBarG.setProgress(Integer.parseInt(colorHex.substring(4, 6), 16)); + seekBarB.setProgress(Integer.parseInt(colorHex.substring(6, 8), 16)); + } else if (colorHex.length() == 6) { + colorValue = Color.parseColor("#" + colorHex); + seekBarA.setProgress(255); + seekBarR.setProgress(Integer.parseInt(colorHex.substring(0, 2), 16)); + seekBarG.setProgress(Integer.parseInt(colorHex.substring(2, 4), 16)); + seekBarB.setProgress(Integer.parseInt(colorHex.substring(4, 6), 16)); + } + setOnSeekBarChangeListener(seekBarA); + setOnSeekBarChangeListener(seekBarR); + setOnSeekBarChangeListener(seekBarG); + setOnSeekBarChangeListener(seekBarB); + + cancelButton.setOnClickListener(view -> dismiss()); + okButton.setOnClickListener(view -> { + try { + colorValue = Color.parseColor("#" + colorValueEditText.getText().toString()); + colorPickerListener.onColorPicked(colorValue); + dismiss(); + } catch (IllegalArgumentException e) { + Toast.makeText(context, R.string.invalid_color, Toast.LENGTH_SHORT).show(); + } + }); + + setView(rootView); + } + + private void setOnSeekBarChangeListener(SeekBar seekBar) { + seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int i, boolean b) { + if (changeColorValueEditText) { + int aValue = seekBarA.getProgress(); + int rValue = seekBarR.getProgress(); + int gValue = seekBarG.getProgress(); + int bValue = seekBarB.getProgress(); + String colorHex = String.format("%02x%02x%02x%02x", aValue, rValue, gValue, bValue).toUpperCase(); + colorValue = Color.parseColor("#" + colorHex); + colorView.setBackgroundColor(colorValue); + colorValueEditText.setText(colorHex); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + + } + }); + } +} diff --git a/app/src/main/res/layout/color_picker.xml b/app/src/main/res/layout/color_picker.xml new file mode 100644 index 00000000..3e8b25cd --- /dev/null +++ b/app/src/main/res/layout/color_picker.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +