startActivityForResult Crashes in fragment - android

error occurs when startActvityResult() called.
I use this to call FragmentFotosdePerfil from other fragment
public void verFotosPerfil(String userID){
fragmentFotosPerfil=new FragmentFotosPerfil();
Bundle bundle= new Bundle();
bundle.putString("userID",userID);
fragmentFotosPerfil.setArguments(bundle);
getFragmentManager().beginTransaction().
replace(R.id.frameLayout2,fragmentFotosPerfil).commit();
}
I call "cargarFotoPerfil" from the XML with Onclick in different buttons
public void cargarFotoPerfil(View view){
switch(view.getId()) {
case R.id.btnCargarFoto2:
System.out.println("caso2");
cargarFotoPerfil2(view);
foto=2;
break;
case R.id.btnCargarFoto3:
cargarFotoPerfil2(view);
foto=3;
break;
case R.id.btnCargarFoto4:
cargarFotoPerfil2(view);
foto=4;
break;
case R.id.btnCargarFoto5:
cargarFotoPerfil2(view);
foto=5;
break;
}
public void cargarFotoPerfil2(View view){
final CharSequence[] opciones={"Elegir de Galeria","Cancelar"};
final AlertDialog.Builder builder=new
AlertDialog.Builder(view.getContext());
builder.setTitle("Elige una Opción");
builder.setItems(opciones, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if (opciones[i].equals("Elegir de Galeria")){
Intent intent=new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
startActivityForResult
(intent.createChooser(intent,"Seleccione"),10);
}else{
dialogInterface.dismiss();
}
}
});
builder.show();
}
here is my logcat report as you show below.
//ERROR.CRASHES IN LINE startActivityForResult()
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.clemente.prueba6, PID: 4937
java.lang.IllegalStateException: Fragment FragmentFotosPerfil{18cbf6df} not attached to Activity
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:1019)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:1010)
at com.example.clemente.prueba6.FragmentFotosPerfil$1.onClick(FragmentFotosPerfil.java:159)
at android.support.v7.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1067)
at android.widget.AdapterView.performItemClick(AdapterView.java:300)
at android.widget.AbsListView.performItemClick(AbsListView.java:1143)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3044)
at android.widget.AbsListView$3.run(AbsListView.java:3833)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Does anyone know the solution to this problem?
Thanks in advance

I believe that any way you want to dismiss the Dialog, And it might fix your crash...
Try changing the onClick to look like this:
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
if (opciones[i].equals("Elegir de Galeria")){
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
startActivityForResult(intent.createChooser(intent,"Seleccione"),10);
}
}

Use isAdded to check if fragment is attached to Activity.
if(isAdded){
final CharSequence[] opciones={"Elegir de Galeria","Cancelar"};
final AlertDialog.Builder builder=new AlertDialog.Builder(view.getContext());
builder.setTitle("Elige una Opción");
builder.setItems(opciones, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if (opciones[i].equals("Elegir de Galeria")){
Intent intent=new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
startActivityForResult(intent.createChooser(intent,"Seleccione"),10);
}else{
dialogInterface.dismiss();
}
}
});
}

I think you need check your code. Because I replied the fragment and your code is working fine. Maybe your mistake is the way that you are using to load the fragment in the Activity.
I let you the code that i use to launch the fragment. This code is working.
Calling another fragment from TestFragment
public class TestFragment extends Fragment {
public TestFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_test_two, container, false);
TestFragmentTwo fragment = new TestFragmentTwo();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.addToBackStack(fragment.toString());
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
return v;
}
}
TestFragmentTwo
public class TestFragmentTwo extends Fragment {
public TestFragmentTwo() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_test_two, container, false);
final CharSequence[] opciones={"Elegir de Galeria","Cancelar"};
final AlertDialog.Builder builder=new AlertDialog.Builder(v.getContext());
builder.setTitle("Elige una Opción");
builder.setItems(opciones, (dialogInterface, i) -> {
if (opciones[i].equals("Elegir de Galeria")){
Intent intent=new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
getActivity().startActivityForResult(intent.createChooser(intent,"Seleccione"),10);
}else{
dialogInterface.dismiss();
}
});
builder.show();
return v;
}
}
As you can see, I am loading a fragment from another fragment, and then I am calling the startActivityResult without problem.
I hope it helps you.

