This question already has answers here:
requestFeature() must be called before adding content
(9 answers)
Closed 8 years ago.
I have dialog fragment. I have intention to use this fragment in activity and dialog. And I override onCreateDialog and onCreateView method. here is coding.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.interval_time_popup, null);
setup(view, false);
return view;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.interval_time_popup, null);
builder.setTitle("Interval Time");
builder.setView(view);
setup(view, true);
builder.setPositiveButton("Set", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
listener.setOnIntervalTime(hourNp.getValue(), minNp.getValue());
dismiss();
}
});
builder.setNegativeButton("Cancel", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
return builder.create();
}
I use this fragment in the activity class like that.
SelectTimeIntervalDialogFragment fragment = new SelectTimeIntervalDialogFragment();
fragment.setHrMin(hr, min);
Bundle args = new Bundle();
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.shift_period_interval_layout, fragment);
t.commit();
I call it from another activity like that.
if((getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_NORMAL) ==
Configuration.SCREENLAYOUT_SIZE_NORMAL){
Intent intent = new Intent(ShiftPeriodActivity.this, SelectIntervalActivity.class);
intent.putExtra("intervalHr", speriod.intervalHr);
intent.putExtra("intervalMin", speriod.intervalMin);
startActivityForResult(intent, 1);
} else {
FragmentManager fm = getSupportFragmentManager();
intervalDialog = new SelectTimeIntervalDialogFragment();
intervalDialog.setHrMin(speriod.intervalHr, speriod.intervalMin);
intervalDialog.show(fm, "interval_fragment");
}
I have two conditions. When the screen size is normal, it call activity which include fragment dialog. Otherwise, it call the popup dialog. I got the exception when it call the popup dialog. It said requestFeature() must be called before adding content. Can I use like this? I would like to know how to overcome this.
Thanks.
It seems your problem is exactly the same as mine - similar-ish code and the same exception thrown.
The solution is to do what #laalto suggested: use either onCreateView() or onCreateDialog() but not both of them at the same time. I know the exception can be seemingly caused by many different things but this is what helped in my case; hopefully it'll help someone else in the future :)
i think you are using requestWindowFeature(); at on create
use it before setContentView(R.layout.activity);
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();
}
}
This question already has answers here:
How to implement OnFragmentInteractionListener
(12 answers)
Closed 6 years ago.
After the user fill the blanks this screen showed up:
This is an alert dialog. It's code here:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Congratulations!");
builder.setMessage("You finished Level 1. Do you want to start Level 2?");
builder.setNegativeButton("Not now", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id) {
}
});
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
builder.show();
I want to pass "Level 2" tab when user click "YES" button.
This is what I tried in onClick:
FragmentManager fm = getChildFragmentManager();
fm.beginTransaction().replace(R.layout.activity_level2, new Level2()).commit();
I get this error:
java.lang.IllegalArgumentException: No view found for id 0x7f04001f (translatingthecaps.translatethecaps:layout/activity_level2) for fragment Level2{60d2f9f #0 id=0x7f04001f}
I just have only this code in Level 2 Fragment:
public class Level2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.activity_level2, container, false);
return view;
}
}
Before alert dialog showed up I can see "Level 2" tab.
When you use a pager, you don't have to explicitly call a FragmentTransaction, all you have to do is
pager.setCurrentItem(2);
Since your pager isn't accessible from your fragment you should use a listener to set a callback to the activity, here is how to use it How to implement OnFragmentInteractionListener
The Fragment is part of a Tabbed Activity. I was able to succesfully modify the Tabbed Activity template of Android Studio 2.1.2. Now I have changed it to the point where all the Fragments inside it have a FAB of their own. When Floating Action Button is clicked it is supposed to show a dialog. I have created a DialogFragment following the instruction from the official docs. The FAB uses setOnClickListener to refer to the method in the java file. I can't use
newEdQua.show(getSupportFragmentManager(), "createNewEdQua")
to show the dialog. it says it cannot resolve it
I also noticed that it won't load the ListView with the content of the Stinrg Array.
In summary I want to show a dialog from a Fragment(thats part of Tabbed Activity).
I have tried to clean and rebuild, sync gradle files with project. I dont want to mess with IDE configuration files. At least not now cause I'm far into a very important project(so suppressing warnings is not an option).
This is my code. It includes only areas with problem.
Dialog Fragment (to be shown):
public class createNewEdQua extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle saveSavedInstanceState){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.createnewEdQua);
builder.setMessage("New Qualification HERE!!");
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
return builder.create();
}
}
Fragment (placed as tab in Tabbed Activity):
public class edSET_Dashboard_Teachers extends Fragment {
FragmentManager fm;
//neInstance() method return reference to fragment
public static edSET_Dashboard_Teachers newInstance(){
edSET_Dashboard_Teachers fragment = new edSET_Dashboard_Teachers();
return fragment;
}
public edSET_Dashboard_Teachers() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//following code is in public View onCreateView() method
String[] edqua={"Conten Here","Contend Here","Content Here"};
//had to use this cause findViewById() method was not working as it should
View view = inflater.inflate(R.layout.fragment_edset__dashboard__teachers, container, false);
ArrayAdapter<String> listOfEdqua2 = new ArrayAdapter<String>(getContext(), R.layout.list_item_edqua, edqua);//i tried using this as the context but error
ListView listView = (ListView)view.findViewById(R.id.edu_info);
listView.setAdapter(listOfEdqua2);
//had to use setOnClickListener cause android:onClick in xml does not work with Fragments ive learned
FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab_edset);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DialogFragment newEdQua = new createNewEdQua();
newEdQua.show(getActivity().getFragmentManager(), "createNewEdQua");
//addEdQua(view);
}
});
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_edset__dashboard__teachers, container, false);
}
//the method to show the dialog
/*
public void addEdQua(View view){
}*/
}
When I run it on a real device while connected to my computer, and I tap the FAB nothing at all happens, no crash no error nothing.
I figured it out
return inflater.inflate(R.layout.fragment_edset__dashboard__teachers, container, false);
should be
return view;//it already inflates the Fragment layout
you are reinflating new view
First declare a FragmentManager variable:
FragmentManager fm;
Then initialise it
fm = getFragmentManager();
then call it wherever you want..
createNewEdQua dialogFragment = new createNewEdQua ();
dialogFragment.show(fm, "Your title");
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 ?