Reputation: 491
So reading through the Google API Guides I came across how to load a custom layout within an Alert Dialog Box here.
I wrote a class that extends a DialogFragment class like this:
String product;
String description;
String company;
public void getAdInfo(String p, String d, String c)
{
product = p;
description = d;
company = c;
}
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.ad_dialog, null));
TextView pt = (TextView) getView().findViewById(R.id.product);
pt.setText(product);
TextView dt = (TextView) getView().findViewById(R.id.description);
dt.setText(description);
TextView ct = (TextView)getView().findViewById(R.id.company);
ct.setText(company);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// do something
}
});
builder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
}
});
return builder.create();
}
}
Here's the layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
/>
<TextView
android:id="@+id/company"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
/>
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="false"
/>
I instanciate the Dialog within an OnClickListener with these lines.
AdDialogFragment ad = new AdDialogFragment();
ad.getAdInfo(j.getAttribute("product"), j.getAttribute("description"), j.getAttribute("company"));
ad.show(getFragmentManager(), null);
j being an element from an xml node.
When I click on the button that's supposed to run the dialog I get this NullPointerException error from LogCat:
E/AndroidRuntime(10483): at com.onix.mallard.android.guifrag.AdDialogFragment.onCreateDialog(AdDialogFragment.java:29)
The error refers to the line:
pt.setText(product);
Ultimately, it crashes the app completely. How can I change the layout of a DialogFragment dynamically? The Android API Guide says that DialogFragments are bound by the same lifecycle as Fragments, but that doesn't tell me much since they don't make use of FragmentTransactions (to my knowledge). If this is not possible and I need to instance the information as an Activity, no harm is done.
If it helps, the dialog is called from within a Fragment.
Upvotes: 3
Views: 6199
Reputation: 491
I solved this issue a while ago by instead of recurring to the AlertDialog class I used a regular Activity. In AndroidManifest.xml, the activity specification has the following line.
android:theme="@styles/Theme.HoloLight.Dialog"
A word of advice, Linear Layout doesn't work. Try RelativeLayout.
Upvotes: 0
Reputation: 27236
Here's how I would do that (untested code) ;)
Your custom Dialog:
public class AdDialogFragment extends DialogFragment {
String mProduct;
String mDescription;
String mCompany;
TextView mProductTV;
TextView mDescriptionTV;
TextView mCompanyTV;
public void setAdInfo(String product, String desc, String company)
{
mProduct = product;
mDescription = desc;
mCompany = company;
}
public AdDialogFragment() {
super();
}
public static AdDialogFragment newInstance() {
return new AdDialogFragment();
}
public Dialog onCreateDialog(final Bundle savedInstanceState) {
LayoutInflater factory = LayoutInflater.from(getActivity());
final View content = factory.inflate(R.layout.ad_dialog, null);
mProductTV = (TextView) content.findViewById(R.id.product);
mDescriptionTV = (TextView) content.findViewById(R.id.description);
mCompanyTV = (TextView) content.findViewById(R.id.company);
fillTextViews();
AlertDialog.Builder dialog;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
dialog = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.Theme.DeviceDefault.Dialog.)); //can't remember the name or create a custom theme.
} else {
dialog = new AlertDialog.Builder(getActivity());//anything below honeycomb can die :).
}
// now customize your dialog
dialog.setTitle(getActivity().getString(R.string.some_title_if_any))
.setView(content)
.setCancelable(true) //this is the default I think.
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// do something
}
});
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
}
});
return dialog.create();
}
private void fillTextViews() {
mProductTV.setText(mProduct);
mDescriptionTV.setText(mDescription);
mCompanyTV.setText(mCompany);
}
And this is how you call it from an Activity for example:
public void showYourFancyDialog() {
AdDialogFragment dialog = AdDialogFragment.newInstance();
dialog.setAdInfo(yourProduct, yourDescription, yourCompany);
dialog.show(getSupportFragmentManager(), "dialog");
}
Using patterns from Google's documentation
Upvotes: 4
Reputation: 8747
You could try the following, it has worked for me:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.ad_dialog, null));
builder.setView(v);
And then call findViewById
like such:
v.findViewById();
Upvotes: 2