The exception says that you are not attached the fragment or else that attached fragment may be destroyed kindly reattach the fragment.

Related

Issue with bundle value in onClickListener method

Im having some troubles with retrieving a bundle value in my onClickListener method or any other method in general. I have comments besides the code for better clarification. So what happens is i get a value from activityA put it in a bundle and pass the values to my fragment. I get the value from the bundle and set in my setter method the value i get from the bundle is not null if i toast the value it shows the correct one on the screen. Below im posting my whole onCreateMethod, im having this issue for the past couple of days so any help is greatly appreciated. What i think happens is that when i try to get the value from the bundle in my onClickListener method it resets itself to 0 for some reason.
Thanks for your help in advance
My onCreateView method in fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_todo_list, container, false);
FloatingActionButton floatingActionButton = view.findViewById(R.id.fab);
recyclerView = (RecyclerView) view.findViewById(R.id.list);
bundle = this.getArguments();
if(bundle != null) {
fk_id = bundle.getLong("fk");
setId_2(fk_id); // i try to set the value
Toast.makeText(getContext(), "iz fragmenta" + getId_2(), Toast.LENGTH_SHORT).show(); // this prints the correct value
floatingActionButton.setOnClickListener(new View.OnClickListener() { //this button stops working if in the if statement
#Override
public void onClick(View v) {
LayoutInflater li = LayoutInflater.from(getActivity());
View popupView = li.inflate(R.layout.popup_layout, null);
final EditText editText = popupView.findViewById(R.id.userInput);
AlertDialog.Builder adb = new AlertDialog.Builder(getContext());
adb.setView(popupView);
adb.setCancelable(false)
.setPositiveButton("Dodaj", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String naziv = editText.getText().toString();
Aktivnost_ ak = new Aktivnost_(naziv, "15-jun", fk_id, "kajetan", "todo");
dodajAktivnost(ak);
array.add(ak);
Toast.makeText(getContext(), "dodano" + getId_2(), Toast.LENGTH_LONG).show();
}
})
.setNegativeButton("Prekliči", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
Toast.makeText(getContext(), "Preklical sem", Toast.LENGTH_LONG).show();
}
});
AlertDialog alertDialog = adb.create();
alertDialog.setCancelable(true);
alertDialog.show();
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
mmAdapter = new ToDoRecyclerViewAdapter(listAktivnosti(getId_2()), getContext(), mListener);
mmAdapter.setOnItemClickListner(new ToDoRecyclerViewAdapter.onItemClickListner() {
#Override
public void onClick(long i) {
Intent intent = new Intent(getActivity(), PodrobnostiActivity.class);
intent.putExtra("key_id", i);
startActivity(intent);
Toast.makeText(getContext(), "" + i, Toast.LENGTH_SHORT).show();
}
});
mmAdapter.setOnLongClick(new ToDoRecyclerViewAdapter.OnLongClickListener_() {
#Override
public void onLongClick(long i, String item) {
if (item.equals("doing")) {
boolean update_1 = db.updateList(i, item);
if (update_1) {
//NAREDI SE LEPE ANIMACIJE
android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(TodoFragment.this).attach(TodoFragment.this).commit();
Toast.makeText(getContext(), "Dodano v bazo.!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "Prislo je do napake!", Toast.LENGTH_SHORT).show();
}
}
}
});
recyclerView.setAdapter(mmAdapter);
}
return view;
}
EDITED
private long fk_id;
public long getId_2() {
return fk_id;
}
public void setId_2(long fk_id) {
this.fk_id = fk_id;
}
EDIT_2
This part is in my activities onCreate
Intent intent = getIntent();
long id = intent.getLongExtra("intVariableName",0);
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, TodoFragment.newInstance(id), "a");
fragmentTransaction.commit();
And i made a newInstance method in my fragment.
public static TodoFragment newInstance(long id) {
TodoFragment fragment = new TodoFragment();
Bundle b = new Bundle();
b.putLong("fk",id);
fragment.setArguments(b);
return fragment;
}
Try the following:
Since you already have access to the data within your variable fk_id in your Fragment, you can mark it as final, and pass it to your Toast:
Toast.makeText(getContext(), "dodano" + fk_id, Toast.LENGTH_LONG).show();
OR
Try marking your getId_2 and setId_2 with synchronized as well as your onCreateView(), this way, the data shared between the two methods will be synchronized.

