无法动态更改自定义 DialogFragment 布局
Posted
技术标签:
【中文标题】无法动态更改自定义 DialogFragment 布局【英文标题】:Can't change a Custom DialogFragment layout dynamically 【发布时间】:2013-04-27 00:08:01 【问题描述】:通过阅读 Google API 指南,我发现了如何在警报对话框 here. 中加载自定义布局@
我写了一个扩展 DialogFragment 类的类,如下所示:
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();
这是布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:id="@+id/product"
android:layout_
android:layout_
android:textIsSelectable="false"
/>
<TextView
android:id="@+id/company"
android:layout_
android:layout_
android:textIsSelectable="false"
/>
<TextView
android:id="@+id/description"
android:layout_
android:layout_
android:textIsSelectable="false"
/>
我用这些行在 OnClickListener 中实例化 Dialog。
AdDialogFragment ad = new AdDialogFragment();
ad.getAdInfo(j.getAttribute("product"), j.getAttribute("description"), j.getAttribute("company"));
ad.show(getFragmentManager(), null);
j 是来自 xml 节点的元素。
当我单击应该运行对话框的按钮时,我从 LogCat 收到此 NullPointerException 错误:
E/AndroidRuntime(10483): at com.onix.mallard.android.guifrag.AdDialogFragment.onCreateDialog(AdDialogFragment.java:29)
错误指的是以下行:
pt.setText(product);
最终,它使应用程序完全崩溃。如何动态更改 DialogFragment 的布局? Android API 指南说 DialogFragments 与 Fragments 受相同的生命周期约束,但这并没有告诉我太多,因为它们没有使用 FragmentTransactions(据我所知)。如果这是不可能的,而我需要将信息作为 Activity 实例化,则不会造成任何损害。
如果有帮助,将从片段中调用对话框。
【问题讨论】:
您的 getAdInfo() 应该是 setAdInfo 我认为,虽然变化不大,但您正在设置值,而不是获取它们。 【参考方案1】:我会这样做(未经测试的代码);)
您的自定义对话框:
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);
这就是您从 Activity 中调用它的方式,例如:
public void showYourFancyDialog()
AdDialogFragment dialog = AdDialogFragment.newInstance();
dialog.setAdInfo(yourProduct, yourDescription, yourCompany);
dialog.show(getSupportFragmentManager(), "dialog");
使用来自Google's documentation的模式
【讨论】:
我使用了你的实现。我使用dialog.show(getFragmentManager(), "ad");
而不是支持管理器,因为我在 onClickListener 中调用它。碰巧,LogCat 抛出另一个错误:E/AndroidRuntime(1550): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
调试后它与上述代码行有关。怎么办?
这可能是一个糟糕的上下文,您使用的是 Activity 的上下文吗?如果使用ApplicationContext,则无法显示对话框(App Context无法触摸UI)。
你也只为 HONEYCOMB 及以上版本开发吗?因为如果您导入正确的包 (android.support.v4.app),getFragmentManager 和 getSupportFragmentManager 都可以访问。你是什么意思我在 onClickListener 中调用它?匿名内联类具有对父对象的引用。【参考方案2】:
您可以尝试以下方法,它对我有用:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.ad_dialog, null));
builder.setView(v);
然后像这样调用findViewById
:
v.findViewById();
【讨论】:
为了进一步解释,getView
返回片段的视图,但您还没有设置它。您仍在创建它的过程中。所以你应该直接得到这个答案描述的视图。
谢谢@kabuko,我真的很想知道为什么getView
对我不起作用,我刚刚尝试了这个,它昨天碰巧起作用了,所以我继续使用它并没有绕过去查原因。这有助于使这更有意义。
@TronicZomB 不完全是。检查马丁对这个问题的回答。 DialogFragment 不再崩溃,但仍然无法正常工作。【参考方案3】:
我不久前解决了这个问题,我没有重复使用 AlertDialog 类,而是使用了常规 Activity。在 AndroidManifest.xml 中,活动规范有以下一行。
android:theme="@styles/Theme.HoloLight.Dialog"
一个忠告,线性布局不起作用。试试相对布局。
【讨论】:
以上是关于无法动态更改自定义 DialogFragment 布局的主要内容,如果未能解决你的问题,请参考以下文章
重叠DialogFragment,在方向更改时以错误的顺序重新创建
Android自定义DialogFragment问题[重复]