Can one show a dialog in superclass? - android

I have a subclass of ListActivity that is reused throughout my project, subclassed again so that each reports to a different ActivityGroup. This is working beautifully until I try to present a dialog in the superclass (as this behaviour should be exhibited by each subclass), and I get the following error:
ERROR/AndroidRuntime(31514): FATAL EXCEPTION: main
ERROR/AndroidRuntime(31514): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
Now, I think this is due to the context that is being fed into the AlertDialog.Builder. I am using standard sample code from Google. Any ideas appreciated.
final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
alert.show();

The problem here is that the activity is part of an ActivityGroup. You cannot open a dialog with a context of the current activity in the ActivityGroup, instead provide the context of the ActivityGroup itself.
In the Activity from which you want to present the dialog:
ProgressDialog dialog = new ProgressDialog(MyActivityGroup.group);
In the ActivityGroup subclass, MyActivityGroup, define your static reference:
public static MediaMenuGroup group;
then
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
group = this;
...

Related

Refresh an activity from another activity Android

I need to reload an activity from another activity in android application. That 2nd activity is a dialog window, and based on the dialog window base activity should refresh the contents. (By click button of dialog activity)
Reload your activity.
context.startActivity(context.getIntent());
context.finish();
Consider A is an activity you want to reload and B is another activity.
In this case, just call finish()
when you are moving from A to B. When you call A from B it will load the activity A again.
Dialog Window and activity is completely deferent things.
It is possible to refresh First Activity from it's dialog. You can do it using interface.
Here is simple solution. In your First Activity implements a Interface name IRefreshInteface. It's definition is like bellow:
public interface IRefreshInteface(){
public void doRefreshValue(String commandValue);
}
Now if you implement IRefreshInteface in your activity you will get method doRefreshValue(String commandValue) and write refresh code here.
#Override
void doRefreshValue(String commandValue){
// Write refresh code here
}
Now in your dialog you have Context of your Activity. Using that context object you can call this doRefreshValue(String commandValue) method easily. Here is the sample code :
public AlertDialog displayMessage(Context context, String title, String message){
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(title);
builder.setMessage(message);
LayoutInflater inflater = LayoutInflater.from(context);
final View v = inflater.inflate(R.layout.custom_view, null);
builder.setView(v);
shipText = (EditText)v.findViewById(R.id.shipNameEditText);
scientistNameText = (EditText)v.findViewById(R.id.scientistEditText);
scientistEmailText = (EditText)v.findViewById(R.id.emailEditText);
volumeText = (EditText)v.findViewById(R.id.volumeEditText);
colourText = (EditText)v.findViewById(R.id.colourEditText);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((IRefreshInteface) context).doRefreshValue("YOUR_COMMAND");
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog dialog= builder.create();
dialog.show();
Button tb = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
tb.setOnClickListener(new CustomListener(dialog));
return dialog;
}
here, pass Context of Activity todisplayMessage() method and call activity method doRefreshValue using this way:
((IRefreshInteface) context).doRefreshValue("YOUR_COMMAND");
For more info visit here and here
Hope this will solve your problem. Sorry for bad english :)

Best Practice to call a login dialog in Android

I'm building an Android application and that aplication have an open part and some actions that need authentication.
What I do is to when the user click on an action that needs authentication a login dialog is show, the user can login and the login will be valid for 30 minutes.
So I have 3 buttons in an fragment that when clicked check if the user is logged in, an if not calls a login dialog.
The problem is: How can I identify what button was clicked, because when the user click the button and is not authenticated I just create the login dialog and set the setTargetFragment to the caller fragment, that was the same for the 3 buttons.
Is there a way to pass a parameter to the login dialog to identify that?
The code are as following:
When the user click the button:
final DialogFragment loginDialog = new LoginDialogFragment();
loginDialog.setTargetFragment(this, 0);
btnAprovar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!LoginService.getInstance().isLoggedOn()) {
loginDialog.show(getFragmentManager(), "Login");
}
}
});
And In the dialog:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.fragment_login_dialog, null);
final EditText txtUser = (EditText) v.findViewById(R.id.txtUsername);
final EditText txtPwd = (EditText) v.findViewById(R.id.txtPassword);
builder.setView(v)
.setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
DoLogin dl = new DoLogin();
dl.execute(txtUser.getText().toString(), txtPwd.getText().toString());
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LoginDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
private void DoPost(Boolean _result) {
if (_result.equals(true)) {
((PublicacaoDetailFragment) this.getTargetFragment()).onAuthTrue();
} else {
((PublicacaoDetailFragment) this.getTargetFragment()).onAuthFalse();
}
}
What is the best Practice to do that?
Thanks
To extend #Rodolfo's answer, you should probably use the decorator/wrapper pattern here.
Instead of extending DialogFragment, in your LoginDialogFragment you should just have an instance variable of a DialogFragment. This way, you can have a method called show(String buttonDescription), for example. Inside your own show(...) method, you can call the show() method of the DialogFragment.
Since you are extending DialogFragment in a class of your own, you have two choices:
Define a variable (with getter and/or setter) inside your custom Dialog class. In your login button onClick method, before calling show() of your Dialog, call the setter for this variable and pass v.getId(). In this case, v is the View associated with the component that you've added the OnClickListener.
Pass your button View id within a Bundle to your DialogFragment.

Dialog error when open from a Adapter + ListView