Fragment,DialogFragment Issue

I am calling dialog fragment from FragmentA and returning some values to fragmentA. Now issue is whenever i go to another fragmentB from same fragmentA and return to it my dialog fragment values get cleared.
when i click on consultant doctor textview, a dialog opens (Pic 2). On Selecting an item (Pic 2),returns a value back to FragmentA. Pic 3 is a Fragment B which opens on same activity. But when i click on cross button on pic 3 and popBackStack , my value for consult doctor clears shown in Pic 4.
Pic 4 is an ISSUE
DialogFragment
#Override
public void onStart() {
super.onStart();
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
getDialog().getWindow().setGravity(Gravity.CENTER);
getDialog().setCancelable(false);
getDialog().setCanceledOnTouchOutside(false);
getDialog().closeOptionsMenu();
}
#Override public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Nullable #Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
View rootView = inflater.inflate(R.layout.consultant_doc_dialog, container, false);
recyclerView = (RecyclerView)rootView.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
adapter = new ConsultantDoctAdapter(getContext(),this);
adapter.getDocList().addAll(new ArrayList<DoctorList>());
recyclerView.setAdapter(adapter);
adapter.getDocList().clear();
adapter.getDocList().addAll(list);
adapter.notifyDataSetChanged();
close = (ImageButton)rootView.findViewById(R.id.bt_close);
close.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
getDialog().dismiss();
}
});
//cityEditText.setOnQueryTextListener(onQueryTextListener);
return rootView;
}
Fragment
#Nullable #Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_create_leads, container, false);
ButterKnife.bind(this, view);
setRetainInstance(true);
init();
setPicker();
setSpinnerListener();
btCheckCalendar.setOnClickListener(this);
etCityId.setOnClickListener(this);
etConsultingDocId.setOnClickListener(this);
btSubmit.setOnClickListener(this);
tvClientReferral.setOnClickListener(this);
etSalesPerson.setText(sharedPref.getString(AppConstants.PREFERENCE_USER_NAME, ""));
etZone.setText(sharedPref.getString(AppConstants.USER_ZONE, ""));
etAreaCode.setText(sharedPref.getString(AppConstants.USER_AREA_CODE, ""));
setSpinner();
getConsultantDoctorList();
return view;
}
Fragment B callBack:
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_main, new MyCalendarFragment())
.addToBackStack("calendarFragment")
.commit();
DialogCallack:
ConsultantDocDialogFragment consultantDocDialog = new ConsultantDocDialogFragment();
consultantDocDialog.setParameter(getContext(), this, doclist);
consultantDocDialog.show(getActivity().getSupportFragmentManager(),
ConsultantDocDialogFragment.class.getSimpleName());
break;
Please help me so that i can able to save state of values got from dialog fragment.
Please find the following code it may help you-
This is Fragment Code where you can get CallBack from Dialog Fragment-
HomeFragment.java
public class HomeFragment extends Fragment implements AlertDFragment.Callback {
private static final int DIALOG_FRAGMENT = 100;
Button alertdfragbutton;
private View rootView;
public HomeFragment() {
}
public static HomeFragment newInstance() {
return new HomeFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_home, container, false);
initUI(rootView);
return rootView;
}
private void initUI(View rootView) {
alertdfragbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
AlertDFragment alertdFragment = new AlertDFragment();
alertdFragment.setTargetFragment(HomeFragment.this, DIALOG_FRAGMENT);
// Show Alert DialogFragment
alertdFragment.show(getChildFragmentManager(), "Alert Dialog Fragment");
}
});
}
#Override
public void accept() {
Log.e("Home ", "OK");
}
#Override
public void decline() {
}
#Override
public void cancel() {
Log.e("Home ", "CANCEL");
}
}
Here is Dialog Fragment where we declare CallBack with methods-
public class AlertDFragment extends DialogFragment {
Callback callback;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
callback = (Callback) getTargetFragment();
return new AlertDialog.Builder(getActivity())
// Set Dialog Icon
.setIcon(R.drawable.androidhappy)
// Set Dialog Title
.setTitle("Alert DialogFragment")
// Set Dialog Message
.setMessage("Alert DialogFragment Tutorial")
// Positive button
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
callback.accept();
// Do something else
//getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, getActivity().getIntent());
}
})
// Negative Button
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
callback.cancel();
// Do something else
// getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, getActivity().getIntent());
}
}).create();
}
public static interface Callback {
public void accept();
public void decline();
public void cancel();
}
}
A simple way to return values from DialogFragment is using setTargetFragment for calling a fragmentB creation, then return data to getTargetFragment (if not null). In fragmentA you can receive data through onActivityResult.
Another way is using SharedPreferences. You can get a new value with onResume or onHiddenChanged.
Instead of using the "Fragment Transition" why don't you just POP-UP your custom view
Just Create a global reference of
Dialogue dialogue
View popupView
and on click of whatever textview button etc.
you can just call a method like
void popup(){
popupView = LayoutInflater.from(getActivity()).inflate(R.layout.your_calenderlayout, null);
//suppose you have TextView cal_textview in popUp view i.e, your_calenderlayout
cal_textview = (TextView ) popupView.findViewById(R.id.cal_textview);
dialog = new Dialog(getContext());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCanceledOnTouchOutside(true);
dialog.setContentView(popupView); //and just add your popUpview
// For setting backgroung
/*dialog.getWindow().setBackgroundDrawableResource(android.R.color.Transparent);
*/
//For setting the width or height of popup
/*WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.CENTER;
dialog.getWindow().setAttributes(lp);*/
dialog.show();
}
and on dismiss of popUp or on click of the view inside popupView you set the value of variables or member inside the fragment directly
Hope this will help
You can use Shared prefs or sqlite to get your values and if you think its use less to save your temporary data in share prefs or sqlite Then Singleton model is a good option .. i believe we should follow KISS
design principle :P

