I have an AndroidStudio Java project using Fragments.
i want to show a dialogbox that asks to aquire permissions when needed.
So i did
Top of fragment
public class DinersFragment extends Fragment implements PermissionDialogFragment.PermissionDialogListener{
in class of fragment
public void showPermissionDialog() {
// Create an instance of the dialog fragment and show it
DialogFragment dialog = new PermissionDialogFragment();
dialog.show(((FragmentActivity) getActivity()).getSupportFragmentManager(), "PermissionDialogFragment");
}
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
}
#Override
public void onDialogNegativeClick(DialogFragment dialog) {
}
but debug i got a cast error and had to add the same to mainActivity
Now things work, but when i click on the yes or no button, the onClicklistener in mainActivity is triggered, but instead i want the onClicklistener in the fragment to trigger.
How do i achieve this to not target mainActivity but the actual fragment?
the permission dialog:
package com.example.thermomaxtb;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
* Use the actory method to
* create an instance of this fragment.
*/
public class PermissionDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.req_perm)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// START THE GAME!
listener.onDialogPositiveClick(PermissionDialogFragment.this);
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
listener.onDialogNegativeClick(PermissionDialogFragment.this);
}
});
// Create the AlertDialog object and return it
return builder.create();
}
public interface PermissionDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
PermissionDialogListener listener;
#Override
public void onAttach(Context context) {
super.onAttach(context);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
listener = (PermissionDialogListener) context;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(e.toString()
+ " must implement NoticeDialogListener");
}
}
}
Related
high school teachers here trying to teach how to implement a DialogFragment with listener attach with an interface to the fragment that show it. for some reason the listener is always null and while the dialog show, when I press the ok or Cancel button of the Dialog, the transfert to the implement method dont work, it stop a the line where I call the listener class (always null) in the alertDialog.Builder Here my code, thank
here my Fragment that call the dialogfragment
package net.ccl.monapp.ui;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import net.ccl.monapp.R;
public class AnimationFragment extends Fragment implements MonDialogFragment.MonDialogListener {
public AnimationFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_animation,container,false);
Button myButton = root.findViewById(R.id.bt_dialog);
final TextView tvTitre = root.findViewById(R.id.tv_titre);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogFragment myDialog = new MonDialogFragment();
// Show Alert DialogFragment
myDialog.show(getFragmentManager(), "Dialog");
}
});
return root;
}
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
TextView myTitre = getView().findViewById(R.id.tv_titre);
myTitre.setText("Mon nouveau titre");
dialog.dismiss();
}
#Override
public void onDialogNegativeClick(DialogFragment dialog) {
Toast.makeText(getActivity(),"Vous avez canceler l'action du dialog",Toast.LENGTH_SHORT);
}
}
here my DialogFragment
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
public class MonDialogFragment extends DialogFragment {
public MonDialogFragment() {
}
public interface MonDialogListener {
void onDialogPositiveClick(DialogFragment dialog);
void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
public MonDialogListener listener;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
// Instantiate the NoticeDialogListener so we can send events to the host
listener = (MonDialogListener) context;
} catch (ClassCastException e) {
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Mon interface dialog");
builder.setMessage("Ceci est un message qui explique que tu peux changer le titre du fragment animation en cliquant sur ok");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
listener.onDialogPositiveClick(MonDialogFragment.this);
}
});
builder .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
listener.onDialogNegativeClick(MonDialogFragment.this);
}
});
return builder.create();
}
}
and here my logcat
Process: net.ccl.monapp, PID: 13691
java.lang.NullPointerException: Attempt to invoke interface method 'void net.ccl.monapp.ui.MonDialogFragment$MonDialogListener.onDialogPositiveClick(androidx.fragment.app.DialogFragment)' on a null object reference
at net.ccl.monapp.ui.MonDialogFragment$1.onClick(MonDialogFragment.java:56)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Your onAttach() isn't actually doing anything since the Context you're attempting to cast is your Activity, not your AnimationFragment.
Instead of reaching up to get your listener, your AnimationFragment should set the listener on the Dialog by overriding onAttachFragment().
First, you need to make sure that your MonDialogFragment is a child fragment of your AnimationFragment by changing your show() to use getChildFragmentManager():
myDialog.show(getChildFragmentManager(), "Dialog");
Then, override onAttachFragment() in your AnimationFragment:
#Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment instanceof MonDialogFragment) {
((MonDialogFragment) fragment).listener = this;
}
}
You can then remove onAttach() from MonDialogFragment entirely.
I am new in Android Development. I want to open the Alert Dialog for Number Picker from Main Activity, and then take input from Alert Dialog and show it in the Main view.
I have written code from taking some references and its working correct. But i don't want to use " implements NumberPickerFragment.NoticeDialogListener" in main activity. Please help me, how can i return the value to main activity.
My code for Main Activity is:
package com.pinnacleappdesign.pinnacleappdesign;
import android.os.Bundle;
import android.app.Activity;
import android.app.DialogFragment;
import android.view.Menu;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements NumberPickerFragment.NoticeDialogListener{
int memoryIndex = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Button firstPaneButton = (Button)findViewById(R.id.first_pane_button1);
firstPaneButton.setOnClickListener(new OnClickListener() {
public void onClick(View v){
DialogFragment newFragment = new NumberPickerFragment();
Bundle args = new Bundle();
args.putInt("currentMemoryIndex", memoryIndex);
newFragment.setArguments(args);
newFragment.show(getFragmentManager(), "numberPicker");
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onDialogPositiveClick(int newMemoryIndex) {
this.memoryIndex = newMemoryIndex;
/** Getting the reference of the textview from the main layout */
TextView tv = (TextView) findViewById(R.id.tv_android);
/** Setting the selected android version in the textview */
tv.setText("Your Choice : " + this.memoryIndex);
}
}
My code for NumberPickerFragment.java is:
package com.pinnacleappdesign.pinnacleappdesign;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.NumberPicker;
import android.widget.Toast;
public class NumberPickerFragment extends DialogFragment{
/* The activity that creates an instance of this dialog fragment must
* implement this interface in order to receive event callbacks.
* Each method passes the DialogFragment in case the host needs to query it. */
public interface NoticeDialogListener {
public void onDialogPositiveClick(int newMemoryIndex);
}
// Use this instance of the interface to deliver action events
NoticeDialogListener mListener;
// Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = (NoticeDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString()
+ " must implement NoticeDialogListener");
}
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle bundle = getArguments();
int currentMemoryIndex = bundle.getInt("currentMemoryIndex");
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View DialogView = inflater.inflate(R.layout.number_picker, null);
final NumberPicker np = (NumberPicker)DialogView.findViewById(R.id.numberPicker1);
np.setMinValue(1);
np.setMaxValue(100);
np.setWrapSelectorWheel(false);
np.setValue(currentMemoryIndex);
builder.setTitle(R.string.dialog_title)
.setView(DialogView)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User confirmed the dialog
int position = np.getValue();
mListener.onDialogPositiveClick(position);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
return builder.create();
}
}
What is wrong with your current method? That appears to be the method Android encourages developers to use as seen here: Communicating with Fragments
You can also do something like this within your NumberPickerFragment:
((MainActivity) getActivity()).yourMethod();
But IMO it is much cleaner and re-usable to use the defined Interface method.
I was just trying showing a DialogFragment object from an on click inside a button listener.
Here is the code of the activity that should start the Dialog:
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
Button button1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addListenerToButton1();
}
private void addListenerToButton1(){
final Context context = this;
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
DP ciao = new DP();
ciao.show(this,"MyDP");
}
});
}
}
And here's the code of the Dialog:
public class DP extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Prova")
.setPositiveButton("POS", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton("NEG", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
}
Errors are:
The method show(FragmentManager, String) in the type DialogFragment is not applicable for the arguments (MainActivity, String)
The method show(FragmentManager, String) in the type DialogFragment is not applicable for the arguments (new View.OnClickListener(){}, String)
Any advice?
Show DialogFragment from Activity by passing FragmentManager instance for interacting with fragments associated with current activity as instead of by passing Activity or Button Context:
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
DialogFragment ciao = DP.newInstance();
ciao.show(MainActivity.this.getFragmentManager(),"MyDP");
}
});
and you will also need to add following newInstance() method in DP DialogFragment which return you DialogFragment instance :
public static DP newInstance() {
DP frag = new DP();
return frag;
}
Try this method of passing the correct context into your DialogFragment
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
DP ciao = new DP();
ciao.show(view.getContext(),"MyDP");
}
});
In your original code, when calling
'ciao.show(this,"MyDP");'
the this refers to its parent class which is OnClickListener.
When assigning a click listener and overriding the onClick, you get passed the view and an argument which you can use to access information from, including the context.
Extend your fragment (DP) from the android.app.DialogFragment
you can access FragmentManager from within Activity by getFragmentManager()
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
DP ciao = new DP();
ciao.show(getFragmentManager(),"MyDP");
}
});
Hopefully this works :)
This question already has answers here:
Receive result from DialogFragment
(15 answers)
Closed 9 years ago.
I want the DialogFragment to return a value to me that was entered in editQuantity when dismissed.
But i am not getting any way to make it work. I can do this by passing the value through the intent but that destroys the progress of the current activity.
Is there any way other than passing through intent that will return me value?
package com.example.myprojectname;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.InputType;
import android.util.Log;
import android.widget.EditText;
public class QuantityDialogFragment extends DialogFragment implements OnClickListener {
private EditText editQuantity;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
editQuantity = new EditText(getActivity());
editQuantity.setInputType(InputType.TYPE_CLASS_NUMBER);
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.app_name)
.setMessage("Please Enter Quantity")
.setPositiveButton("OK", this)
.setNegativeButton("CANCEL", null)
.setView(editQuantity)
.create();
}
#Override
public void onClick(DialogInterface dialog, int position) {
String value = editQuantity.getText().toString();
Log.d("Quantity: ", value);
dialog.dismiss();
}
}
Assuming that you want to foward result to the calling Activity:) try this code snippet:
public class QuantityDialogFragment extends DialogFragment implements OnClickListener {
private EditText editQuantity;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
editQuantity = new EditText(getActivity());
editQuantity.setInputType(InputType.TYPE_CLASS_NUMBER);
return new AlertDialog.Builder(getActivity()).setTitle(R.string.app_name).setMessage("Please Enter Quantity")
.setPositiveButton("OK", this).setNegativeButton("CANCEL", null).setView(editQuantity).create();
}
#Override
public void onClick(DialogInterface dialog, int position) {
String value = editQuantity.getText().toString();
Log.d("Quantity: ", value);
MainActivity callingActivity = (MainActivity) getActivity();
callingActivity.onUserSelectValue(value);
dialog.dismiss();
}
}
and on Your activity add :
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
QuantityDialogFragment dialog = new QuantityDialogFragment();
dialog.show(getSupportFragmentManager(), "Dialog");
}
/**
* callback method from QuantityDialogFragment, returning the value of user
* input.
*
* #param selectedValue
*/
public void onUserSelectValue(String selectedValue) {
// TODO add your implementation.
}
}
Taking this idea a little further, I created a listener interface inside the dialog and implemented it in the main activity.
public interface OnDialogResultListener {
public abstract void onPositiveResult(String value);
public abstract void onNegativeResult();
}
public void setOnDialogResultListener(OnDialogResultListener listener) {
this.onDialogResultListener = listener;
}
Call onNegativeResult() inside an overriden onCancel(DialogInterface) and onPositiveResult(String) where you want your dialog to return the value.
Note: don't forget to dismiss() your dialog after calling onPositiveResult() or the dialog window will stay opened.
Then inside your main activity you can create a listener for the dialog, like so:
QuantityDialogFragment dialog = new QuantityDialogFragment();
dialog.setOnDialogResultListener(new QuantityDialogFragment.OnDialogResultListener() {
#Override
public void onPositiveResult(String value) {
//Do something...
}
#Override
public void onNegativeResult() {
//Do something...
}
});
This will make your dialog easier to reuse later.
Is it possible to show ListFragment as Dialog? Or there's no way and I should implement my own ListView, empty TextView and indeterminate ProgressBar inside DialogFragment myself?
Another Option:
Build Dialog Fragment:
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
public class ListDialogFragment extends DialogFragment {
private OnListDialogItemSelect listener;
private String title;
private String[] list;
public ListDialogFragment(OnListDialogItemSelect listener, String[] list, String title) {
this.listener=listener;
this.list=list;
this.title=title;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(title)
.setCancelable(false)
.setItems(list, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
listener.onListItemSelected(list[item]);
getDialog().dismiss();
ListDialogFragment.this.dismiss();
}
}).create();
}
public interface OnListDialogItemSelect{
public void onListItemSelected(String selection);
}
}
On Your Fragment Activity like this:
public class YourActivity extends FragmentActivity implements OnListDialogItemSelect{
private void showCountryFragment(){
FragmentManager fm = getSupportFragmentManager();
ListDialogFragment newFragment = new ListDialogFragment(this,getCountries(),"Country:");
newFragment.show(fm, "country_picker");
}
#Override
public void onListItemSelected(String selection) {
_bt_country.setText(selection);
}
}
I am not very sure whether it works with ListFragment or not but we can show an activity as Dialog by applying a theme to activity in manifest file as:
<activity android:theme="#android:style/Theme.Dialog" />
Please try with your ListFragment, and let me know if it works.
Thank you.