-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
30 changed files
with
1,570 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
app/src/main/java/cc/ioctl/nfcdevicehost/activity/base/BasePreferenceFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package cc.ioctl.nfcdevicehost.activity.base; | ||
|
||
import android.os.Bundle; | ||
import android.util.Log; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.fragment.app.FragmentActivity; | ||
import androidx.preference.EditTextPreference; | ||
import androidx.preference.ListPreference; | ||
import androidx.preference.MultiSelectListPreference; | ||
import androidx.preference.Preference; | ||
import androidx.preference.PreferenceFragmentCompat; | ||
import androidx.preference.PreferenceGroup; | ||
import androidx.preference.PreferenceScreen; | ||
import androidx.preference.TwoStatePreference; | ||
|
||
import com.google.android.material.snackbar.Snackbar; | ||
|
||
import cc.ioctl.nfcdevicehost.R; | ||
import cc.ioctl.nfcdevicehost.util.config.IConfigItem; | ||
import cc.ioctl.nfcdevicehost.util.config.PrefLutUtils; | ||
|
||
/** | ||
* Base class for all preference fragments. | ||
* Preference key name should be like "#default_config/generic:key_name$sub_key_name" | ||
* Each key should be unique and start with "#" | ||
* # [default_config/] generic:key_name [$sub_key_name] | ||
* 1.mmkv file name 2.group 3.key_name 4.sub_key_name(optional) | ||
*/ | ||
public abstract class BasePreferenceFragment extends PreferenceFragmentCompat implements | ||
Preference.OnPreferenceChangeListener { | ||
|
||
private static final String TAG = "BasePreferenceFragment"; | ||
|
||
protected FragmentActivity mActivity; | ||
|
||
@Deprecated | ||
@Override | ||
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { | ||
doOnCreatePreferences(savedInstanceState, rootKey); | ||
mActivity = getActivity(); | ||
initAllPreferences(); | ||
} | ||
|
||
protected abstract void doOnCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey); | ||
|
||
private void initPreference(Preference preference) { | ||
preference.setIconSpaceReserved(false); | ||
if (preference.getKey() != null) { | ||
preference.setPersistent(false); | ||
// find the config item | ||
String prefKey = preference.getKey(); | ||
if (prefKey == null) { | ||
return; | ||
} | ||
if (prefKey.startsWith("#")) { | ||
String fullName = prefKey.substring(1).replace("!", ""); | ||
IConfigItem<?> item = PrefLutUtils.findConfigByFullName(fullName); | ||
bindPreferenceToItem(preference, item, prefKey); | ||
preference.setOnPreferenceChangeListener(this); | ||
} | ||
} | ||
if (preference instanceof PreferenceGroup) { | ||
PreferenceGroup preferenceGroup = ((PreferenceGroup) preference); | ||
for (int i = 0; i < preferenceGroup.getPreferenceCount(); i++) { | ||
initPreference(preferenceGroup.getPreference(i)); | ||
} | ||
} | ||
} | ||
|
||
private void bindPreferenceToItem(@NonNull Preference preference, @Nullable IConfigItem rawItem, | ||
String keyName) { | ||
if ((rawItem == null || !rawItem.isValid()) | ||
&& (preference instanceof TwoStatePreference | ||
|| preference instanceof ListPreference | ||
|| preference instanceof MultiSelectListPreference | ||
|| preference instanceof EditTextPreference)) { | ||
preference.setEnabled(false); | ||
if (preference.getSummaryProvider() != null) { | ||
// remove summary provider | ||
preference.setSummaryProvider(null); | ||
} | ||
preference.setSummary(R.string.ui_summary_not_implemented); | ||
} else if (rawItem != null) { | ||
try { | ||
if (preference instanceof TwoStatePreference) { | ||
TwoStatePreference pref = (TwoStatePreference) preference; | ||
pref.setChecked((Boolean) (rawItem.getValue())); | ||
} else if (preference instanceof ListPreference) { | ||
ListPreference pref = (ListPreference) preference; | ||
pref.setValue(rawItem.getValue().toString()); | ||
} else if (preference instanceof EditTextPreference) { | ||
EditTextPreference pref = (EditTextPreference) preference; | ||
String value = (String) rawItem.getValue(); | ||
pref.setText(value == null ? "" : value); | ||
} | ||
} catch (Exception e) { | ||
Log.e(TAG, "bindPreferenceValue: ", e); | ||
preference.setSummary((e + "").replaceAll("java\\.[a-z]+\\.", "")); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public boolean onPreferenceChange(Preference preference, Object newValue) { | ||
try { | ||
String prefKey = preference.getKey(); | ||
if (prefKey == null) { | ||
return false; | ||
} | ||
if (prefKey.startsWith("#")) { | ||
String fullName = prefKey.substring(1).replace("!", ""); | ||
IConfigItem<?> item = PrefLutUtils.findConfigByFullName(fullName); | ||
if (item != null) { | ||
if (preference instanceof TwoStatePreference) { | ||
IConfigItem<Boolean> it = (IConfigItem<Boolean>) item; | ||
it.setValue((Boolean) newValue); | ||
} else if (preference instanceof ListPreference) { | ||
IConfigItem<String> it = (IConfigItem<String>) item; | ||
it.setValue((String) newValue); | ||
} else if (preference instanceof EditTextPreference) { | ||
IConfigItem<String> it = (IConfigItem<String>) item; | ||
it.setValue(newValue.toString()); | ||
} | ||
} | ||
} | ||
return true; | ||
} catch (Exception e) { | ||
Log.e(TAG, "onPreferenceChange: save error", e); | ||
Snackbar.make(mActivity.getWindow().getDecorView(), getString(R.string.ui_toast_save_error_v0s, | ||
e.getMessage()), Snackbar.LENGTH_LONG).show(); | ||
return false; | ||
} | ||
} | ||
|
||
protected void initAllPreferences() { | ||
PreferenceScreen preferenceScreen = getPreferenceScreen(); | ||
for (int i = 0; i < preferenceScreen.getPreferenceCount(); i++) { | ||
Preference preference = preferenceScreen.getPreference(i); | ||
initPreference(preference); | ||
} | ||
} | ||
|
||
@Override | ||
public void onResume() { | ||
super.onResume(); | ||
initAllPreferences(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
app/src/main/java/cc/ioctl/nfcdevicehost/activity/ui/settings/SettingsFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package cc.ioctl.nfcdevicehost.activity.ui.settings; | ||
|
||
import android.app.Activity; | ||
import android.os.Bundle; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.appcompat.app.ActionBar; | ||
import androidx.appcompat.app.AppCompatActivity; | ||
|
||
import cc.ioctl.nfcdevicehost.R; | ||
import cc.ioctl.nfcdevicehost.activity.MainUiFragmentActivity; | ||
import cc.ioctl.nfcdevicehost.activity.base.BasePreferenceFragment; | ||
|
||
public class SettingsFragment extends BasePreferenceFragment { | ||
|
||
@Override | ||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, | ||
@Nullable Bundle savedInstanceState) { | ||
Activity activity = getActivity(); | ||
if (activity instanceof AppCompatActivity) { | ||
ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar(); | ||
if (actionBar != null) { | ||
actionBar.setDisplayHomeAsUpEnabled(true); | ||
} | ||
} | ||
return super.onCreateView(inflater, container, savedInstanceState); | ||
} | ||
|
||
@Override | ||
public void onResume() { | ||
super.onResume(); | ||
Activity activity = getActivity(); | ||
if (activity instanceof MainUiFragmentActivity) { | ||
((MainUiFragmentActivity) activity).hideFloatingActionButton(); | ||
} | ||
} | ||
|
||
@Override | ||
public void doOnCreatePreferences(Bundle savedInstanceState, String rootKey) { | ||
setPreferencesFromResource(R.xml.root_preferences, rootKey); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
app/src/main/java/cc/ioctl/nfcdevicehost/util/annotation/ConfigGroup.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package cc.ioctl.nfcdevicehost.util.annotation; | ||
|
||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.Target; | ||
|
||
import androidx.annotation.NonNull; | ||
|
||
@Target({ElementType.TYPE, ElementType.FIELD}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface ConfigGroup { | ||
// TODO: 2021-12-21 add KAPT processing for this annotation | ||
@NonNull String value(); | ||
} |
56 changes: 56 additions & 0 deletions
56
app/src/main/java/cc/ioctl/nfcdevicehost/util/config/AbsObservableItem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package cc.ioctl.nfcdevicehost.util.config; | ||
|
||
import androidx.lifecycle.LiveData; | ||
|
||
import cc.ioctl.nfcdevicehost.util.ThreadManager; | ||
|
||
public abstract class AbsObservableItem<T> extends LiveData<T> implements IObservable<T>, IConfigItem<T> { | ||
/** | ||
* The data of the item is always provided by the {@link #getValue()} method. | ||
* This AbsObservableItem itself is not responsible for providing the data. | ||
*/ | ||
protected AbsObservableItem() { | ||
super(); | ||
} | ||
|
||
@Override | ||
public abstract T getValue(); | ||
|
||
protected abstract void setValueInternal(T value); | ||
|
||
@Override | ||
public abstract boolean isValid(); | ||
|
||
/** | ||
* Called when the value of the item has changed by any means, eg. by another process. | ||
* It's not required to call this method if value is changed by calling {@link #setValue(Object)} | ||
* | ||
* @param newValue the new value of the item | ||
*/ | ||
protected void notifyItemChanged(T newValue) { | ||
if (ThreadManager.isUiThread()) { | ||
super.setValue(newValue); | ||
} else { | ||
ThreadManager.runOnUiThread(() -> super.setValue(newValue)); | ||
} | ||
} | ||
|
||
@Override | ||
public void setValue(T value) { | ||
if (ThreadManager.isUiThread()) { | ||
setValueInternal(value); | ||
super.setValue(value); | ||
} else { | ||
ThreadManager.runOnUiThread(() -> { | ||
setValueInternal(value); | ||
super.setValue(value); | ||
}); | ||
} | ||
} | ||
|
||
@Override | ||
protected void postValue(T value) { | ||
setValueInternal(value); | ||
super.postValue(value); | ||
} | ||
} |
Oops, something went wrong.