How to load Fragment using AlertDialog?

I'm trying to load fragment after alert Dialog response but when i attempt to load logcat shows "IllegalStateException: Fragment not attached to Activity". Generally IllegalStateException comes when you try to perform work after the Fragment is no longer attached to the Activity. but in my case every thing is fine i don't understand why fragment is not attached to an activity.
this is my MainActivity:
using this class i call DilogCreate which extends DialogFragment.
public class MainActivity extends AppCompatActivity {
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new DilogCreate(view.getContext(),R.string.tilte,R.string.no,R.string.yes);
}
});
}
this is my DilogCreate class:
on the basis of dialog response decide fragment can be loaded or not if dialog response yes i call another activity name Second.java under this class i try to load fragment.
public class DilogCreate extends DialogFragment {
AlertDialog alertDialog;
public DilogCreate(final Context context, int tilte, int no, int yes) {
AlertDialog.Builder mAlertDilog = new AlertDialog.Builder(context);
mAlertDilog.setNegativeButton(yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(context, second.class);
startActivity(intent);
}
});
alertDialog = mAlertDilog.create();
alertDialog.show();
}
}
this is my my Second.java class:
this class is appear because of dialog response and under this class i tried to load fragment.
public class Second extends AppCompatActivity {
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loadFragment);
fragmentManager=getSupportFragmentManager();
fragmentTransaction=fragmentManager.beginTransaction();
Myfragment myfragment=new Myfragment();
fragmentTransaction.replace(R.id.cont,myfragment);
fragmentTransaction.commit();
}
}
this is MyFragment.java extends Fragment :
public class Myfragment extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag,container,false);
}
}
Logcat status:
java.lang.IllegalStateException: Fragment DilogCreate{8aea1d4} not attached to Activity
please help me guys i have no idea why this error is coming.
new DilogCreate(view.getContext(),R.string.tilte,R.string.no,R.string.yes);
pass MainActivity.this instead of view.getContext().You need to pass activity context here.
fragment is load on the activity and one activity switch to another by using base reference that's why i need to call startActivity() method using base Activity refrence.
so i change startActivit() method in the DilogCreate class like this:
Intent intent=new Intent(context,Second.class);
context.startActivity(intent);//make sure context is the refrence of the base context

