1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-03 01:57:40 +01:00

fixed dialog fragment target w/child fragment manager crashes

This commit is contained in:
Mariotaku Lee 2017-08-06 19:36:29 +08:00
parent 3d1a3f18bc
commit 07fc1167dc
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
16 changed files with 355 additions and 404 deletions

View File

@ -1,168 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.preference;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.PreferenceDialogFragmentCompat;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.extension.DialogExtensionsKt;
import org.mariotaku.twidere.preference.iface.IDialogPreference;
import org.mariotaku.twidere.util.TwidereColorUtils;
import me.uucky.colorpicker.ColorPickerDialog;
import static org.mariotaku.twidere.Constants.PRESET_COLORS;
import static org.mariotaku.twidere.TwidereConstants.LOGTAG;
public class ColorPickerPreference extends DialogPreference implements
IDialogPreference {
private int mDefaultValue = Color.WHITE;
private boolean mAlphaSliderEnabled = false;
public ColorPickerPreference(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.dialogPreferenceStyle);
}
public ColorPickerPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
setWidgetLayoutResource(R.layout.preference_widget_color_picker);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ColorPickerPreferences);
mAlphaSliderEnabled = a.getBoolean(R.styleable.ColorPickerPreferences_alphaSlider, false);
setDefaultValue(a.getColor(R.styleable.ColorPickerPreferences_defaultColor, 0));
a.recycle();
}
@Override
public void setDefaultValue(final Object value) {
if (!(value instanceof Integer)) return;
mDefaultValue = (Integer) value;
}
@Override
protected void onSetInitialValue(final boolean restoreValue, final Object defaultValue) {
if (isPersistent() && defaultValue instanceof Integer) {
persistInt(restoreValue ? getValue() : (Integer) defaultValue);
}
}
private int getValue() {
try {
if (isPersistent()) return getPersistedInt(mDefaultValue);
} catch (final ClassCastException e) {
Log.w(LOGTAG, e);
}
return mDefaultValue;
}
@Override
public void displayDialog(PreferenceFragmentCompat fragment) {
ColorPickerPreferenceDialogFragment df = ColorPickerPreferenceDialogFragment.newInstance(getKey());
df.setTargetFragment(fragment, 0);
df.show(fragment.getFragmentManager(), getKey());
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
final ImageView imageView = (ImageView) holder.findViewById(R.id.color);
imageView.setImageBitmap(TwidereColorUtils.getColorPreviewBitmap(getContext(), getValue(), false));
}
public boolean isAlphaSliderEnabled() {
return mAlphaSliderEnabled;
}
public static final class ColorPickerPreferenceDialogFragment extends PreferenceDialogFragmentCompat
implements DialogInterface.OnShowListener, DialogInterface.OnClickListener {
private ColorPickerDialog.Controller mController;
public static ColorPickerPreferenceDialogFragment newInstance(String key) {
final ColorPickerPreferenceDialogFragment df = new ColorPickerPreferenceDialogFragment();
final Bundle args = new Bundle();
args.putString(ARG_KEY, key);
df.setArguments(args);
return df;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final ColorPickerPreference preference = (ColorPickerPreference) getPreference();
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(preference.getDialogTitle());
builder.setView(R.layout.cp__dialog_color_picker);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, this);
Dialog dialog = builder.create();
dialog.setOnShowListener(this);
return dialog;
}
@Override
public void onDialogClosed(boolean positive) {
final ColorPickerPreference preference = (ColorPickerPreference) getPreference();
if (mController == null) return;
final int color = mController.getColor();
if (preference.isPersistent()) {
preference.persistInt(color);
}
preference.callChangeListener(color);
preference.notifyChanged();
}
@Override
public void onShow(DialogInterface dialog) {
final ColorPickerPreference preference = (ColorPickerPreference) getPreference();
final AlertDialog alertDialog = (AlertDialog) dialog;
DialogExtensionsKt.applyTheme(alertDialog);
final View windowView = alertDialog.getWindow().getDecorView();
if (windowView == null) return;
mController = new ColorPickerDialog.Controller(getContext(), windowView);
mController.setAlphaEnabled(preference.isAlphaSliderEnabled());
for (int presetColor : PRESET_COLORS) {
mController.addColor(ContextCompat.getColor(getContext(), presetColor));
}
mController.setInitialColor(preference.getValue());
}
}
}

