ListFragment as DialogFragment - android

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.

Related

Targeting the wrong class when showing DialogFragment in Fragment

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");
}
}
}

Android listener always null when attach in a DialogFragment

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.

DialogFragments for users to enter data

I've been trying to make a dialogFragment for my app but it's proving to be quite hard to do with a lack of examples available on the internet. Below is an image of something similar that I'd want.
Having a similar design to the image above would be great. I'm not sure if what I'm doing is correct and so far this is what I have done.
I don't know how to lay out the dialogFragment like the way it has been done for the first picture and I'm not sure how to get fields where my users can enter data to. Below is the code I currently have.
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.util.Log;
import android.view.*;
import android.widget.Button;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class Reminders extends Activity
{
Button add, edit, remove;
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.reminders);
initializeVariables();
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showDialog();
}
});
List<ListViewItem> items = new ArrayList<Reminders.ListViewItem>();
items.add(new ListViewItem()
{
{
ThumbnailResource = R.drawable.ic_launcher;
Title = "Item1 Title";
Date = "Item1 Date";
Time = "Item1 Time";
Amount = "£0.00";
}
});
items.add(new ListViewItem()
{
{
ThumbnailResource = R.drawable.ic_launcher;
Title = "Item2 Title";
Date = "Item2 Date";
Time = "Item2 Time";
Amount = "£0.00";
}
});
CustomListViewAdapter adapter = new CustomListViewAdapter(this, items);
lv.setAdapter(adapter);
}
private void initializeVariables()
{
add = (Button) findViewById(R.id.bAdd);
edit = (Button) findViewById(R.id.bEdit);
remove = (Button) findViewById(R.id.bRemove);
lv = (ListView) findViewById(R.id.LVReminder);
}
class ListViewItem
{
public int ThumbnailResource;
public String Title;
public String Date;
public String Time;
public String Amount;
}
void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment
.newInstance(R.string.dialog_title);
newFragment.show(getFragmentManager(), "New");
}
public void doPositiveClick() {
// Do stuff here.
Log.i("FragmentAlertDialog", "Positive click!");
}
public void doNegativeClick() {
// Do stuff here.
Log.i("FragmentAlertDialog", "Negative click!");
}
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.ic_launcher)
.setTitle(title)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
((Reminders) getActivity())
.doPositiveClick();
}
})
.setNegativeButton(R.string.alert_dialog_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
((Reminders) getActivity())
.doNegativeClick();
}
}).create();
}
}
}
I'd appreciate any advice on how to get a DialogFragment like the one in the first pic I provided. Thanks to anyone who tries to help me with this.
You can create the layout that you wish to achieve via XML document. Then from there you could change your onCreateDialog as follows:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
int title = getArguments().getInt("title");
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.my_dialog_layout, null);
return new AlertDialog.Builder(getActivity())
.setView(v)
.setIcon(R.drawable.ic_launcher)
.setTitle(title)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
((Reminders) getActivity())
.doPositiveClick();
}
})
.setNegativeButton(R.string.alert_dialog_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
((Reminders) getActivity())
.doNegativeClick();
}
}).create();
}
}
It seems more to me that that 'dialog' is an activity with a dialog theme, try this:
<activity android:theme="#android:style/Theme.Dialog">
I wouldn't recommend creating the layout you've supplied as it's too complex for mobile. But a simplified version with 1 option per line could be created.
You can see all supported Buttons, options, etc supported for AlertDialog.Builder in the official docs.
As #TronicZomB pointed out, you can use your own XML layout with setView(View view).

Showing a DialogFragment object from an on click inside a button listener

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 :)

Get value from DialogFragment [duplicate]

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.

Categories

Resources