Android: Call onClick from fragment/activity for views within Custom Dialog

I've created a custom dialog, which has multiple views within it.
On click of these Views, I would like to start activities for results, like Camera, Gallery, etc.
CustomDialog
public class CustomDialog extends BottomBaseDialog {
public static LinearLayout ll_camera;
public static LinearLayout ll_gallery;
public CustomDialog(Context context, View animateView) {
super(context, animateView);
}
#Override
public View onCreateView() {
View inflate = View.inflate(context, R.layout.dialog_custom, null);
ll_camera = ViewFindUtils.find(inflate, R.id.camera_linear_layout);
ll_gallery = ViewFindUtils.find(inflate, R.id.gallery_linear_layout);
return inflate;
}
#Override
public boolean setUiBeforShow() {
ll_camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// OPEN INTENT FOR CAMERA
dismiss();
}
});
ll_gallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// OPEN INTENT FOR GALLERY
dismiss();
}
});
return false;
}
}
Then within my fragment, I've displayed this dialog by
IOSTaoBaoDialog dialog = new IOSTaoBaoDialog(getActivity(), AddActivity.drawerLayout);
dialog.show();
How can I call onClick for the Camera and Gallery Linear Layout views from within my Fragment?
I also need to get the result of the activities back into the fragment, so I can process it.
Please suggest.
I've done a lot of search and I came across suggestions to use Interfaces, however, I do not clearly understand how that will work.
IOSTaoBaoDialog dialog = new IOSTaoBaoDialog(getActivity(), AddActivity.drawerLayout);
dialog.show();
Change To
IOSTaoBaoDialog dialog = new IOSTaoBaoDialog(getparent(), AddActivity.drawerLayout);
dialog.show();
If This Not Work Then Try
IOSTaoBaoDialog dialog = new IOSTaoBaoDialog(getActivity().getparent(), AddActivity.drawerLayout);
dialog.show();
OR
IOSTaoBaoDialog dialog = new IOSTaoBaoDialog(getparent().getActivity(), AddActivity.drawerLayout);
dialog.show();
For startActivityForResult()
IF(getparent() == null)
{
startActivityForResult();
}else
{
getparent().startActivityForResult();
}
You should be using DialogFragment, look at this answer. Here are the two important lines from that answer:
In calling Fragment:
dialog.setTargetFragment(this, YES_NO_CALL);
In DialogFragment:
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
Basically, when you call the DialogFragment, you need to call setTargetFragment with a request code. Then in your fragment, you handle the response in onActivityResult.
I figured out the solution for this, for if somebody else also gets stuck in the same situation:
I passed the instance of my calling fragment to the dialog. Then from within the dialog, I called the fragment.startActivityForResult() method. So when the result was received, it was sent to the onActivityResult() method of the fragment.
The code is:
Dialog:
public class SelectApplicationDialog extends BottomBaseDialog {
public static LinearLayout ll_camera;
public static LinearLayout ll_gallery;
Fragment fragment;
public SelectApplicationDialog(Context context, View animateView, Fragment fragment) {
super(context, animateView);
this.fragment = fragment;
}
#Override
public View onCreateView() {
View inflate = View.inflate(context, R.layout.dialog_select_application, null);
ll_camera = ViewFindUtils.find(inflate, R.id.camera_linear_layout);
ll_gallery = ViewFindUtils.find(inflate, R.id.gallery_linear_layout);
return inflate;
}
#Override
public boolean setUiBeforShow() {
ll_camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File externalStorageFile = new File(imagePath);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
AddCourseFragment.imageUri = Uri.fromFile(externalStorageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, AddCourseFragment.imageUri);
fragment.startActivityForResult(intent, 1);
dismiss();
}
});
ll_gallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
fragment.startActivityForResult(pickPhoto, 2);
dismiss();
}
});
return false;
}
}
Calling Fragment:
public void openUploadImageDialog() {
SelectApplicationDialog dialog = new SelectApplicationDialog(getContext(),
AddActivity.addLinearLayout, AddCourseFragment.this);
dialog.show();
}

