Android Can';不要动态更改自定义对话框片段布局

Android Can';不要动态更改自定义对话框片段布局,android,android-fragments,nullpointerexception,android-alertdialog,Android,Android Fragments,Nullpointerexception,Android Alertdialog,因此,通过阅读GoogleAPI指南,我发现了如何在警报对话框中加载自定义布局 我编写了一个扩展DialogFragment类的类,如下所示: String product; String description; String company; public void getAdInfo(String p, String d, String c) { product = p; description = d; company = c; } public Dial

因此,通过阅读GoogleAPI指南,我发现了如何在警报对话框中加载自定义布局

我编写了一个扩展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_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"
   />
j是来自xml节点的元素

当我单击应该运行对话框的按钮时,我从LogCat中得到以下NullPointerException错误:

E/AndroidRuntime(10483):    at com.onix.mallard.android.guifrag.AdDialogFragment.onCreateDialog(AdDialogFragment.java:29)
错误是指以下行:

pt.setText(product);
最终,应用程序完全崩溃。如何动态更改DialogFragment的布局?AndroidAPI指南说DialogFragments与Fragments受相同的生命周期约束,但这并没有告诉我太多,因为据我所知,他们没有使用FragmentTransactions。如果这是不可能的,并且我需要将该信息作为一项活动进行实例,则不会造成任何伤害


如果有帮助,将从片段中调用该对话框。

您可以尝试以下方法,它对我有效:

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();

下面是我将如何做到这一点(未经测试的代码);)

您的自定义对话框:

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);
}
这就是你在活动中对它的称呼,例如:

public void showYourFancyDialog() {
   AdDialogFragment dialog = AdDialogFragment.newInstance();
   dialog.setAdInfo(yourProduct, yourDescription, yourCompany);
   dialog.show(getSupportFragmentManager(), "dialog");
}

使用

中的模式,我不久前解决了这个问题,我使用了常规活动,而不是重复使用AlertDialog类。在AndroidManifest.xml中,活动规范有以下行

android:theme="@styles/Theme.HoloLight.Dialog"

一句忠告,线性布局不起作用。请尝试RelativeLayout。

为了进一步解释,
getView
返回片段的视图,但您尚未设置它。您仍在创建它的过程中。所以你应该像这个答案所描述的那样直接获取视图。谢谢@kabuko,我真的很想知道为什么
getView
对我不起作用,我只是尝试了一下,昨天它正好起作用,所以我就这么做了,没有找到原因。这有助于使其更有意义。@TronicZomB不太清楚。检查马丁对这个问题的回答。DialogFragment不再崩溃,但仍然无法工作。我认为您的getAdInfo()应该设置为setAdInfo,虽然这没有多大变化,但您正在设置值,而不是获取值。我使用了您的实现。我使用了dialog.show(getFragmentManager(),“ad”)而不是支持管理器,因为我在onClickListener中调用它。碰巧,LogCat抛出了另一个错误:
E/AndroidRuntime(1550):android.view.WindowManager$BadTokenException:无法添加窗口--调试后,标记null不适用于应用程序
,它与前面提到的代码行有关。怎么办?这可能是一个不好的环境,你在使用活动的环境吗?如果使用ApplicationContext,则无法显示对话框(应用程序上下文无法接触UI)。此外,您是否仅为蜂巢和更高版本开发?因为如果导入正确的软件包(android.support.v4.app),getFragmentManager和getSupportFragmentManager都是可以访问的。你是什么意思,我把这叫做一个听众?匿名内联类具有对父对象的引用。
android:theme="@styles/Theme.HoloLight.Dialog"