mirror of https://github.com/tasks/tasks
Change tags with multi-select
parent
c19649065a
commit
274d98160a
@ -0,0 +1,179 @@
|
|||||||
|
package org.tasks.tags;
|
||||||
|
|
||||||
|
import static org.tasks.preferences.ResourceResolver.getData;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||||
|
import androidx.core.content.res.ResourcesCompat;
|
||||||
|
import androidx.core.graphics.drawable.DrawableCompat;
|
||||||
|
import org.tasks.R;
|
||||||
|
|
||||||
|
public class CheckBoxTriStates extends AppCompatCheckBox {
|
||||||
|
|
||||||
|
private int alpha;
|
||||||
|
private State state;
|
||||||
|
private OnCheckedChangeListener clientListener;
|
||||||
|
|
||||||
|
private final OnCheckedChangeListener privateListener =
|
||||||
|
new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
switch (state) {
|
||||||
|
case PARTIALLY_CHECKED:
|
||||||
|
case UNCHECKED:
|
||||||
|
setState(State.CHECKED, true);
|
||||||
|
break;
|
||||||
|
case CHECKED:
|
||||||
|
setState(State.UNCHECKED, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public CheckBoxTriStates(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckBoxTriStates(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CheckBoxTriStates(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(State state, boolean notify) {
|
||||||
|
if (this.state != state) {
|
||||||
|
this.state = state;
|
||||||
|
|
||||||
|
if (notify && this.clientListener != null) {
|
||||||
|
this.clientListener.onCheckedChanged(this, this.isChecked());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBtn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {
|
||||||
|
if (this.privateListener != listener) {
|
||||||
|
this.clientListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setOnCheckedChangeListener(privateListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Parcelable onSaveInstanceState() {
|
||||||
|
Parcelable superState = super.onSaveInstanceState();
|
||||||
|
|
||||||
|
SavedState ss = new SavedState(superState);
|
||||||
|
|
||||||
|
ss.state = state.ordinal();
|
||||||
|
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRestoreInstanceState(Parcelable state) {
|
||||||
|
SavedState ss = (SavedState) state;
|
||||||
|
super.onRestoreInstanceState(ss.getSuperState());
|
||||||
|
this.state = State.values()[ss.state];
|
||||||
|
updateBtn();
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
alpha = (int) (255 * ResourcesCompat.getFloat(getResources(), R.dimen.alpha_secondary));
|
||||||
|
setState(State.UNCHECKED, false);
|
||||||
|
setOnCheckedChangeListener(this.privateListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBtn() {
|
||||||
|
int btnDrawable;
|
||||||
|
int alpha = 255;
|
||||||
|
switch (state) {
|
||||||
|
case PARTIALLY_CHECKED:
|
||||||
|
btnDrawable = R.drawable.ic_indeterminate_check_box_24px;
|
||||||
|
break;
|
||||||
|
case CHECKED:
|
||||||
|
btnDrawable = R.drawable.ic_outline_check_box_24px;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
btnDrawable = R.drawable.ic_outline_check_box_outline_blank_24px;
|
||||||
|
alpha = this.alpha;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Drawable original = getResources().getDrawable(btnDrawable);
|
||||||
|
Drawable drawable = original.mutate();
|
||||||
|
drawable.setAlpha(alpha);
|
||||||
|
DrawableCompat.setTint(
|
||||||
|
drawable,
|
||||||
|
state == State.UNCHECKED
|
||||||
|
? getResources().getColor(R.color.icon_tint)
|
||||||
|
: getData(getContext(), R.attr.colorAccent));
|
||||||
|
|
||||||
|
setButtonDrawable(drawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum State {
|
||||||
|
PARTIALLY_CHECKED,
|
||||||
|
CHECKED,
|
||||||
|
UNCHECKED
|
||||||
|
}
|
||||||
|
|
||||||
|
static class SavedState extends BaseSavedState {
|
||||||
|
@SuppressWarnings("hiding")
|
||||||
|
public static final Parcelable.Creator<SavedState> CREATOR =
|
||||||
|
new Parcelable.Creator<SavedState>() {
|
||||||
|
@Override
|
||||||
|
public SavedState createFromParcel(Parcel in) {
|
||||||
|
return new SavedState(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavedState[] newArray(int size) {
|
||||||
|
return new SavedState[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int state;
|
||||||
|
|
||||||
|
SavedState(Parcelable superState) {
|
||||||
|
super(superState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SavedState(Parcel in) {
|
||||||
|
super(in);
|
||||||
|
state = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
super.writeToParcel(out, flags);
|
||||||
|
out.writeValue(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CheckboxTriState.SavedState{"
|
||||||
|
+ Integer.toHexString(System.identityHashCode(this))
|
||||||
|
+ " state="
|
||||||
|
+ state
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM19,19L5,19L5,5h14v14zM7,11h10v2L7,13z"/>
|
||||||
|
</vector>
|
||||||
Loading…
Reference in New Issue