Android YesNoDialogPreference - android

You may think this is a duplicate question but i looked up almost every existing answer and i still did not get it right. Here is my question:
I want to create a default YesNoDialogPreference by extending the DialogPreferenceclass
Creating a preference using YesNoDialogPreference in prefs.xml
In the MainActivity i want to set an onClickListener for Yes and No options
I have tried doing this using AlertDialog.Builder but it didn't work, i've also tried to use com.android.internal.preference.YesNoPreference and it did work cause of R.attr error
Can somebody please give me a full answer...PLEASE!!, i have been struggling with this for weeks now.
Here's my code:
YesNoDialogPreference.java
import android.content.Context;
import android.preference.DialogPreference;
import android.util.AttributeSet;
public class YesNoDialogPreference extends DialogPreference {
public YesNoDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
persistBoolean(positiveResult);
}
}
The preference from prefs.xml
<com.me.myapp.YesNoDialogPreference
android:key="KEY"
android:dialogMessage="You sure ?"
android:title="Do something"
android:summary="will do something"
/>
I do not know how to link them in the MainActivity.

What you are trying to achieve does not make sense. The MainActivity is not active so can't be the target of the dialog.
You need an onClick handler in your YesNoDialogPreference which then does what you want. You typically safe the value in your settings and read that value in all other places - like your MainActivity.
Here is a code sample:
How to get the DialogPreference POSITIVE_BUTTON to work on OnClick?

Just use onClick method and implement listener to provide handle actions where you want
#Override
public void onClick(DialogInterface dialog, int which){
if(which == DialogInterface.BUTTON_POSITIVE) {
// do your stuff to handle positive button
}else if(which == DialogInterface.BUTTON_NEGATIVE){
// do your stuff to handle negative button
}
}

Related

Clear password field in other activity on exit

