I have searched for an answer to this question but none of the answers helped me.
The problem is that I have a DialogFragment that is displayed when a user add a widget (as part of the WidgetConfig). It looks like this:
The dialog is created like this;
Calling activity:
public class AppWidgetConfigure extends Activity {
private void setUp(){
//Config widget code removed
DialogFragment dialog = new ChooserDialog();
dialog.show(getFragmentManager(), "dialog");
}
}
the DialogFragment:
public class ChooserDialog extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
choices = getResources().getStringArray(R.array.choices);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getResources().getString(R.string.widget_dialog_chooser_title));
builder.setPositiveButton(getResources().getString(R.string.widget_dialog_chooser_posBtn), this);
builder.setNegativeButton(getResources().getString(R.string.widget_dialog_chooser_negBtn), this);
builder.setSingleChoiceItems(choices, -1, this);
return builder.create();
}
}
I want the dialog to have a transparent background. Currently, as shown in the picture, there is the WidgetConfigure activity as background.
Thankful for any help.
Marcus
Using below code we can get transparent AlertDialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),android.R.style.Theme_Translucent);
But in your case you have some choices to be displayed in alert dialog. In that case you need to create a layout with transparent background with choice list and set that layout to dialog.
something like this
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog, null);
builder.setView(view);
Related
I have a custom dialog which extends AppCompatDialogFragment. I am calling it from within one Fragment of a BottomNavigationBar. It gets dismissed when a message is returned from a ListenerService. It all works well until I switch to a different fragment using one of the icons on the BottomNavigationBar and then back to the fragment with Dialog functionality. The next time I show the dialog the message does not dismiss it.
I have a member variable:
SendingMessageDialog sendingMessageDialog;
When I click a button it calls this to show the dialog:
sendingMessageDialog = new SendingMessageDialog();
sendingMessageDialog.show(getActivity().getSupportFragmentManager(), "Sending Message");
When the message is receive I call this:
sendingMessageDialog.dismiss();
sendingMessageDialog = null;
I have also tried it this way:
private void dismissDialog() {
Fragment prev = getActivity().getSupportFragmentManager().findFragmentByTag("Sending Message");
if (prev != null) {
Log.d(TAG, "dismissDialog: prev is not null");
SendingMessageDialog df = (SendingMessageDialog) prev;
df.dismiss();
}
}
My SendingMessageDialog which extends AppCompatDialogFragment, I have this code in my onCreateDialog:
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateDialog: starting");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.send_message_dialog, null);
builder.setView(view)
.setTitle("Sending Token")
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
return builder.create();
}
I have looked up a few post on stackoverflow but none seem to address this specific issue. I saw this one, but there is no cancel() method available. I saw this one but I have to dismiss the dialog when I get a message from another part of the system, so I cannot just do this in-line sort of thing. This one just seemed like a simple mistake of calling show on the wrong dialog. I couldn't quite get a handle on this one, but it's 8 years old and seems to be about the coordination of two dialogs.
Many of the examples identify the dismiss is not working. In my case it is, until I switch fragments using the bottom navigation and then return to the fragment where the dialog process exists.
Nothing special happening in the navigation:
selectedFragment = new RunScenarioListFragment();
and:
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frame_layout_run_scenario,selectedFragment)
.addToBackStack(null)
.commit();
I have a MainActivity containing 5 fragments, 2 of which have a help icon on the toolbar on top right. I have hidden this icon on other 3 fragments. Upon clicking help icon, an alert dialog shows up with title, message and a positive button.
This is my Alert Dialog code:
public class HelpDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Help");
builder.setMessage("Placeholder");
builder.setPositiveButton("Got It", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {}
});
return builder.create();
}
}
and this is how I am showing it from MainActivity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_help:
DialogFragment helpDialog = new HelpDialogFragment();
helpDialog.show(getSupportFragmentManager(), "dialogHelp");
return true;
}
return super.onOptionsItemSelected(item);
}
The above code works but I would like to show different message based on the fragment selected so how to change the message? I tried this to change title
helpDialog.getDialog().setTitle("Some Text");
Please note I want to change Dialog message, i.e main content, I only got setTitle() method on getDialog() and not setMessage(), the above setTitle is just for example purpose but even it is throwing NullPointerException.
As you can see in the above screenshot, "Placeholder" text is the default text I added at the time of creating AlertDialog but now how to change it?
From reading your post and comments it looks like you need to set different titles depending on whatever fragment is visible. And the creation of dialogs happens from Activity so you are not sure what title to set.
The problem is essentially identifying the visible fragment and set message according to it.
You can pass the message with arguments like this.
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putString(message, "My title");
fragment.setArguments(bundle);
Then in your Fragment, get the data (e.g. in onCreate() method)
Bundle bundle = this.getArguments();
if (bundle != null) {
String message = bundle.getString(message, defaultValue);
}
How to identify the currently visible fragment? You can do this as suggested in these answers. Once you get the current fragment, just send the message in the arguments above according to it.
By combining the above 2 ideas you can do this.
Another way would be to start the dialog from the fragment and not from the Activity but that would involve more changes so the above approach is better.
First pass the required message over a bundle while calling HelpDialogFragment class
HelpDialogFragment helpDialog = new HelpDialogFragment();
Bundle bundle = new Bundle();
bundle.putString("placeholder", "Custom placeholder");
helpDialog.setArguments(bundle);
helpDialog.show(getSupportFragmentManager(), "dialogHelp");
Now modify your HelpDialogFragment class create the dialog like this
public class HelpDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Help");
if (getArguments() != null)
builder.setMessage(getArguments().getString("placeholder",""));
builder.setPositiveButton("Got It", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {}
});
return builder.create();
}
}
I had a working DialogFragment that was using an inner class to do a bunch of things on some objects, set menu icons etc. When i went to Android Studio i realised that was incorrect and i've been trying to change the inner class to be static.
In so doing, I am now trying to use onCreateDialog to, as per Google docs, "doPositiveClick" and "doNegativeClick", so that the calling MainActivity can do the work on those objects instead of the fragment doing it.
What is now confusing me however, is how do I set the layout in the fragment - I can enter a title, message and buttons as such:
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.alert_title)
.setMessage(R.string.alert_message)
.setPositiveButton(R.string.set,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((MainActivity)getActivity()).doPositiveClick();
}
}
)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((MainActivity)getActivity()).doNegativeClick();
}
}
)
But previously I was doing the layout like:
final EditText input = new EditText(MainActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(20, 20);
input.setText("5");
input.setLayoutParams(lp);
input.setRawInputType(Configuration.KEYBOARD_QWERTY);
Problem is, where does this go in onCreateDialog ? The Google docs shows how to set text on a dialog textView, but that is within onCreateView().
My confusion is that the google doc doesnt do both, ie, it doesnt show how to both, set up custom elements, AND set up the positive/negative click in the calling MainActivity - or if it does, i'm sorry I cant see it right now.
So can anyone make it clearer for me, using the above onCreateDialog, how can I have an editText field, with a default value that takes user input, and then get back that input to the doPositiveClick() to process.
DialogFragment can use in 2 ways: dialog or view.
case1: use DialogFragment as a dialog. you have to implement onCreateDialog() to return a dialog. and then have to show the dialog in the following way. see the example:
public static class MyAlertDialogFragment extends DialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(title)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialog)getActivity()).doPositiveClick();
}
}
)
.setNegativeButton(R.string.alert_dialog_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialog)getActivity()).doNegativeClick();
}
}
)
.create();
}
}
Create and have to show dialog as the following way. show this way don't care, whether onCreateView() is implemented or not.
// Create the fragment and show it as a dialog.
DialogFragment newFragment = MyDialogFragment.newInstance();
newFragment.show(getFragmentManager(), "dialog");
case2: use as view (it is not feature of dialog). it is only view. you have to implement onCreateView() and show dialog as the following way:
public static class MyDialogFragment extends DialogFragment {
static MyDialogFragment newInstance() {
return new MyDialogFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("This is an instance of MyDialogFragment");
return v;
}
}
and have to show view as follow. the same as use Fragment class. show this way don't care, whether onCreateDialog() is implemented or not.
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = MyDialogFragment.newInstance();
ft.add(R.id.embedded, newFragment);
ft.commit();
summary:
in design, you can implement onCreateView() and onCreateDialog() together and use the same source code with this DialogFragment lifecycle. If the screen is small, use DialogFragment as Dialog. If the screen is big, use DialogFragment as view (the same common Fragment class).
Notice that use the correct way to show DialogFragment to suitable with onCreateView() and onCreateDialog() to prevent exception.
sorry guys I thought I exhausted my searches but just after I posted this I was able to fix it, putting the text field/layout inside the onCreateDialog BEFORE the Builder and then doing setView() to that input as such:
**LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(20, 20);
final EditText input = new EditText(getActivity());
input.setText("5");
input.setLayoutParams(lp);
input.setRawInputType(Configuration.KEYBOARD_QWERTY);**
// Use the Builder class for convenient dialog construction
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.alert_title)
.setMessage(R.string.alert_message)
**.setView(input)**
.setPositiveButton(R.string.set,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((MainActivity)getActivity()).doPositiveClick();
}
}
)
Only question now is how do I get the value back after the user inputs ?
I'm trying to implement a simple Dialog into my code. But it does not work. I have searched every available tutorial, including the official developer guide but nothing works. The error I got from logcat is that I'm getting a nullPointerException, I'm guessing that's on the getActivity. Any help?
This is what I have: This is my Custom Dialog class.
public class SaveDialog extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Save Password");
builder.setView(getContentView());
Dialog dialog = builder.create();
dialog.show();
return dialog;
}
private View getContentView() {
LayoutInflater inflater = getActivity().getLayoutInflater();
return inflater.inflate(R.layout.dialog, null);
}
}
and this is my main activity where the onclick occurs
private void savePassword() {
SaveDialog savePasswordDialog = new SaveDialog();
savePasswordDialog.show(savePasswordDialog.getSupportFragmentManager(), "tag");
}
Every single time I fire up the onClick, the app crashes. On top of that, currently I am trying to use getSupportFragmentManager, but it says it's undefined.
You should use getSupportFragmentManager(), which is only available in FragmentActivity.
You should change your activity to a fragment one.
Check this answer
Try this..works!!
((AppCompatActivity)activity).getSupportFragmentManager()
Just call getFragmentManager() from your android.support.v4.app.DialogFragment or android.support.v4.app.Fragment. It will return a android.support.v4.app.FragmentManager (this is, the support FragmentManager)
You don't have to manually show the dialog in onCreateDialog(), just returning it is sufficient for DialogFragment to work its magic (and show the dialog) when you call savePassword().
So remove this line from onCreateDialog :
dialog.show();
and it should work. Good luck!
I am using a custom DialogFragment to let a user change his login credentials. There are some text fields and two buttons (save/cancel). The layout is set in DialogFragment's onCreateView method.
If I open the dialog text fields are filled with default values. When the user changes text in a text field and clicks the cancel button the dialog is dismissed. Next time the dialog opens the text field changed before does not contain the default value as i expected but the text the user changed before. The text fields are not reset. This is almost the same problem mentioned here Reset an Android Dialog. The problem is that the solution provided refers to a Dialog which is deprecated in API level 11 and i cannot use onPrepareDialog with a DialogFragment.
Is there a similar way to reset the content of a DialogFragment?
You can override onResume() in your class, which extends DialogFragmet, as follows:
private static class MyDialogFragment extends DialogFragment {
public static MyDialogFragment newInstance() {
// ...
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// ...
}
#Override
public void onResume() {
super.onResume();
Dialog dialog = getDialog();
// reset code goes here - use dialog as you would have in onPrepareDialog()
}
}
You can also use .setText() method in Your activity as reaction after negative button click. Eg:
In DialogFragment.java, onCreateDialog(...)define AlertDialog.Builder
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
then
//this is better than creating button in layout
builder.setNegativeButton(R.string.button_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((MainAct) getActivity()).cancelDialog(DialogFragment.this);
}
}
);
In MainActivity.java create method cancelDialog(DialogFragment df) {
//here use df to reset text fields
}