Show DialogFragment from another DialogFragment

I have a DialogFragment that displays a list of options to the user, one of these options is "Delete" option, when the user presses the delete option I want to show another DialogFragment as a confirmation, unfortunately, the confirmation dialog doesn't show.
here is my code
First Fragment code
public class ContactDialogOption extends SherlockDialogFragment {
public static final String TAG = ContactDialogOption.class.getSimpleName();
public ContactDialogOption() {
super();
// TODO Auto-generated constructor stub
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIcon(R.drawable.ic_launcher);
builder.setTitle(R.string.options);
builder.setItems(new String[] {
getString(R.string.call), getString(R.string.send_message),
getString(R.string.copy), getString(R.string.edit),
getString(R.string.delete)
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if(which == 4) //delete
{
FragmentManager mgr = getActivity().getSupportFragmentManager();
FragmentTransaction ft = mgr.beginTransaction();
Fragment old = mgr.findFragmentByTag("SecondFragment");
if (old != null) {
ft.remove(old);
}
ft.addToBackStack(null);
fragment.show(ft, fragmentTag);
}
}
});
return builder.create();
}
}
I got the exact same problem, this situation does not happen when you try to open a DialogFragment from a Fragment.
The only solution I found was to modify the following call:
fragment.show(ft, fragmentTag);
To:
fragment.show(getFragmentManager(), fragmentTag);
The problem with this solution is that we cannot work on the FragmentTransition.
I don't understand why the behavior is different than with the fragments.
I came across the same problem of not being able to show another DialogFragment from within the positive and negative click listeners of the first DialogFragment. My solution was to immediately pop the first fragment, which allows the second DialogFragment to attach and display successfully.
// Call this before adding the second dialog fragment
activity.getSupportFragmentManager().popBackStackImmediate();
Please check this following code. Hope this will help many of you!
public class SubcategoryFragment extends DialogFragment {
public SubcategoryFragment() {
}
public static SubcategoryFragment newInstance(Integer code, String name) {
SubcategoryFragment fragment = new SubcategoryFragment();
mCode = code;
mTitle = name;
return fragment;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
liststring = new ArrayList<>();
getAdapter();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_subcategory, container, false);
gridView = (GridView) view.findViewById(R.id.sub_grid);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
closeDialog = (ImageView) getDialog().findViewById(R.id.closeDialog);
title = (TextView) getDialog().findViewById(R.id.dialogTitle);
gridView = (GridView) getDialog().findViewById(R.id.sub_grid);
title.setText(String.format("Choose %s", mTitle));
closeDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getDialog().dismiss();
}
});
}
#Override
public Dialog onCreateDialog(#NonNull Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// request a window without the title
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
// closeDialog = (ImageView) dialog.findViewById(R.id.closeDialog);
return dialog;
}
public void getAdapter() {
gridAdapter = new HomeSubGridViewAdapter(getContext(), R.layout.gridview_custom_layout, liststring);
gridView.setAdapter(gridAdapter);
}
}
This is the method for calling dialog from fragment
fragmentManager = ((FragmentActivity) context).getSupportFragmentManager();
SubcategoryFragment postalFragment = SubcategoryFragment.newInstance(Integer.valueOf(item.getId()), item.getName());
postalFragment.show(fragmentManager, "SubcategoryFragment");
Feel Free to ask if you feel any problem is that
You can call a DialogFragment from Another DialogFragment.
NewDialogFragment newDialogFragment= new NewDialogFragment();
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
newDialogFragment.show(transaction, "New_Dialog_Fragment");
Very recently, I had this problem and none of the options above worked for me. I tried using the method below:
DialogFragment fragment = new MyFragment(); //where MyFragment is my fragment I want to show
fragment.setCancelable(true);
fragment.show(getSupportFragmentManager(), "timePicker");
This will ONLY work if you're using this in an activity (i.e to call a dialog fragment from an activity class).
I however fixed this by downcasting my activity instance to an AppCompat activity and using it to call getSupportFragment() as shown below:
DialogFragment timeFragment = new TimePicker();
timeFragment.setCancelable(true);
AppCompatActivity activity = (AppCompatActivity) getActivity();
timeFragment.show(activity.getSupportFragmentManager(), "timePicker");
I hope this helps.. Merry coding!!
This is the code that works for me:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (getArguments() == null) {
throw new InvalidParameterException("The key types dialog needs the protocol id to be in the arguments");
}
if (mCallback == null) {
throw new InvalidParameterException("The key types dialog needs an callback to be set");
}
mProtocolId = getArguments().getInt(ApplicationConstants.FragmentsConstants.PROTOCOL_ID);
final List<KeyTypeEntity> allKeyTypes = BusinessFacade.getInstance(getActivity()).KeyTypeLogic.getAllKeyTypes();
ArrayAdapter<KeyTypeEntity> keyTypeAdapter = new ArrayAdapter<KeyTypeEntity>(getActivity(), android.R.layout.simple_list_item_1, allKeyTypes);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("").setAdapter(keyTypeAdapter, new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
final KeyTypeEntity keyTypeEntity = allKeyTypes.get(which);
AlertDialog.Builder number = new AlertDialog.Builder(getActivity());
List<String> keyNumbers = new ArrayList<String>();
for (int i = 0; i < 50; i++) {
keyNumbers.add("" + (i + 1));
}
ArrayAdapter<String> kAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, keyNumbers);
number.setTitle("").setAdapter(kAdapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
addNewKey(keyTypeEntity, which + 1);
}
});
number.show();
}
}).setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
mCallback.onDialogClosed();
}
});
mDialog = builder.create();
return mDialog;
}
In the first click handler I just create a new dialog and show it. This will close the first dialog, open the second one, and when the user clicks on an item in the list, the second click handler is called.
Hope this helps, and I am not too late :)
You can pass FragmentManage to newInstance() method of First DialogFragment then you can use it to show new dialogfragment
this is my code.
private static FragmentManager fragmentManager;
public static PlayListDialog newInstance(Context context, FragmentManager fragmentManager1) {
playListDialog = new PlayListDialog();
mContext = context;
fragmentManager = fragmentManager1;
return playListDialog;
}
#Override
public void createNewPlaylist() {
NewPlayListDialog newPlayListDialog = NewPlayListDialog.newInstance(mContext);
newPlayListDialog.showDialog(fragmentManager.beginTransaction(),fragmentManager.findFragmentByTag("newdialog"));
}
Use this:
getActivity().getSupportFragmentManager
instead of
getChildFragmentManager().
Hope this helps.
If you want the kotlin version use this:
val newDialogFragment = NewDialogFragment()
val transaction: FragmentTransaction =
requireActivity().supportFragmentManager.beginTransaction()
newDialogFragment.show(transaction, "New_Dialog_Fragment")

Categories

Resources