I am trying to implement a relatively simple DialogFragment that is supposed to contain an image and a OK button and I want to display it on demand from my activity.
I set its layout in onCreateView via inflater.inflate, but I can't figure out how to tell it that the implementation for the OK button event handler is located in my custom DialogFragment class. It seems to try to find it in the activity, which is not what I want. Would calling getDialog().dismiss() be enough to dismiss it?
Here is how I create a dialog in my activity:
ResponseDialog dialog = new ResponseDialog();
dialog.show(getFragmentManager(), "dialog_response_image");
Also, some folks say that my custom DialogFragment should set getDialog().setCanceledOnTouchOutside(true);, but where should I set this. In onActivityCreated?
How can I get access to its view from the activity, if I wish to set the source of the image contained by it?
Also, for some reason, it fills up the entire display, even if I use static width / height. Does anyone know how to fix this? - I managed to fix this by swithching to LinearLayout instead of RelativeLayout in the DialogFragment layout XML...
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#color/background_color"
tools:context=".MainActivity"
android:layout_width="200dp"
android:layout_height="400dp"
android:id="#+id/dialogImageReponse" >
<Button
android:id="#+id/dialogButtonOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="#string/ok"
android:onClick="Ok" />
</RelativeLayout>
I'll try to answer each of your questions:
1.) About the "how to tell it that the implementation for the OK button event handler is located in my custom DialogFragment class" I'm not sure why you want to do that since you haven't told us.
2.) "Would calling getDialog().dismiss() be enough to dismiss it?". If you wish to dismiss the DialogFragment from your Activity then you just need to call dialog.dismiss() ('dialog' here refers to ResponseDialog dialog = new ResponseDialog(); so obviously you can only call dialog.dismiss() once you've created the ResponseDialog object.
3.) Regarding "getDialog().setCanceledOnTouchOutside(true);" Once again you just need to call
dialog.setCanceledOnTouchOutside(true);
immediately after this:
ResponseDialog dialog = new ResponseDialog();
dialog.show(getFragmentManager(), "dialog_response_image");
4.) You can get access to its view by calling:
View v = dialog.getView();
Although if you just wish to set the source of the image to be used contained by it, and I assume you want to use a photo or a picture stored in your phone then you would have to use a parametrized constructor for ResponseDialog like this and as a parameter you would have to pass the URI OR the filepath of the picture that you would like displayed in the dialogfragment :
ResponseDialog dialog = new Response(String filepath);
and then in your custom dialog class which I understand is ResponseDialog you would have to use this filepath (received in the constructor) to create a bitmap and then set the bitmap as the source of the ImageView in that DialogFragment.
Related
I have an Activity that I have already implemented sometime ago.
It involves around making a in app purchase, so all the logic is relatively self contained. it doesn't need to care about anything else.
Now, i wish to make that Activity to optionally show up in a dialog in some other activity. Is there a quick way to do that? I still need to keep the old behavior however, where the activity show up as a regular screen.
So is there someway that I could launch the activity with that make it show up as a dialog?
Thanks
You cant show activity as dialog.
Your options are:
1: Open the other activity with some boolean extra like "showDialog", true
Intent intent = new Intent(this, OtherActivity.class);
intent.putExtra("showDialog", true);
and in the other activity in (for example) onCreate:
Boolean showDialog = getIntent().getExtras().getBoolean("showDialog");
if (showDialog) {
// Code to show dialog
}
2: Create a DialogFragment and show it in your original activity. This custom DialogFragment you can use on both activities
https://guides.codepath.com/android/Using-DialogFragment
Probably your cleanest option depending on how complex your Activity is, is to create a new DialogFragment based on your current activity.
A DialogFragment is basically a Fragment, so has a relatively similar set of lifecycle callbacks to your Activity so it shouldn't be too difficult to re-work as a DialogFragment.
If the in-app purchase framework has specific callback requirements with an Activity then you will need to take that into account.
Another separate option would be to mock the appearance of a Dialog, by creating an Activity that may be transparent around the border of the main content.
Just Inflate the layout one button click on onCreate Method.
WhAT I WILL SUGGEST IS try alert box and in place of normal layout inflate you activity layout .
these might help
The easiest way to do that is to apply a dialog theme to the activity:
<activity android:theme="#style/Theme.AppCompat.Dialog" />
Or in the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat_Dialog);
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
}
You can customize parameters of the theme in styles.xml, e.g. dim enabled/disabled, click outside behavior.
The crucial point is to perform setTheme() before super.onCreate(), because Theme is immutable, once set through super.onCreate() it cannot be mutated later.
I have an Activity A, which opens a DialogFragment. In this dialog, a button opens an Activity B.
I would like this Activity B to open below the DialogFragment (which remains open), and I don't want the dialog to be recreated.
How can I achieve this? Is there a way to change the DialogFragment's parent Activity?
Cheers.
You can use a transition to do this.
public void Trans(View v){
Intent intent = new Intent(this,SecondActivity.class);
String transitionName = getString(R.string.transition_album_cover);
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(HomeActivity.this,
albumCoverImageView, // The view which starts the transition
transitionName // The transitionName of the view we’re transitioning to
);
ActivityCompat.startActivity(HomeActivity.this, intent, options.toBundle());
}
In the layout of HomeActivity:
<ImageView
android:layout_height="200dp"
android:layout_width="200dp"
android:src="#drawable/pic"
android:id="#+id/transPic"
android:onClick="Trans"
android:transitionName="#string/transition_album_cover" />
And in the layout of SecondActivity
<ImageView
android:layout_height="300dp"
android:layout_width="match_parent"
android:scaleType="centerCrop"
android:id="#+id/transPic"
android:src="#drawable/pic"
android:transitionName="#string/transition_album_cover" />
Here I used an ImageView as a common element in both HomeActivity and Second Activity. I believe you can try something of this sort for the dialogue box too. I have not done it for Dialog box myself though.
EDIT: Changing the parent of the dialogue is not something that is achievable this way. I didn't read that part when I was posting the answer. But this is still worth a try I guess, if you are not obliged to use a Dialog itself.
I'm trying to create a DialogFragment that contains a RecyclerView of EditTexts. It scrolls and the Copy/Cut/Paste appears when I click on an EditText but the keyboard never appears. The adapter works since I tried implementing the RecyclerView in an Activity.
I already tried finding solutions for making the keyboard show up such as adding this in the XML
</request focus>
or this to the dialog
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
but still, none works.
Thank you so much.
additional: here's how it currently appears
I know this question was asked one year ago, but I asked this very same question today, so it seems that this question is still puzzling people...
Anyways, I came across multiple "solutions" after browsing Stack Overflow and the Android API reference, but only one that would work. Now I'm not sure why these other, seemingly good solutions, wouldn't work for me. But at least I think I understand (or I have a theory) why the solution that finally worked, worked.
NOTE! This solution may not work if you are using some other way to create your dialog in onCreateDialog(Bundle) than by utilizing AlertDialog and its AlertDialog.Builder.
Here is the solution that worked for me.
By doing as above solution suggests, you are "tricking" the AlertDialog into setting the right flags for you. I'm not saying it's bad code practice, but it may not be the ideal code practice. For those of you not just looking for a quick solution but prepared to dive deep into this matter, continue reading:
So according to AlertDialog's documentation, AlertDialog automatically sets some window placement -related flags based on if any views in the dialog return true from View.onCheckIsTextEditor(). This behaviour of AlertLayout is brought up by this solution that seems to have helped a lot of people asking the same question but without a RecyclerView involved and with only AlertDialog involved, not AlertDialog used by a DialogFragment subclass.
You might get the latter solution working (check out its most up-voted comment), but your DialogFragment subclass must provide a way, after the DialogFragment has been shown, to get the AlertDialog's window, so that you can modify its flags. I haven't tried this, as my DialogFragment doesn't provide that functionality.
a) Force the input method open.
InputMethodManager inputMananger = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMananger.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
b) Request focus of the EditText that you wish to gain focus.
editText.requestFocusFromTouch();
I had the same problem when using a RecyclerView.Adapter, in a view that is created for a class that extends a DialogFragment. Also, in my ViewHolder I use an EditText that was not showing the keyboard when it gets focus.
#Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_text_detected_list, null);
//{...setAdapter, and other setups...}
AlertDialog dialog = builder.setView(view).create();
//The below line, solves my problem with the keyboard not showing up
dialog.setOnShowListener(d -> dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM));
return dialog;
}
This worked for me :
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
super.onCreateDialog(savedInstanceState);
// ...
alertDialog.show();
// This line is the key
alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
return alertDialog;
}
Try using :
InputMethodManager imm1 = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
edt_user_name.postDelayed(new Runnable()
{
#Override
public void run()
{
edt_user_name.requestFocus();
imm1.showSoftInput(edt_user_name, 0);
}
}, 100);
For a particular EditText e.g edt_user_name.
In my case, I've solved this by adding an EditText inside the fragment layout (not just RecyclerView)like this :
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/editFake"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
android:importantForAutofill="no"
android:hint="#string/empty"
android:inputType="none"
tools:targetApi="o"
android:background="#null"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
Ist there a possibility to do something like that:
int selected_value = Dialog("This dialog show a combobox, i want to know which item is selected")
Or
String typed_chars = Dialog("This Dialog show a TextBox, i want to know the typed chars")
It is strongly recommended, that the code will stop while the dialog is shown and resume after dismissing the dialog, like the "showdialogforresult" method in c# or vb.net, I have to show lots of Dialogs and every dialog depends on former choices, I will become crazy if i have to code this with listener or callbacks...
While I don't think this is exactly possible like you do it, you do not need to code an anonymous class per Button callback.
Instead you can designate one class that implements DialogInterface.OnClickListener() and which you specify for all of the buttons. Its onClick() callback gets the information about which Dialog was invoked and which button was clicked. So you can operate within this onClick() method with some switch/case or if/else cascades.
Not perfect, but won't make you crazy :)
I have a class that extends android.app.Dialog, the layout is done in an xml file, and the setup (button listeners, etc) is done on the onCreate method. My problem is that whenever the dialog is displayed, then dismissed, and displayed again, the Editable TextViews are still populated with the information that was displayed previously. What is the common way to clear these text fields? Remember - this is a separate class that extends Dialog - so there is no 'onDialogCreate' like Activity has.
Or, perhaps I am extending the wrong class? There is just a lot of processing being done, and do not want to have all the code in the main Activity. I would like it to be in a separate Class. I tried to extend AlertDialog, but it does not create the border like Dialog does. Any help would be great.
The dialog is shown via the Activity:
protected Dialog onCreateDialog(int id) {
switch(id){
case DIALOG_NEW_SAFE:
return(new NewSafeDialog(this));
default:
return(null);
}
}
onCreateDialog(..) caches the dialog which means the same instance is reused.
3 ways to fix the undesired behavior off my head:
Override onPrepareDialog(..), use findViewById(..) to get whatever you want to clear, clear it.
Don't rely on managed dialogs at all, do new NewSafeDialog(this).show() each time you want to show the dialog.
Add onCancelListener(..), onDismissListener(..) inside your custom dialog that would call a method to clear itself.
The good way to create a dialog is by using showDialog() as you did so don't change it.
The good and easy way to force deletion of a dialog in order to make your creation code recalled again is:
void removeDialog (int id)
So if you simply do the following, it's gonna work ;)
removeDialog(DIALOG_NEW_SAFE);
showDialog(DIALOG_NEW_SAFE);
Try clearing the text in the constructor of the NewSafeDialog i.e. your dialog class.