Android Edit Text Preference with own layout with no newValue on onPreferenceChange - android

I've got with my own layout.
I would like to receive the text from the editText after positive button on the layout is clicked. But in onPreferenceChange, I always get only the default value.
It seems that I need to bind my own EditText to the preferences somehow, but I don't know how and where to do this.
Can anybody help me?

To answer my own question:
First of all, in PreferenceScreen, you need to state:
<full.path.to.your.OwnLayoutClass
android:name="whatevever"
android:dialogLayout="#layout/your_own_layout" />
your_own_layout can be anything you'd like, linearlayout with of buttons, editTexts, according to your wishes.
Essential is the class representing your own preference Dialog. Here is a simple example of how to do it:
public class YourOwnLayoutClass extends DialogPreference {
private LinearLayout mView;
public YourOwnLayoutClass(Context context, AttributeSet attrs) {
super(context, attrs);
setPersistent(false);
setDialogLayoutResource(R.layout.your_own_layout);
}
#Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mView = (LinearLayout) view;
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
// get value from editFields, do whatever you want here :)
// you can acces them through mView variable very easily
}
}
}
Important references:
I need to have a custom dialog in Preferences
Concise way of writing new DialogPreference classes?
Android: launch a custom Preference from a PreferenceActivity

Related

How to make a custom Preference layout launch a Dialog Fragment and react to Button?

I have made the custom layout for the preference layout with one button and the text view .How to open the dialog fragment when user click on the text view field and also interact the button on the field ?
This is What i want ,
when the toggle button is off .The person cant open the dialog fragment .Once the toggle button is enabled the dialog fragment will get active and user can edit the value and that will get update in summary.
Preference.xml
<com.example.app.Utils.CustomIPPreference
android:key="#string/pref_manual_IpKey"
android:title="Set Device Ip manually"
android:summary="#string/default_ip" />
CustomIPPreference.java
public class CustomIPPreference extends Preference {
public CustomIPPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setLayoutResource(R.layout.custom_ip_device_select);
}
#Override
protected void onBindView(View view) {
LinearLayout layout = view.findViewById(R.id.ManualIPBOX_layout);
SwitchCompat switchCompat = view.findViewById(R.id.manualIpToggle);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LogUtils.e("pref_manual_IpKey");
CustomIpDialog customIpDialog = new CustomIpDialog();
customIpDialog.show(getFragmentManager(), "Frag"); //getFragmentManager not found error
}
});
switchCompat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LogUtils.e("APP", "TOGGLE");
}
});
super.onBindView(view);
}
The getFragmentManager is giving me error in the code. If i use Dialog preference i cant add a toggle button in right .How can i make Both interact ?
I am not able to find any reference related to this.Please help me out!!

How to show/hide buttons of custom dialog in preferences dynamically?

I have created a custom dialog that is used from a preference screen. Everything works fine except one thing: I want to switch the visibility of the Cancel button based on the status of an internal check.
Normally you have onPrepareDialog and onCreateDialog and you can do this in onCreateDialog. But here we have onPrepareDialogBuilder... so where is onCreateDialogBuilder? Where can I do something like
builder.setNegativeButton(null, null);
after onPrepareDialogBuilder? I cannot do it IN onPrepareDialogBuilder since I need the Cancel button in case the internal check fails.
Can you please help me to get into the right direction?
public UnlockPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.dialog_enter_registration);
}
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setTitle(R.string.label_enter_registration);
}
// would need something like
#Override
protected void onCreateDialogBuilder(AlertDialog.Builder builder) {
super.onCreateDialogBuilder(builder);
if (internalCheckOk())
builder.setNegativeButton(null, null);
else
builder.setNegativeButton(..., ...);
}

popup window pref android

I want to implement an about box in my wallpaper. For that, I want a window to show up which contains the information when a user clicks on it.
None of the available controls like checkbox, listview etc. can be used for this......
I also tried to make a Dialog Pref by following advice from some other questions I looked at but ended up with a dialog that just does not seem appropriate for an about box.
My DialogPref:
public class DialogPref extends DialogPreference {
public DialogPref(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
persistBoolean(positiveResult);
}
}
So can you help me implement a popup window for an about box?

Save state on screen rotate when a compound component is used multiple times