I need to clear password field on exit of app,i am exiting the app in other activity and on exit it goes to mainActivity which has login details in which i need to clear password field,how will i do this in other activity ,i tried using setText("") but in vain.
public void backButtonHandler() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
ReminderActivity.this);
// Setting Dialog Title
alertDialog.setTitle("Leave application?");
// Setting Dialog Message
alertDialog.setMessage("Are you sure you want to leave the application?");
// Setting Positive "Yes" Button
alertDialog.setPositiveButton("YES",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//I need to clear here all pwd data present in MainActivity in edittext
finish();
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("NO",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
In your MainActivity do like this:
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
editText.SetText("");
}
So, it will clear editText value, whenever your MainActivity will get resumed.
Or when you click the login button do
editText.SetText("");
Then it will be cleared before another activity starts
Using setText won't work and may even throw some type of NPE if your activity is no longer in memory.
There are a couple of ways you can do this depending on your requirements:
You can simply clear the text field in the activity/fragment's onStop or onDestroy overrides
If you absolutely have to set the text field from a different activity, then I suggest the following design:
In your Application class, create a nested class that implements ActivityLifeCycleCallbacks. This is a great class to implement as it allows you to monitor the state of all of your activities. It resolved a lot of problems for me
If you have a singleton model, or static String value that binds to your password TextView then you're almost there (other workarounds available if you give us more info).
So let's look at some code:
Design 1:
public void onStop()
{
super.onStop();
myTextField.setText("");
}
Your Application class:
public class MyApplication extends Application
{
...
private static final class MyActivityLifeCycleCallback implements ActivityLifecycleCallbacks
{
#Override
public void onActivityStopped(Activity activity)
{
//Here, I am assuming that your class name is MainActivity
Log.i(TAG, "onActivityStopped:" + activity.getLocalClassName());
if("MainActivity".isEqual(activity.getLocalClassName())
{
myDataModel.getInstance().setPassword("");
//or if your password String member is static
//((MainActivity)activity).myPasswordMember = "";
}
//Or if you want to only clear the password text when RAActivity stops, simply replace "MainActivity" with the RAActivity class name.
}
#Override
public void onActivityDestroyed(Activity activity,
Bundle savedInstanceState)
{
Log.i(TAG, "onActivityDestroyed:" + activity.getLocalClassName());
if(activity.getLocalClassName().contains("MySecondActivity"))
{
//reset your password here - implementation will depend on how you have your data model organized (private, singleton, static, etc.)
}
}
....
}
Remember that this design would work well with some type of a singleton or central data model (think MVC architecture) so that you can propagate the change in data to your components.
Hope it helps
EDIT:
I have added the code according to your comment. But to be honest, I think it's a better idea to simply call the setText("") method in the MainActivity's onStop function like I suggested. This is a simple problem and my second design might be a bit too much. Anyway, the code is updated, so if you like it, mark it as an answer :)
Here's another idea. IF RAActivity calls MainActivity again (probably not) using startActivity, you can simply pass a bundle value to MainActivity that tells it that it's coming from RAActivity. That way, MainActivity can clear the password if it was called from RAActivity. Lots of options.

Callback When DialogFragment is Dismissed

I want to launch a dialog with a custom layout, which I've implemented via a DialogFragment. (I basically just changed onCreateView() and added button handlers). The dialog lets the user quickly change an important setting.
This dialog will be launched from several different activities. The different activities don't have much in common, except that they need to refresh after the user makes a change to the setting. They don't need to get any information from the dialog; they merely need to know when it's closed (dismissed).
What I've Tried
I tried having the activity refresh in onResume(), but launching and dismissing a dialog never seems to call this method. (So I'm not sure why it even exists, but that's probably a topic for another question.)
Next, I tried adding a DialogInterface.OnDismissListener to the dialog:
public static void showMyDialog(OnDismissListener listener, Activity activity)
{
DialogFragment fragment = new MyDialogFragment();
fragment.show(activity.getFragmentManager(), "date");
activity.getFragmentManager().executePendingTransactions();//A
fragment.getDialog().setOnDismissListener(listener);//B
}
When I originally left out the line A, I got a NullPointerException on line B because the dialog is null at that point. Following the advice of this SO answer, I put in the call to executePendingTransaction(). This causes an IllegalStateException on line B, with the message "OnDismissListener is already taken by DialogFragment and cannot be replaced." I also tried putting setOnDismissListener() before the call to show(), but that always caused a NullPointerException.
I then read this other SO answer, which says the original asker was "calling getDialog() too early in the DialogFragment's life cycle." So I tried adding a constructor to my DialogFragment:
public MyDialogFragment(SomeCallback illTakeAnythingICanGet)
{
//I'll store the callback here and call it later
}
Unfortunately, adding a constructor made Android Lint freak out with a fatal warning, and when I looked it up, I found a comment in this question that seems to say this approach will make it impossible to deal with the user rotating the screen while the dialog is open.
The Question
How can an activity figure out when a DialogFragment has closed (been dismissed) in a way that won't break my app if the user rotates the screen? Should I be using something else besides a DialogFragment?
This is just a longer explanation of harism's comment in case anyone else has the same problem I did.
You can accomplish what I wanted by creating an interface like this:
public interface MyDialogCloseListener
{
public void handleDialogClose(DialogInterface dialog);//or whatever args you want
}
Have the activity that launches your dialog (DialogFragment) implement this interface. Then give that DialogFragment the following method:
public void onDismiss(DialogInterface dialog)
{
Activity activity = getActivity();
if(activity instanceof MyDialogCloseListener)
((MyDialogCloseListener)activity).handleDialogClose(dialog);
}
More explanatory code for someone to do the same.
Create the interface as:
package com.example.dialoglistener;
import android.content.DialogInterface;
public interface MyDialogCloseListener {
public void handleDialogClose(DialogInterface dialog);
}
Implement the interface in activity as:
MyDialogCloseListener closeListener = new MyDialogCloseListener() {
#Override
public void handleDialogClose(DialogInterface dialog) {
//do here whatever you want to do on Dialog dismiss
}
};
Write a DismissListener in DialogFragement as
public void DismissListener(MyDialogCloseListener closeListener) {
this.closeListener = closeListener;
}
call DismissListener from your activity as:
dialogFragementObject.DismissListener(closeListener);
and finally write onDismiss method
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if(closeListener != null) {
closeListener.handleDialogClose(null);
}
}
Tyler's example was the only example I could find that actually worked. The only thing that needs changed for the example to work is the call to the DismissListner method in the DialogFragment class. He has it as:
dialogFragementObject.DismissListner(closeListener);
This just needs to be a cast to whatever your class name of that DialogFragment is. For example:
((MyDialogFragment)dialogFragementObject).DismissListner(closeListener);

Android Preference - replace preference function

I have an EditPreference in a PreferenceActivity and I have a variable that tells me if I should allow the user to access this preference or to show some alert.
My problem is that I couldn't find how to cancel the preference dialog before it's displayed and to show my alert (according to the variable).
I tried to return true/false in the preference onClick or in onTreeClick but that didn't do anything, the dialog still popped.
On Android 2.1+ .
Thanks.
The DialogPreference.onClick(), which handles clicks to the preference itself, is protected, so you can't override it in your own PreferenceActivity class members.
However, you can extend the class to achieve what you need. Below is a very minimalist example:
package com.example.test;
import android.content.Context;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
public class MyEditTextPreference extends EditTextPreference {
private Runnable alternative = null;
public MyDatePickerDialog(Context context,
AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyDatePickerDialog(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyDatePickerDialog(Context context) {
super(context);
}
public void setAlternativeRunnable(Runnable runnable) {
alternative = runnable;
}
// this will probably handle your needs
#Override
protected void onClick() {
if (alternative == null) super.onClick();
else alternative.run();
}
}
In your XML file:
<com.example.test.MyEditTextPreference
android:key="myCustom"
android:title="Click me!" />
In your PreferenceActivity:
MyEditTextPreference pref = (MyEditTextPreference) this.findPreference("myCustom");
pref.setAlternativeRunnable(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplication(), "Canceled!", Toast.LENGTH_SHORT)
.show();
}
});
As a final note, let me say that whenever you can't find a way to do what you want, think about taking a look at how the Android classes themselves work. Most of the times, they will give you good insights to achieve what you want.
In this case, it's the DialogInterface.onClick() method, as described above. So you know you need to override it somehow to achieve that. In this case, the solution is extending the EditTextPreference class itself.