View File

@ -1,219 +0,0 @@
package org.mariotaku.twidere.preference;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.ThemedPreferenceDialogFragmentCompat;
import org.mariotaku.twidere.preference.iface.IDialogPreference;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutSpec;
import org.mariotaku.twidere.util.dagger.GeneralComponent;
import javax.inject.Inject;
import static org.mariotaku.twidere.TwidereConstants.LOGTAG;
/**
* Created by mariotaku on 16/3/15.
*/
public class KeyboardShortcutPreference extends DialogPreference implements IDialogPreference {
private SharedPreferences.OnSharedPreferenceChangeListener mPreferencesChangeListener;
private String mContextTag, mAction;
@Inject
KeyboardShortcutsHandler mKeyboardShortcutsHandler;
public KeyboardShortcutPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
public KeyboardShortcutPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public KeyboardShortcutPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet set) {
GeneralComponent.Companion.get(context).inject(this);
TypedArray a = context.obtainStyledAttributes(set, R.styleable.KeyboardShortcutPreference);
mContextTag = a.getString(R.styleable.KeyboardShortcutPreference_android_tag);
mAction = a.getString(R.styleable.KeyboardShortcutPreference_android_action);
a.recycle();
if (TextUtils.isEmpty(mAction)) {
throw new IllegalArgumentException("android:action required");
}
setKey(mAction);
setDialogLayoutResource(R.layout.dialog_keyboard_shortcut_input);
setPersistent(false);
setDialogTitle(KeyboardShortcutsHandler.getActionLabel(context, mAction));
setTitle(KeyboardShortcutsHandler.getActionLabel(context, mAction));
mPreferencesChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
updateSummary();
}
};
updateSummary();
}
@Override
protected void onPrepareForRemoval() {
mKeyboardShortcutsHandler.unregisterOnSharedPreferenceChangeListener(mPreferencesChangeListener);
super.onPrepareForRemoval();
}
@Override
public void onAttached() {
super.onAttached();
mKeyboardShortcutsHandler.registerOnSharedPreferenceChangeListener(mPreferencesChangeListener);
}
private void updateSummary() {
final KeyboardShortcutSpec spec = mKeyboardShortcutsHandler.findKey(mAction);
setSummary(spec != null ? spec.toKeyString() : null);
}
@Override
public void displayDialog(PreferenceFragmentCompat fragment) {
KeyboardShortcutDialogFragment df = KeyboardShortcutDialogFragment.newInstance(mAction);
df.setTargetFragment(fragment, 0);
df.show(fragment.getFragmentManager(), mAction);
}
public String getAction() {
return mAction;
}
private String getContextTag() {
return mContextTag;
}
public KeyboardShortcutsHandler getKeyboardShortcutsHandler() {
return mKeyboardShortcutsHandler;
}
public static class KeyboardShortcutDialogFragment extends ThemedPreferenceDialogFragmentCompat
implements DialogInterface.OnKeyListener {
private TextView mKeysLabel;
private TextView mConflictLabel;
private KeyboardShortcutSpec mKeySpec;
private int mModifierStates;
public static KeyboardShortcutDialogFragment newInstance(String key) {
final KeyboardShortcutDialogFragment df = new KeyboardShortcutDialogFragment();
final Bundle args = new Bundle();
args.putString(ARG_KEY, key);
df.setArguments(args);
return df;
}
@Override
public void onDialogClosed(boolean positiveResult) {
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, this);
builder.setNeutralButton(R.string.action_clear, this);
builder.setOnKeyListener(this);
}
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (KeyEvent.isModifierKey(keyCode)) {
mModifierStates |= KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode);
}
} else if (event.getAction() != KeyEvent.ACTION_UP) {
return false;
}
if (KeyEvent.isModifierKey(keyCode)) {
mModifierStates &= ~KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode);
}
final KeyboardShortcutPreference preference = (KeyboardShortcutPreference) getPreference();
final String action = preference.getAction();
final String contextTag = preference.getContextTag();
final KeyboardShortcutsHandler handler = preference.getKeyboardShortcutsHandler();
final KeyboardShortcutSpec spec = KeyboardShortcutsHandler.getKeyboardShortcutSpec(contextTag,
keyCode, event, KeyEvent.normalizeMetaState(mModifierStates | event.getMetaState()));
if (spec == null || !spec.isValid()) {
Log.d(LOGTAG, String.format("Invalid key %s", event), new Exception());
return false;
}
mKeySpec = spec;
mKeysLabel.setText(spec.toKeyString());
final String oldAction = handler.findAction(spec);
final Context context = getContext();
if (action.equals(oldAction) || TextUtils.isEmpty(oldAction)) {
mConflictLabel.setVisibility(View.GONE);
if (dialog instanceof AlertDialog) {
((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setText((android.R.string.ok));
}
} else {
mConflictLabel.setVisibility(View.VISIBLE);
final String label = KeyboardShortcutsHandler.getActionLabel(context, oldAction);
mConflictLabel.setText(context.getString(R.string.conflicts_with_name, label));
if (dialog instanceof AlertDialog) {
((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setText((R.string.overwrite));
}
}
return true;
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mKeysLabel = (TextView) view.findViewById(R.id.keys_label);
mConflictLabel = (TextView) view.findViewById(R.id.conflict_label);
mConflictLabel.setVisibility(View.GONE);
}
@Override
public void onClick(DialogInterface dialog, int which) {
final KeyboardShortcutPreference preference = (KeyboardShortcutPreference) getPreference();
final String action = preference.getAction();
final KeyboardShortcutsHandler handler = preference.getKeyboardShortcutsHandler();
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
if (mKeySpec == null) return;
handler.register(mKeySpec, action);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
handler.unregister(action);
break;
}
}
}
}
}