I have a little problem with a Dialog.
It's a ListView of Videos with thumbnails that load the videos with an Adapter. The ListView register an OnItemClickListener and inside the OnClickItem method I try to raise the Dialog.
I've tried with various types of Dialog but nothing happened. A simplified piece of code it's here:
public class ListOfVideos extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_of_videos);
init_phone_video_grid();
}
private void init_phone_video_grid() {
// Here's some code for the video reading
// The ListView
videolist = (ListView) findViewById(R.id.PhoneVideoList);
videolist.setAdapter(new VideoAdapter(getApplicationContext()));
videolist.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Here's some code for the video reading
/** ============= Here's the problem ================ **/
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setMessage("Example Message")
.setTitle("This is the title!!")
.setCancelable(false)
.setNeutralButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
System.out.println("[debug]" + "Open File " + filename);
}
});
}
The list of videos load perfectly. But when I click on an Item:
The Dialog does not show
I got a error message in the LogCat, that state: "show() Dialog's window is null!"
The println debug message, appears ok in the LogCat
I have searched for that message error, but there's not much information.
I think the problem could be on the Context that receive the Builder, but I'm stuck on this point.
Any advice will be apreciated
That error message is saying that the Context given to the AlertDialog.Builder has no attached window, which Dialogs need as a UI anchor, basically. An Activity is what should be used for such a Context, as it will have the required window.
Without seeing VideoAdapter's code, the root cause is presumably new VideoAdapter(getApplicationContext()), which is handing your VideoAdapter the application Context to build Views with. That likely means that the v passed into onItemClick() is one such View, and v.getContext() is returning that application Context in new AlertDialog.Builder(v.getContext()).
That application Context does not have a window but your Activity does, as mentioned. Furthermore, the Activity is actually what you want to give to VideoAdapter to build Views with anyway, to ensure that they are created with the correct theme and styling. Change that relevant line to:
videolist.setAdapter(new VideoAdapter(ListOfVideos.this));
That alone might solve the issue, depending on what VideoAdapter does internally. However, it's arguably better to specify the Activity again in the AlertDialog.Builder constructor call, just so there's no question:
AlertDialog.Builder builder = new AlertDialog.Builder(ListOfVideos.this);
As a final note, whenever a Context is needed for any UI component, you usually want to use the immediately available Activity.
Here is a example of How to create dialog box..
String message = "Hello";
AlertDialog.Builder alt_bld = new AlertDialog.Builder(
CurrentActi.this);
alt_bld.setTitle("Alert")
.setMessage(message)
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//here right the code that you want perform onClick
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = alt_bld.create();
alert.setTitle("Alert");
alert.show();
May be it will help you..

closing dialog on clicking outside

What I want is a dialog without any button, and closing that dialog when I click outside the dialog body. Is it possible?
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
openCredit();
}
//THIS IS ONE CUSTOM DIALOG
public void openCredit(){
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = MainActivity.this.getLayoutInflater();
builder.setView(inflater.inflate(R.layout.activity_splash, null));
builder.show();
}
}
EDIT: I have search and found two functions setCanceledOnTouchOutside() and setCancelable(). First one is not working with my method of AlertDialog, giving error of "The method setCanceledOnTouchOutside(boolean) is undefined for the type AlertDialog.Builder". And 2nd one is just for pressing back button.
So, I change my code like below and it is now working. Thanks.
public void openCredit(){
AlertDialog builder = new AlertDialog.Builder(this).create();
LayoutInflater inflater = MainActivity.this.getLayoutInflater();
builder.setView(inflater.inflate(R.layout.activity_splash, null));
builder.setCancelable(true);
builder.show();
builder.setCanceledOnTouchOutside(true);
}
Have you tried this..
builder.setCancelable(true);
Add this line for doing this
builder.setCancelable(true);

Android Custom List Dialog

Could someone point out a working example of a custom dialog that takes an ArrayAdapter as input and shows a selectable list.
I have tried to create a Dialog using an AlertDialog Builder as such...
final ArrayAdapter<MyObject> myAdapter = getMyobjects();
final AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle("Pick an item").setAdapter(myAdapter,
new android.content.DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int item) {
Toast.makeText(Islands.this, myAdapter.getItem(item).toString(), Toast.LENGTH_SHORT).show();
}
});
final AlertDialog alert = builder.create();
return alert;
My problem is that my dialog is not updating then i called
#Override
protected void onPrepareDialog(final int id, final Dialog dialog) {
switch (id) {
case DIALOG_GET_AVAIL_DESTS:
((AlertDialog) dialog).getListView().setAdapter( getDestinations());
break;
}
}
However the onClick listener listens to the initial set of items...
Indeed AlertDialog is implements Facade design pattern with this class behind :
http://www.netmite.com/android/mydroid/frameworks/base/core/java/com/android/internal/app/AlertController.java
And the whole code is such a mess...
I took 3 hours to try to do that, and I am going to build a dialog from scratch, using android.R.layout as a basis.
Steff
You have to make a call to
invalidateViews()
on your listview - that will cause it to redraw the view with the updates.
Since you are using onPrepareDialog(int id, Dialog dialog), I am guessing you're initially setting up the dialog in onCreateDialog(int id).
Doing so cause the system to save the dialog you initially create. In order to achieve the desired functionality, when the dialog is dismissed, tell the system to discard it by calling android.app.Activity.removeDialog(int id).
Any subsequent invocations will have your dialog regenerated through the onCreateDialog(int id) method, causing the set of items to be updated.

Categories

Resources