How can I build a dialog which is launched by a service?

I think my problem is easy to fix for you. I have a service running in the background and starting an Intent which starts an activity, which opens a dialog.
Her is my code from the service:
Intent todialog = new Intent();
todialog.setClass(myService.this, openDialogInSleep.class);
todialog.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(todialog);
and here is the activity:
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
public class openDialogInSleep extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AlertDialog.Builder(openDialogInSleep.this)
.setTitle("huhu")
.setNeutralButton("close", null);
}
}
Finally the android manifest:
<activity android:name=".openDialogInSleep" android:theme="#android:style/Theme.Dialog"></activity>
My Problem is, that there is not shown the dialog with the title "huhu" and the button "close". There is only shown a dialog in a strange form which simply shows a part of my activityname.
What did I forget?
Please help me.
mfg. Alex
You forget to chain in show() to actually show your dialog.
new AlertDialog.Builder(openDialogInSleep.this)
.setTitle("huhu")
.setNeutralButton("close", new OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
openDialogInSleep.this.finish();
}
})
.show();
One thing you have missed is to call show() on the dialog generated by the AlertBuilder.
UPDATE
If I understand you correctly you don't want the activity to take control of the screen but rather just show the dialog?
If that is the case I don't think it is possible, the only way you can create a similar effect is by using a Toast Message. This can be launched from your Service and you wouldn't require the activity at all.

Trying to call an activity, but having troubles with onClick

im trying to run this simple code (im a beginner :).
trying to run this. the // text is usually what i use for buttons. however, i saw this switch technique that i wanted to try, it seemed more efficient. however, i get errors related to the onClick (something about the ( ) and that 'void is an invalid type'). i have no idea what can cause this. just wanna access the buttons. can anyone please tell me why?
Thanks!
package com.experiment.fewops;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class FewOptions extends Activity {
/** Called when the activity is first created. */
final Button sexy = (Button) findViewById(R.id.buttonSexy);
final Button text = (Button) findViewById(R.id.buttonText);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// sexy.setOnClickListener(new View.OnClickListener() {
//
// #Override
// public void onClick(View v) {
// Intent intent = new Intent(this, SexyPage.class);
// startActivity(intent);
// }
// });
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.buttonSexy:
Intent intent = new Intent(this,SexyPage.class);
startActivity(intent);
break;
}
};
}
}
There are actually 2 problems here:
First, as #Saiesh said, if you want to implement the click listener at the class level, you need to change your class declaration to implment OnClickListener. So your declaration will look like
public class FewOptions extends Activity implements OnClickListener{
The second problem (and the reason you're getting the error about void being a bad type) is that you're declaring the onClick method in the body of your onCreate method. move the declaration of the onClick method outside the closing brace (}) of the onCreate method and that error should go away.
One more note: after you make the 2 fixes above, don't forget to add your class as the click listener for the button:
sexy.setOnClickListener(this);
You need to pass right context
Intent intent = new Intent(FewOptions.this,SexyPage.class);
FewOptions.this.startActivity(intent);
Well the solution is that to use this onClick() method your class needs to implement the onClickListener interface . Thus your class heading should be something like this
public class FewOptions extends Activity implements onClickListener
{
//Eclipse will automatically ask you to override the onClick() method
}
So thats the solution :)

Categories

Resources