View File

@ -53,7 +53,7 @@ abstract class MultiSelectListPreference extends DialogPreference implements IDi
@Override
public void displayDialog(PreferenceFragmentCompat fragment) {
public void displayDialog(@NonNull PreferenceFragmentCompat fragment) {
final MultiSelectListDialogFragment df = MultiSelectListDialogFragment.newInstance(getKey());
df.setTargetFragment(fragment, 0);
df.show(fragment.getFragmentManager(), getKey());

View File

@ -23,6 +23,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.PreferenceDialogFragmentCompat;
@ -94,7 +95,7 @@ public class NotificationTypePreference extends DialogPreference implements
}
@Override
public void displayDialog(PreferenceFragmentCompat fragment) {
public void displayDialog(@NonNull PreferenceFragmentCompat fragment) {
final NotificationTypeDialogFragment df = NotificationTypeDialogFragment.newInstance(getKey());
df.setTargetFragment(fragment, 0);
df.show(fragment.getFragmentManager(), getKey());

View File

@ -185,7 +185,7 @@ public class SeekBarDialogPreference extends DialogPreference implements IDialog
}
@Override
public void displayDialog(PreferenceFragmentCompat fragment) {
public void displayDialog(@NonNull PreferenceFragmentCompat fragment) {
SeekBarDialogPreferenceFragment df = SeekBarDialogPreferenceFragment.newInstance(getKey());
df.setTargetFragment(fragment, 0);
df.show(fragment.getFragmentManager(), getKey());

View File

@ -50,7 +50,7 @@ public class SettingsImportExportPreference extends DialogPreference implements
}
@Override
public void displayDialog(PreferenceFragmentCompat fragment) {
public void displayDialog(@NonNull PreferenceFragmentCompat fragment) {
ImportExportDialogFragment df = ImportExportDialogFragment.newInstance(getKey());
df.setTargetFragment(fragment, 0);
df.show(fragment.getFragmentManager(), getKey());

View File

@ -98,7 +98,7 @@ public class ThemeBackgroundPreference extends DialogPreference implements Const
}
@Override
public void displayDialog(PreferenceFragmentCompat fragment) {
public void displayDialog(@NonNull PreferenceFragmentCompat fragment) {
InternalDialogFragment df = InternalDialogFragment.newInstance(getKey());
df.setTargetFragment(fragment, 0);
df.show(fragment.getFragmentManager(), getKey());

View File

@ -102,14 +102,24 @@ class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() {
companion object {
const val EXTRA_FEATURE = "feature"
const val EXTRA_SOURCE = "source"
fun show(fm: FragmentManager, feature: String, source: String? = null, requestCode: Int = 0): ExtraFeaturesIntroductionDialogFragment {
const val FRAGMENT_TAG = "extra_features_introduction"
fun create(feature: String, source: String? = null, requestCode: Int = 0):
ExtraFeaturesIntroductionDialogFragment {
val df = ExtraFeaturesIntroductionDialogFragment()
df.arguments = Bundle {
this[EXTRA_FEATURE] = feature
this[EXTRA_SOURCE] = source
this[EXTRA_REQUEST_CODE] = requestCode
}
df.show(fm, "extra_features_introduction")
return df
}
fun show(fm: FragmentManager, feature: String, source: String? = null, requestCode: Int = 0):
ExtraFeaturesIntroductionDialogFragment {
val df = create(feature, source, requestCode)
df.show(fm, FRAGMENT_TAG)
return df
}
}

View File

@ -72,15 +72,20 @@ class SetUserNicknameDialogFragment : BaseDialogFragment(), OnClickListener {
companion object {
private val FRAGMENT_TAG_SET_USER_NICKNAME = "set_user_nickname"
const val FRAGMENT_TAG = "set_user_nickname"
fun show(fm: FragmentManager, userKey: UserKey, nickname: String?): SetUserNicknameDialogFragment {
fun create(userKey: UserKey, nickname: String?): SetUserNicknameDialogFragment {
val f = SetUserNicknameDialogFragment()
val args = Bundle()
args.putParcelable(EXTRA_USER_KEY, userKey)
args.putString(EXTRA_NAME, nickname)
f.arguments = args
f.show(fm, FRAGMENT_TAG_SET_USER_NICKNAME)
return f
}
fun show(fm: FragmentManager, userKey: UserKey, nickname: String?): SetUserNicknameDialogFragment {
val f = create(userKey, nickname)
f.show(fm, FRAGMENT_TAG)
return f
}
}

View File

@ -79,18 +79,20 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac
when (arguments?.getString(EXTRA_ACTION)) {
ACTION_ADD_URL_SUBSCRIPTION -> {
if (!extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION)) {
val df = ExtraFeaturesIntroductionDialogFragment.show(childFragmentManager,
val df = ExtraFeaturesIntroductionDialogFragment.create(
ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION)
df.setTargetFragment(this, REQUEST_ADD_URL_SUBSCRIPTION_PURCHASE)
df.show(fragmentManager, ExtraFeaturesIntroductionDialogFragment.FRAGMENT_TAG)
} else {
showAddUrlSubscription()
}
}
else -> {
if (!extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION)) {
val df = ExtraFeaturesIntroductionDialogFragment.show(childFragmentManager,
val df = ExtraFeaturesIntroductionDialogFragment.create(
ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION)
df.setTargetFragment(this, REQUEST_PURCHASE_EXTRA_FEATURES)
df.show(fragmentManager, ExtraFeaturesIntroductionDialogFragment.FRAGMENT_TAG)
}
}
}

View File

@ -127,7 +127,7 @@ class UserTimelineFragment : ParcelableStatusesFragment() {
override fun onFilterClick(holder: TimelineFilterHeaderViewHolder) {
val df = UserTimelineFilterDialogFragment()
df.setTargetFragment(this, REQUEST_SET_TIMELINE_FILTER)
df.show(childFragmentManager, "set_timeline_filter")
df.show(fragmentManager, "set_timeline_filter")
}
@Subscribe

View File

@ -0,0 +1,147 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.preference
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.graphics.Color
import android.os.Bundle
import android.support.v4.content.ContextCompat
import android.support.v7.app.AlertDialog
import android.support.v7.preference.DialogPreference
import android.support.v7.preference.PreferenceDialogFragmentCompat
import android.support.v7.preference.PreferenceFragmentCompat
import android.support.v7.preference.PreferenceViewHolder
import android.util.AttributeSet
import android.util.Log
import android.widget.ImageView
import me.uucky.colorpicker.ColorPickerDialog
import org.mariotaku.twidere.Constants.PRESET_COLORS
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.preference.iface.IDialogPreference
import org.mariotaku.twidere.util.TwidereColorUtils
class ColorPickerPreference(context: Context, attrs: AttributeSet? = null) :
DialogPreference(context, attrs, R.attr.dialogPreferenceStyle), IDialogPreference {
var defaultValue: Int = Color.WHITE
var isAlphaSliderEnabled: Boolean
private val value: Int
get() {
try {
if (isPersistent) return getPersistedInt(defaultValue)
} catch (e: ClassCastException) {
Log.w(LOGTAG, e)
}
return defaultValue
}
init {
widgetLayoutResource = R.layout.preference_widget_color_picker
val a = context.obtainStyledAttributes(attrs, R.styleable.ColorPickerPreferences)
isAlphaSliderEnabled = a.getBoolean(R.styleable.ColorPickerPreferences_alphaSlider, false)
setDefaultValue(a.getColor(R.styleable.ColorPickerPreferences_defaultColor, 0))
a.recycle()
}
override fun setDefaultValue(value: Any) {
if (value !is Int) return
defaultValue = value
}
override fun onSetInitialValue(restoreValue: Boolean, defaultValue: Any?) {
if (isPersistent && defaultValue is Int) {
persistInt(if (restoreValue) value else defaultValue)
}
}
override fun displayDialog(fragment: PreferenceFragmentCompat) {
val df = ColorPickerPreferenceDialogFragment.newInstance(key)
df.setTargetFragment(fragment, 0)
df.show(fragment.fragmentManager, key)
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val imageView = holder.findViewById(R.id.color) as ImageView
imageView.setImageBitmap(TwidereColorUtils.getColorPreviewBitmap(context, value, false))
}
class ColorPickerPreferenceDialogFragment : PreferenceDialogFragmentCompat(), DialogInterface.OnShowListener, DialogInterface.OnClickListener {
private lateinit var controller: ColorPickerDialog.Controller
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val preference = preference as ColorPickerPreference
val context = context
val builder = AlertDialog.Builder(context)
builder.setTitle(preference.dialogTitle)
builder.setView(R.layout.cp__dialog_color_picker)
builder.setPositiveButton(android.R.string.ok, this)
builder.setNegativeButton(android.R.string.cancel, this)
val dialog = builder.create()
dialog.setOnShowListener(this)
return dialog
}
override fun onDialogClosed(positive: Boolean) {
val preference = preference as ColorPickerPreference
val color = controller.color
if (preference.isPersistent) {
preference.persistInt(color)
}
preference.callChangeListener(color)
preference.notifyChanged()
}
override fun onShow(dialog: DialogInterface) {
val preference = preference as ColorPickerPreference
val alertDialog = dialog as AlertDialog
alertDialog.applyTheme()
val windowView = alertDialog.window!!.decorView ?: return
controller = ColorPickerDialog.Controller(context, windowView)
controller.setAlphaEnabled(preference.isAlphaSliderEnabled)
for (presetColor in PRESET_COLORS) {
controller.addColor(ContextCompat.getColor(context, presetColor))
}
controller.setInitialColor(preference.value)
}
companion object {
fun newInstance(key: String): ColorPickerPreferenceDialogFragment {
val df = ColorPickerPreferenceDialogFragment()
val args = Bundle()
args.putString(PreferenceDialogFragmentCompat.ARG_KEY, key)
df.arguments = args
return df
}
}
}
}

View File

@ -0,0 +1,172 @@
package org.mariotaku.twidere.preference
import android.content.Context
import android.content.DialogInterface
import android.content.SharedPreferences
import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.support.v7.preference.DialogPreference
import android.support.v7.preference.PreferenceDialogFragmentCompat
import android.support.v7.preference.PreferenceFragmentCompat
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.widget.TextView
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.fragment.ThemedPreferenceDialogFragmentCompat
import org.mariotaku.twidere.preference.iface.IDialogPreference
import org.mariotaku.twidere.util.KeyboardShortcutsHandler
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutSpec
import org.mariotaku.twidere.util.dagger.GeneralComponent
import javax.inject.Inject
/**
* Created by mariotaku on 16/3/15.
*/
class KeyboardShortcutPreference(context: Context, attrs: AttributeSet? = null) :
DialogPreference(context, attrs), IDialogPreference {
private val preferencesChangeListener: SharedPreferences.OnSharedPreferenceChangeListener
val contextTag: String
val action: String
@Inject
lateinit var keyboardShortcutsHandler: KeyboardShortcutsHandler
init {
GeneralComponent.get(context).inject(this)
val a = context.obtainStyledAttributes(attrs, R.styleable.KeyboardShortcutPreference)
contextTag = a.getString(R.styleable.KeyboardShortcutPreference_android_tag)
action = a.getString(R.styleable.KeyboardShortcutPreference_android_action)
.takeUnless(String::isNullOrEmpty) ?: throw IllegalArgumentException("android:action required")
a.recycle()
key = action
dialogLayoutResource = R.layout.dialog_keyboard_shortcut_input
isPersistent = false
dialogTitle = KeyboardShortcutsHandler.getActionLabel(context, action)
title = KeyboardShortcutsHandler.getActionLabel(context, action)
preferencesChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { preferences, key -> updateSummary() }
updateSummary()
}
override fun onPrepareForRemoval() {
keyboardShortcutsHandler.unregisterOnSharedPreferenceChangeListener(preferencesChangeListener)
super.onPrepareForRemoval()
}
override fun onAttached() {
super.onAttached()
keyboardShortcutsHandler.registerOnSharedPreferenceChangeListener(preferencesChangeListener)
}
private fun updateSummary() {
val spec = keyboardShortcutsHandler.findKey(action)
summary = spec?.toKeyString()
}
override fun displayDialog(fragment: PreferenceFragmentCompat) {
val df = KeyboardShortcutDialogFragment.newInstance(action)
df.setTargetFragment(fragment, 0)
df.show(fragment.fragmentManager, action)
}
class KeyboardShortcutDialogFragment : ThemedPreferenceDialogFragmentCompat(), DialogInterface.OnKeyListener {
private lateinit var keysLabel: TextView
private lateinit var conflictLabel: TextView
private var keySpec: KeyboardShortcutSpec? = null
private var modifierStates: Int = 0
override fun onDialogClosed(positiveResult: Boolean) {
}
override fun onPrepareDialogBuilder(builder: AlertDialog.Builder?) {
builder!!.setPositiveButton(android.R.string.ok, this)
builder.setNegativeButton(android.R.string.cancel, this)
builder.setNeutralButton(R.string.action_clear, this)
builder.setOnKeyListener(this)
}
override fun onKey(dialog: DialogInterface, keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN) {
if (KeyEvent.isModifierKey(keyCode)) {
modifierStates = modifierStates or KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode)
}
} else if (event.action != KeyEvent.ACTION_UP) {
return false
}
if (KeyEvent.isModifierKey(keyCode)) {
modifierStates = modifierStates and KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode).inv()
}
val preference = preference as KeyboardShortcutPreference
val action = preference.action
val contextTag = preference.contextTag
val handler = preference.keyboardShortcutsHandler
val spec = KeyboardShortcutsHandler.getKeyboardShortcutSpec(contextTag,
keyCode, event, KeyEvent.normalizeMetaState(modifierStates or event.metaState))
if (spec == null || !spec.isValid) {
Log.d(LOGTAG, String.format("Invalid key %s", event), Exception())
return false
}
keySpec = spec
keysLabel.text = spec.toKeyString()
val oldAction = handler.findAction(spec)
val context = context
if (action == oldAction || TextUtils.isEmpty(oldAction)) {
conflictLabel.visibility = View.GONE
(dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.setText(android.R.string.ok)
} else {
conflictLabel.visibility = View.VISIBLE
val label = KeyboardShortcutsHandler.getActionLabel(context, oldAction)
conflictLabel.text = context.getString(R.string.conflicts_with_name, label)
(dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.setText(R.string.overwrite)
}
return true
}
override fun onBindDialogView(view: View) {
super.onBindDialogView(view)
keysLabel = view.findViewById(R.id.keys_label)
conflictLabel = view.findViewById(R.id.conflict_label)
conflictLabel.visibility = View.GONE
}
override fun onClick(dialog: DialogInterface?, which: Int) {
val preference = preference as KeyboardShortcutPreference
val action = preference.action
val handler = preference.keyboardShortcutsHandler
when (which) {
DialogInterface.BUTTON_POSITIVE -> {
if (keySpec == null) return
handler.register(keySpec, action)
}
DialogInterface.BUTTON_NEUTRAL -> {
handler.unregister(action)
}
}
}
companion object {
fun newInstance(key: String): KeyboardShortcutDialogFragment {
val df = KeyboardShortcutDialogFragment()
val args = Bundle()
args.putString(PreferenceDialogFragmentCompat.ARG_KEY, key)
df.arguments = args
return df
}
}
}
}

View File

@ -58,7 +58,7 @@ class RandomizeAccountNamePreference @JvmOverloads constructor(
override fun displayDialog(fragment: PreferenceFragmentCompat) {
val df = RenameAccountsConfirmDialogFragment.newInstance(key, getPersistedBoolean(false))
df.setTargetFragment(fragment, 0)
df.show(fragment.childFragmentManager, key)
df.show(fragment.fragmentManager, key)
}
class RenameAccountsConfirmDialogFragment : PreferenceDialogFragmentCompat() {

View File

@ -30,7 +30,8 @@ import org.mariotaku.twidere.preference.iface.IDialogPreference
/**
* Created by mariotaku on 16/3/15.
*/
class ThemedEditTextPreference(context: Context, attrs: AttributeSet? = null) : EditTextPreference(context, attrs), IDialogPreference {
class ThemedEditTextPreference(context: Context, attrs: AttributeSet? = null) :
EditTextPreference(context, attrs), IDialogPreference {
override fun displayDialog(fragment: PreferenceFragmentCompat) {
val df = ThemedEditTextPreferenceDialogFragmentCompat.newInstance(key)

View File

@ -311,11 +311,11 @@ object MenuUtils {
}
R.id.set_nickname -> {
val nick = colorNameManager.getUserNickname(status.user_key)
val df = SetUserNicknameDialogFragment.show(fm,
status.user_key, nick)
val df = SetUserNicknameDialogFragment.create(status.user_key, nick)
if (fragment != null) {
df.setTargetFragment(fragment, REQUEST_SET_NICKNAME)
}
df.show(fm, SetUserNicknameDialogFragment.FRAGMENT_TAG)
}
R.id.open_with_account -> {
val intent = Intent(INTENT_ACTION_SELECT_ACCOUNT)