Create AlertDialog with both MultiChoiceItems and message - android

I'm trying to create an AlertDialog where both a message (in a TextView, for instance) and a MultiChoice-list can be displayed at the same time, but I'm a bit lost as to how to do it.
Will I have to create my own subclass of AlertDialog, or is there an easier way to do it?

You could create a normal AlertDialog but, instead of using the setMessage() method, you could just use a custom layout (you can inflate it in a View or even create a custom view) and use then the setView() method of the AlertDialog class.

Use DialogFragment for customization
public class ResponseDialog extends DialogFragment implements View.OnClickListener{
#Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.DialogAnimationFromDown;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Black_NoTitleBar);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
return dialog;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.YOUR_CUSTOM_LAYOUT, null);
//implement in layout what you want
return v;
}
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
}
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
}
}
}
for more info https://developer.android.com/reference/android/app/DialogFragment.html

Related

Android dialog has no focus

I have a problem about Android dialog, most of the issues appears on Samsung devices, I'm not sure whether other devices have the same problem.
When a dialog(AlertDialog or DialogFragment) is shown, it has no focus and I can't click at anything on the dialog. It seems that focus is still on activity or fragment who creates the dialog, the activity/fragment below the dialog has response to my touch events.
I use this to create a AlertDialog
new AlertDialog.Builder(activity)
.setTitle(R.string.about_title)
.setMessage(buildAppInfo())
.setNegativeButton(R.string.app_ok, (dialog, which) -> dialog.dismiss())
.show());
This is my DialogFragment class:
public class MyDialog extends DialogFragment {
private MyDialogBinding binding;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.my_dialog, container, false);
binding.tvTitle.setText(R.string.dialog_title);
binding.tvMessage.setText(R.string.dialog_content);
binding.btnCancel.setOnClickListener(v -> dismiss());
return binding.getRoot();
}
#Override
public void show(#NonNull FragmentManager manager, String tag) {
if (!isAdded() && null == manager.findFragmentByTag(tag)) {
super.show(manager, tag);
}
}
}
And use this to create a DialogFragment
private final MyDialog dialog = new MyDialog();
dialog.show(getChildFragmentManager(), "");
Function setCancelableOnTouchOutside does not work. This issue occurs sometimes, when it occurs, I have to restart my app. Thank you very much in advance for your help.

Textview in Dialog Fragment is not getting visible when we try to show the textview from its parent class

I have a class called "text". and then I have Dialog Fragment named "dialog" under this "text" class.
I am trying to make visible the text from the showText() which is located in the "text" class.
But it's getting visible. it's getting visible only from the dialog fragment.
Could anyone please help find out the issue.
private class text extends Activity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dialog dialogobj = new dialog();
dialogobj.show(mActivity.getFragmentManager(), "dialog");
dialogobj.showText();
}
public class dialog extends DialogFragment {
private TextView mText1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setStyle(STYLE_NO_TITLE, android.R.style.Theme_Material_Light_Dialog);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View dialogView = inflater.inflate(R.layout.dummy_layout, container, false);
mText1 = (TextView) dialogView.findViewById(R.id.left_img_view);
}
private void showText() {
mText1.setVisibility(View.Visible);
}
}
}
You have declared the variable mText1 as textview, but when call the findViewById method you are casting with Imageview. Check if it is causing the problem.
I advise using a capital letter as the first letter of your classes.
I think you should try to call your dialog initialization in the onCreate method of the Activity:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Dialog dialog = new Dialog();
dialog.show(getFragmentManager(), "dialog");
dialog.showText();
}

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 can I make a BottomSheetDialogFragment non-modal?

In onCreateView() I've tried setting some properties, but the DialogFragment still goes away on tapping outside.
I would like the fragment to remain nearly all the time while the user interacts with other parts of the app.
This is in a class that extends BottomSheetDialogFragment:
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
// makes background non-interactive
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
// prevents dimming of background
getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
// no effect?
getDialog().setCanceledOnTouchOutside(false);
this.setCancelable(false);
return view;
}
Code like:
public class MyDialogFragment extends DialogFragment {
...
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(...)
.setMessage(...)
.setCancelable(false);
...
Dialog dialog = builder.create();
dialog.getWindow();
return dialog;
}
...
}
works for me.

inside Android Dialog, how to setup onActivityResult for startActivityForResult?

From an activity, I can easily setup the onActivityResult() and call startActivityForResult() and everything works fine.
Now, I need to call startActivityForResult() from the Dialog. But I can't setup the onActivityResult(), I believe Dialog is not an Activity.
How do I get the result?
I try something like this inside a dialog but it failed.
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, m_PicUri);
((Activity) getContext()).startActivityForResult(intent, Const.TAKE_PIC_ACTIVITY_RET_CODE);
You can declare your Activity to have a Dialog theme. Look into this SO question: Android Activity as a dialog
You would change this in your AndroidManifest.xml file:
<activity android:theme="#android:style/Theme.Dialog" />
You should be able to use startActivityForResult() like normal. I know the BluetoothChat example Android program uses something similar to return the Bluetooth device that you choose from a Dialog list.
if your dialog is a dialog fragment you can use
getActivity().startActivityForResult(intent);
in this way the result is sent to the activity that created the dialog
You can use DialogFragment instead of Dialog. Because The dialog is secondary to its activity. When you start the activity with startActivityForResult(), your dialog gets dismissed
Another Example Use Callback
Create Interface
public interface DialogCallback {
void getResults(String results);
}
Create DialogFragment
public class DialogFragment extends DialogFragment {
DialogCallback dialogCallback;
public DialogFragment setCallBack(DialogCallback dialogCallback){
this.dialogCallback = dialogCallback;
return this;
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_layout, container, false);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
dialogCallback.getResults("hello");
}
}
In your Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new DialogFragment().setCallBack(dialogCallback).show(getFragmentManager(),"");
}
DialogCallback dialogCallback = new DialogCallback() {
#Override
public void getResults(String results) {
if(results!=null){
Log.e(TAG,results);
}
}
};
Output
When you dismiss the DialogFragment you will see the "hello" Log in your Activity
Use the compatibility package then build your dialog using DialogFragment
On the dialog constructor pass the reference of parent Activity, then you can use in the dialog like this,
parentActivity.startActivityForResult(intent, CODE);

Categories

Resources