I am creating a dialog and setting setContentView of a layout. And I am programmatically adding buttons, images to layout in dialog setContentView . Now how I can assign dialog box view to another view.
That is a layout is assigned to a a view like below
View getview=R.layout.tamil_alphabet_speak_word;
Similarly how can I assign the dialog box view to another view. Since I am adding all elements to the view "TamilAlphabets" programmatically the child are null it returns for the below code.
Alphbetdialog=new Dialog(TamilAlphabets.this);
Alphbetdialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Alphbetdialog.setContentView(R.layout.tamil_alphabetsdialog);
(adding elements to the layout "TamilAlphabets" code
..............
)
LayoutInflater inflator=(LayoutInflater)TamilAlphabets.this.getSystemService
(TamilAlphabets.this.LAYOUT_INFLATER_SERVICE);
View row=inflator.inflate(tamil_alphabetsdialog, Parent,false);
LinearLayout l1=(LinearLayout)row.findViewById(R.id.alphabetlayout1);
ViewGroup vg=(ViewGroup)l1;
vg.getChildCount();
So I need to assign the dialog box view to another view how do I do that.
I need something like this
View getview=<I need dialog box view>
You should avoid using Dialog class directly and instead use Dialog subclass's or DialogFragment
https://developer.android.com/guide/topics/ui/dialogs.html:
The Dialog class is the base class for dialogs, but you should avoid instantiating Dialog directly. Instead, use one of the following subclasses:
AlertDialog
A dialog that can show a title, up to three buttons, a list of selectable items, or a custom layout.
DatePickerDialog or TimePickerDialog
A dialog with a pre-defined UI that allows the user to select a date or time.
In any case im guessing that what you want is a custom dialog and what is recomendaded is using the DialogFragment class in that case here is an example
Dialog fragment layout
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent">
Dialog class
public class DialogExampleFragment extends DialogFragment {
private static final String ARG_PARAM = "extra:PARAM";
private String mText;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
mText = arguments.getString(ARG_PARAM);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setTitle("title");
return dialog;
}
public static DialogExampleFragment newInstance(String message) {
Bundle args = new Bundle();
args.putSerializable(ARG_PARAM, message);
DialogExampleFragment fragment = new DialogExampleFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_dialog_example, container, false);
TextView t = (TextView) root.findViewById(R.id.textView1);
t.setText(mText);
return root;
}
}
To show as a dialog
DialogExampleFragment.newInstance("Message")
.show(getFragmentManager(), "dialog");
Note since a DialogFragment is a fragment it has de advantage of being able to be shown as a Dialog or as a regular fragment you can get all the information on the link i posted above
Related
In my activity, on click of a button I am opening a Dialog which has a RecyclerView in it.
final Dialog dialog = new Dialog(MyActivity.this);
dialog.setTitle("Details");
dialog.setContentView(R.layout.details_popup);
RecyclerView detailsRecyclerView = (RecyclerView) dialog.findViewById(R.id.detailsRecyclerView);
Button detailsCloseButton = (Button) dialog.findViewById(R.id.detailsCloseButton);
//feedbackResponseSubList contains n items
**DetailsAdapter detailsAdapter = new DetailsAdapter(R.layout.detail_item, feedbackResponseSubList);
detailsRecyclerView.setAdapter(detailsAdapter);**
detailsCloseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
The close button is visible but the recyclerView is not getting populated with data. Even the methods onCreateViewHolder(), onBindViewHolder() and getItemCount() of Detailsdapter are not getting called.
I have figured out the problem. After setting layout manager in recyclerview, it works fine.
LinearLayoutManager layoutManager = new LinearLayoutManager(dialog.getContext());
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
detailsRecyclerView.setLayoutManager(layoutManager);
The problem is that the Dialog is already created when you try to modify the adapter, because of that It's not getting populated with your data.
You have two options, create your own Dialog which extend Dialog class and in onCreate() put your code to populate the list or add adapter.notifyDataSetChanged() after setAdapter() to tell that your data inside the list was updated.
Use a dialog fragment instead of Dialog. An dialog fragment gives all the features of a dialog while providing the functionality of a fragment.
public class AlertDialogFragment extends DialogFragment {
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflate layout with recycler view
View v = inflater.inflate(R.layout.details_popup, container, false);
RecyclerView detailsRecyclerView = (RecyclerView) getActivity().findViewById(R.id.detailsRecyclerView);
DetailsAdapter detailsAdapter = new DetailsAdapter(R.layout.detail_item, feedbackResponseSubList);
detailsRecyclerView.setAdapter(detailsAdapter);
detailsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return v;
}
public Dialog onCreateDialog(Bundle SavedInstanceState) {
//The rest of the code you will get when u search for dialogfragments
I dont know what path to take, I have a MainActivity class which host my ViewPagerTabStrip and each tabs are fragments, one tab consist of ListView and a button. When I click that button I want to either inflate a UI where the user fills in editfields or dialogFragment similiar process. Working with fragments what is best way to implement this? and How can I? I have set a onClickListener on the button and is working.
I have a method in my DBHelper that puts the users input into an SQLite database.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_notes, container, false);
add = (Button) view.findViewById(R.id.addbtn);
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(getActivity(), "onClick works", Toast.LENGTH_SHORT).show();
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
LayoutInflater inflater= getActivity().getLayoutInflater();
//this is what I did to added the layout to the alert dialog
View layout= inflarter.inflate(R.layout.alert_dialog,null);
alert.setView(layout);
final EditText titleInput=(EditText)layout.findViewById(R.id.dialog_title);
final EditText bodyInput=(EditText)layout.findViewById(R.id.dialog_body);
}
});
return view;
}
What do I call in the Fragment
Simplest way would be to use an AlertDialog with a custom layout, which has has some EditTexts. When the OK button in the dialog is clicked, get the values from the EditTexts, and put them in your database.
I'm writing a custom dialog on android.
I did this using the onCreateView method.
public class CheckpointLongPressDialog extends DialogFragment {
public void CheckpointLongPressDialog() {}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_checkpoint_long_press_dialog, container);
getDialog().setTitle("TITLE");
return view;
}
How can i center the title programmatically?
Maybe its not the best way, I use a custom title TextView.
TextView title = new TextView(mainActivity);
title.setText(alertTitle);
title.setBackgroundResource(R.drawable.gradient);
title.setPadding(10, 10, 10, 10);
title.setGravity(Gravity.CENTER); // this is required to bring it to center.
title.setTextSize(22);
getDialog().setCustomTitle(title);
I solve the problem using a builder and inflating the xml layout.
private AlertDialog.Builder builder;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.fragment_checkpoint_long_press_dialog, null));
// Create the AlertDialog object and return it
return builder.create();
}
Try this..
final int titleId = getActivity().getResources().getIdentifier("alertTitle", "id", "android");
TextView title = (TextView) getDialog().findViewById(titleId);
if (title != null) {
title.setGravity(Gravity.CENTER);
}
What if you use the whole layout to inflate also your custom title?. Instead of getDialog().setTitle("TITLE"); you can also include a TextView in your custom layout for the title.
The title view is using default theme. You have 2 ways to do what you want, first one is better for having a more customized experience:
Use this to have a dialog without title, and then make custom title bar in the layout of this fragment.
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
Extend the default theme for the dialog and update it, then set it in this dialog.
THere a tons of question about android.util.AndroidRuntimeException: requestFeature() must be called before adding content. But none of the proposed solutions worked for me.
I have a custom DialogFragment
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity()).create();
}
#Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.notification_dialog, null);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//setting up dialog
}
I'm showing it like this
newDialogInstance().show(activity.getFragmentManager(), "tag-dialog-fragment");
And each time I get:
android.util.AndroidRuntimeException: requestFeature() must be called before adding content
at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:226)
at com.android.internal.app.AlertController.installContent(AlertController.java:234)
at android.app.AlertDialog.onCreate(AlertDialog.java:337)
at android.app.Dialog.dispatchOnCreate(Dialog.java:355)
at android.app.Dialog.show(Dialog.java:260)
at android.app.DialogFragment.onStart(DialogFragment.java:490)
at android.app.Fragment.performStart(Fragment.java:1719)
Could someone explain me what is going on here?
This is a late answer but maybe that'll help someone, the problem comes from the fact that you are trying to inflate the dialog from both onCreateDialog and onCreateView. To avoid this you can avoid using onCreateView and inflate your layout in onCreateDialog instead.
You would get this:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View layout = inflater.inflate(R.layout.notification_dialog, null);
/** Add modifications on your layout if needed */
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add your custom layout to the builder
builder.setView(layout);
return builder.create();
}
Then just remove onCreateView or use it to do other things like using savedInstanceState as explained in this other answer: https://stackoverflow.com/a/15602648/2206688
You can also review the documentation example:
http://developer.android.com/guide/topics/ui/dialogs.html#CustomLayout
Another late answer and I wrote part of it already as a comment but maybe it's useful for someone else as well.
As Yoann already wrote, the problem is that the View is created twice and, in the case of the dialog, it creates its own window which causes the problem. The official documentation (http://developer.android.com/reference/android/app/DialogFragment.html#AlertDialog) makes it seem that it is possible to overwrite onCreateView and onCreateDialog at the same time and show a custom layout that can be embedded or used AlertDialog-styled:
Instead of (or in addition to) implementing
onCreateView(LayoutInflater, ViewGroup, Bundle) to generate the view
hierarchy inside of a dialog, you may implement onCreateDialog(Bundle)
to create your own custom Dialog object.
This is most useful for creating an AlertDialog, [...]
It is possible to overwrite both methods, just not in combination with the AlertDialog.Builder.
What is working for me so far is this:
public class CustomDialogFragment extends DialogFragment {
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (isInLayout())
return super.onCreateDialog(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setView(R.layout.my_custom_layout)
.setTitle(R.string.my_title)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO implement
}
});
return builder.create();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (!isInLayout())
return super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.my_custom_layout, container);
return v;
}
}
I'm using isInLayout() to decide whether to call the super method or use the custom implementation.
EDIT: This example uses the support library classes: http://developer.android.com/reference/android/support/v7/app/AlertDialog.Builder.html#setView(int)
Use like this :
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.notification_dialog, null);
builder.setView(view);
return builder;
}
I'm trying to create a DialogFragment that shows a dialog with a custom ListView inside.
public class MultiSelectDialogCustom extends DialogFragment {
ListView mLocationList;
private ArrayList<String> mOfficeListItems = new ArrayList<String>();
public static MultiSelectDialogCustom newInstance(int title) {
MultiSelectDialogCustom dialog = new MultiSelectDialogCustom();
Bundle args = new Bundle();
args.putInt("title", title);
dialog.setArguments(args);
return dialog;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Collections.addAll(mOfficeListItems, getResources().getStringArray(R.array.offices));
View v = inflater.inflate(R.layout.fragment_choice_list, container,
true);
mLocationList = (ListView)v.findViewById(R.id.location_criteria_list);
final FunctionListArrayAdapter adapter = new FunctionListArrayAdapter(
this, android.R.layout.simple_list_item_1, mOfficeListItems);
mLocationList.setAdapter(adapter);
getDialog().setTitle(getArguments().getInt("title"));
return v;
}
}
When calling it from a fragment :
MultiSelectDialogCustom dialogFrag = MultiSelectDialogCustom_.newInstance(R.string.dialog_title);
dialogFrag.show(getActivity().getSupportFragmentManager(), null);
It only shows a blank dialog with the title... why my isn't my list displayed?
Instead of using onCreateView you should be overriding onCreateDialog and inside of it, it'll look something like:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Collections.addAll(mOfficeListItems, getResources().getStringArray(R.array.offices));
View v = getActivity().getLayoutInflater().inflate(R.layout.fragment_choice_list, null);
mLocationList = (ListView)v.findViewById(R.id.location_criteria_list);
final FunctionListArrayAdapter adapter = new FunctionListArrayAdapter(
this, android.R.layout.simple_list_item_1, mOfficeListItems);
mLocationList.setAdapter(adapter);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getArguments().getInt("title")).setView(v);
return builder.create();
}
This quote from the DialogFragment documentation page describes what you're trying to do:
Implementations should override this class and implement onCreateView(LayoutInflater, ViewGroup, Bundle) to supply the content of the dialog. Alternatively, they can override onCreateDialog(Bundle) to create an entirely custom dialog, such as an AlertDialog, with its own content.
In your case, it seems like onCreateDialog is the way to go since you want to do a custom inner view.
May be you are missing something very small but important. Are you missing notifyDataSetChanged() in your adapter?
"Once you have added the new item to the adapter you have to call notifyDataSetChanged() so that the listview refreshes itself with the new set of data found in the adapter."
what I forgot was:
view.setAdapter(adapter);
after I added that the code worked