I'm facing a problem where I know the root cause but don't see a way to fix it. If a custom compound component is used multiple times in an activity, the values saved from views will overwrite each other. To explain it easier I made the following example.
The xml for the new component, only an EditText to make it shorter.
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<EditText
android:id="#+id/custom_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number" >
</EditText>
</merge>
The class implementing the new behavior, only inflating the layout.
public class CustomView extends LinearLayout {
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.custom_view, this, true);
}
}
And a layout using 2 of them.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<test.customview.CustomView
android:id="#+id/customView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</test.customview.CustomView>
<test.customview.CustomView
android:id="#+id/customView2"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</test.customview.CustomView>
</LinearLayout>
When the screen is rotated, the value from second View is also restored in the first one.
Digging into the framework's code I found out that Parcelable objects returned from onSaveInstanceState defined in View class are put in a SparseArray with the key object's id. Because I'm including CustomView multiple times the EditText with id "custom_text" is also getting added multiple times. Having the same id, values saved will overwrite each other.
I'm looking for any suggestion on how this should be actually implemented. Right now, I don't see any way to change those identifiers.
Seems like I have some solution with this problem. I try to find it for some time.
1.First you must create inner class which extends BaseSavedState, inside your CustomView.
CustomView{
String value; //some text value from edittext
EditText edittext;
...
private static class Save extends BaseSavedState{
String savedValue;
public Save(Parcel incoming) {
super(incoming);
savedValue = incoming.readString();
Log.i("Save", "Parcel");
}
public Save(Parcelable parcelable) {
super(parcelable);
Log.i("Save", "Parcelable");
}
#Override
public void writeToParcel(Parcel outcoming, int flags) {
super.writeToParcel(outcoming, flags);
outcoming.writeString(savedValue );
Log.i("Save", "writeToParcel");
}
public static final Parcelable.Creator<Save> CREATOR =
new Creator<CustomView.Save>() {
#Override
public Save[] newArray(int size) {
Log.i("Parcelable.Creator<Save>", "newArray");
return new Save[size];
}
#Override
public Save createFromParcel(Parcel incoming) {
Log.i("Parcelable.Creator<Save>", "createFromParcel");
return new Save(incoming);
}
};
}
}
2.then override this two methods in CustomView
CustomView{
String value; //some text value from edittext
EditText edittext;
...
#Override
protected Parcelable onSaveInstanceState() {
Log.i("CustomView", "onSaveInstanceState");
Parcelable p = super.onSaveInstanceState();
Save save = new Save(p);
save.savedValue = value; // value is from CustomView class
return save;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
Log.i("CustomView", "onRestoreInstanceState");
if(!(state instanceof Save)){
super.onRestoreInstanceState(state);
return;
}
Save save = (Save) state;
value = save.savedValue;
//setting in this place value to edittext will not do anything.
//instead, you have to do this in step 3
super.onRestoreInstanceState(save.getSuperState());
}
...
}
3.override onAttachedToWindow() and set to edittext "value".
CustomView{
String value; //some text value from edittext
EditText edittext;
...
#Override
protected void onAttachedToWindow() {
edittext.setText(value);
super.onAttachedToWindow();
}
...
}
and now you can have multiple instances of your Custom View 's that are resistant to change orientation - they will have the correct values.I have not tested this solution in 100% but it seems to be good.

Disable, reenable and the soft keyboard does not appear on touch

Take a look at this example:
public class TestEditSoftKbdActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.editText1).setFocusable(false);
findViewById(R.id.editText1).setClickable(false);
findViewById(R.id.editText1).setEnabled(false);
findViewById(R.id.editText1).setFocusable(true);
findViewById(R.id.editText1).setClickable(true);
findViewById(R.id.editText1).setEnabled(true);
findViewById(R.id.editText1).invalidate();
findViewById(R.id.editText1).requestLayout();
}
}
After this sequence of calls the edit text view would no longer pop up its soft input method upon being touched :(
Could someone explain what is going wrong here?
If you want to close soft keyboard for your text view follow this link. Here is a solution for you. But you need to define your own TextView to do that. He suggests using;
public class NoImeEditText extends EditText {
public EditTextEx(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onCheckIsTextEditor() {
return false;
}
}
Hope it works.

Categories

Resources