my code:
public class CustomDialogFragment extends SherlockDialogFragment {
/** The system calls this to get the DialogFragment's layout, regardless
of whether it's being displayed as a dialog or an embedded fragment. */
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.p_product_gallery, container, false);
ImageView tttiv=(ImageView)v.findViewById(R.id.test_image);
tttiv.setImageResource(R.drawable.baozi);
return v;
}
/** The system calls this only when creating the layout in a dialog. */
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// The only reason you might override this method when using onCreateView() is
// to modify any dialog characteristics. For example, the dialog includes a
// title by default, but your custom layout might not need it. So here you can
// remove the dialog title, but you must call the superclass to get the Dialog.
mDialog = super.onCreateDialog(savedInstanceState);
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mDialog.getWindow().setBackgroundDrawable((new ColorDrawable(0x0f000000)));
mPager = (ViewPager) mDialog.findViewById(R.id.aa_pager);
mPager.setAdapter(mAdapter);
mAdapter = new ProductGalleryAdapter(getSupportFragmentManager());
return mDialog;
}
}
The "mPager" always is null.
Can any one provide an example?
tkx!
Unless you are using Android 4.2 (and Android Support Library rev 11), fragments are not supported in fragments...
Fragments within Fragments
Related
I have an Android Activity, from which I want to show a Dialog. It would probably be a custom DialogFragment. Now when the user clicks on specific buttons I want the layout's inside the dialog to change with the data from the previous DialogFragment and so that it would have an ability to also go back to previous Layout.
I dont think there is an easy way to change views inside of the same DialogFragment so what would be the best way to do this?
I have tried doing it in method onViewCreated and when a button is clicked, but nothing happens.
In my activity I call the fragment like this at the moment:
FragmentManager fm = getSupportFragmentManager();
NewDialog newDialog = NewDialog.newInstace(userId, loc, currentId);
newDialog.setNewClickListener(new NewDialog.OnNewClickListener() {
#Override
public void onCancelClicked() {
finishAdd();
}
#Override
public void onAcceptClicked() {
...
}
});
newDialog.show(fm, "new_frag");
And the fragment:
public class NewDeliveryPointDialog extends DialogFragment {
private LayoutInflater inflater;
private ViewGroup container;
public NewDialog(){
}
public static NewDialog newInstace(){
...
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
this.inflater = inflater;
this.container = container;
return inflater.inflate(R.layout.dialog_layout_1, container);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
saveButton.setOnClickListener(v -> {
View.inflate(getContext(), R.layout.dialog_layout_2, container);
view.invalidate();
view.refreshDrawableState();
}
});
}
}
A DialogFragment is not made to have navigation to other fragments within the same dialog.
You basically have these options:
On your button click you close the Dialog and open another Dialog. But this seems odd. If there is so much happening, probably dialogs are not the best shot.
Instead of DialogFragments have another fragment container overlaying the original one (basically what a Dialog fragment does for you). Within the second container you can easily navigate to other fragments and set it to gone when the user finished interaction.
If there are just a few Views in the Dialog, you could consider setting the old ones to gone and the new ones to visible
I think your code didn't work, because container is null. Method onCreateView gives you #Nullable ViewGroup container, which is null for DialogFragment (but non null for Fragment). So when you call View.inflate(getContext(), R.layout.dialog_layout_2, container), it just creates a view in memory and doesn't attach it to container, cause it is null. See LayoutInflater.inflate, cause View.inflate is just a convenience wrapper for this function.
I dont think there is an easy way to change views inside of the same DialogFragment so what would be the best way to do this?
Instead of changing dialog root you can just manipulate child views inside dialog root layout (add, remove them, or change visibility).
Also my advice is to use recommended way to create dialog with custom layout (onCreateDialog + setView), but if you don't want to do that, you can refer view you've created in onCreateView as dialog root.
You can try creating a dialog fragment with an empty shell layout in which you would replace your two different fragments with ChildFragmentManager and regular fragment transactions
passing data between them can be done using the activity's view model since they both live in the same activity.
So add the ShellDialogFragment using the activity's FragmentManager and in the shell fragment class change between NewDialog & NewDeliveryPointDialog on your button click listener with ChildFragmentManager
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");
Basically, I have built over the default new Activity UI offered by Eclipse and Android Development Tools with the scrollable tabs and swipe.
It is Fragment based.
I am trying to inflate a view inside the fragment, attach a button click listener in this view which will initiate an AsyncTask, which will in turn display a progress dialog in its onPostExecute method.
Here's some code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.my_view, container, false);
Button bProcess= (Button) rootView.findViewById(R.id.bJustParked);
bProcess.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
new JustParkedGetLocation().execute();
}
});
// Modify views in fragment below
return rootView;
}
Obviously, JustParkedGetLocation extends AsyncTask and is a subclass of the class which holds the onCreateView method above. However, if I want to create a dialog in JustParkedGetLocation->onPreExecute(), e.g.:
#Override
protected void onPreExecute() {
ProgressDialog progress = new ProgressDialog(this);
progress.setIndeterminate(true);
progress.setTitle("Getting location");
progress.show();
super.onPreExecute();
}
...the parameter for the ProgressDialog constructor is not correct, since the class that holds the onCreateView method is static (the class that extends Fragment) by default. Resulting in the following error:
The constructor ProgressDialog(MainActivity.ExtendedFragment.JustParkedGetLocation) is undefined
You need to pass the constructor a reference to the activity context:
ProgressDialog progress = new ProgressDialog(getActivity());
I am working in an android application and am using a DialogFragment to show a dialog and I want to make that DialogFragment not cancelable. I have made the dialog cancelable property to false, but still its not affecting.
Please look into my code and suggest me a solution.
public class DialogTest extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_test, container, true);
getDialog().requestWindowFeature(STYLE_NO_TITLE);
getDialog().setCancelable(false);
return view;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_test, container, true);
getDialog().requestWindowFeature(STYLE_NO_TITLE);
getDialog().setCancelable(false);
return view;
}
instead of getDialog().setCancelable(false); you have to use directly setCancelable(false);
so the updated answer will be like this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_test, container, true);
getDialog().requestWindowFeature(STYLE_NO_TITLE);
setCancelable(false);
return view;
}
Use the following Snippet
void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment.newInstance(
R.string..alert_dialog_two_buttons_title);
newFragment.setCancelable(false);
newFragment.show(getFragmentManager(), "dialog");
}
and if you want to disable the out side touch around dialog use the following line of code
DialogFragment.getDialog().setCanceledOnTouchOutside(true);
In case you use alert builder (and probably in every case you wrap dialog inside a DialogFragment) to help build your dialog, please don't use getDialog().setCancelable(false) or Dialog.setCancelable(false) because it's not going to work.
Use setCancelable(false) as shown in code below as it's mentioned in oficial android documentation:
public void setCancelable (boolean cancelable)
Added in API level 11
Control whether the shown Dialog is cancelable. Use this instead of directly calling Dialog.setCancelable(boolean), because DialogFragment needs to change its behavior based on this."
ref:http://developer.android.com/reference/android/app/DialogFragment.html#setCancelable(boolean)
public class MyDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_layout, null, false);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle("in case you want use a title").setView(view);
AlertDialog alert = builder.create();
// alert.setCancelable(false); <-- dont' use that instead use bellow approach
setCancelable(false); <- press back button not cancel dialog, this one works fine
alert.setCanceledOnTouchOutside(false); <- to cancel outside touch
return alert;
}
Simple Solution in DialogFragment
Used
dialog.setCanceledOnTouchOutside(false)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
AlertDialog.Builder(activity!!).apply {
isCancelable = false
setMessage("Your message")
// your other adjustments
return this.create()
}
}
worked for me.
The main thing is to use isCancelable = false over setCancellable(false)
within override fun onCreateDialog().
/**
* Control whether the shown Dialog is cancelable. Use this instead of
* directly calling {#link Dialog#setCancelable(boolean)
* Dialog.setCancelable(boolean)}, because DialogFragment needs to change
* its behavior based on this.
*
* #param cancelable If true, the dialog is cancelable. The default
* is true.
*/
DialogFragment.setCancelable(boolean cancelable) {
mCancelable = cancelable;
if (mDialog != null) mDialog.setCancelable(cancelable);
}
I have a dialog fragment using a custom layout with a quite complex View hierarchy. The code for the dialog fragment is more or less similar to the following.
public class CardDetailDialog extends DialogFragment {
public CardDetailDialog() {
setRetainInstance(true);
setStyle(STYLE_NORMAL, android.R.style.Theme_Light);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.card_detail_dialog, container, false);
/* Modify some view objects ... */
return view;
}
}
Whenever I invoked the show() method for this dialog fragment, I noticed that onCreateView is always called and layout inflation process is repeated. In my app, user might want to show the dialog multiple times during a session and I thought this is inefficient. Is there any way to keep the view / dialog instance across multiple show() invocation? Is it possible to do this using DialogFragment, or do I have to deal directly with Dialog class?
Using a boolean flag seems to do the trick (See the KEY CHANGEs). I override onCreateDialog, but employing the same strategy in onCreateView should work as well (keep a reference to your view you create)
I'm still getting some issues related to Orientation changes, but it may be related to a different issue
public class LogFragment extends DialogFragment{
private boolean isCreated; //KEY CHANGE
private Dialog mDialog; //KEY CHANGE -- to hold onto dialog instance across show()s
public LogFragment() {
setRetainInstance(true); // This keeps the fields across activity lifecycle
isCreated = false; // KEY CHANGE - we create the dialog/view the 1st time
}
#Override
public Dialog onCreateDialog(Bundle inState) {
if (isCreated) return mDialog; // KEY CHANGE - don't recreate, just send it back
View v = View.inflate(getActivity(),R.layout.log_layout,null);
mDialog = new AlertDialog.Builder(getActivity())
...
.create();
isCreated = true; // KEY CHANGE Set the FLAG
return mDialog;
}