【问题标题】:getOwnerActivity returns null in custom dialoggetOwnerActivity 在自定义对话框中返回 null
【发布时间】:2011-09-25 01:59:05
【问题描述】:

我编写了一个自定义对话框并尝试从其父活动中获取一些数据,但是当我调用 getOwnerActivity 时,我总是得到 null,谁能告诉我为什么会发生这种情况?为什么我可以在 DemoDialog 中显示数据,而无法显示来自 TestDialogActivity 的数据?

非常感谢。

DialogTestActivity

public class DialogTestActivity extends Activity {
    List<String> data = new ArrayList<String>();
    Button button;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
                showDialog(0);
            }
        });
    }

    public List<String> getData(){
        data.add("one");
        data.add("two");
        data.add("three");
        return data;
    }

    public Dialog onCreateDialog(int id){
        return new DemoDialog(this);
    }
}

演示对话框

public class DemoDialog extends Dialog {
    Context context;

    public DemoDialog(Context context) {
        super(context);
        setContentView(R.layout.dialog);
        this.context = context;
        setTitle("Delete City");
        ListView list = (ListView)findViewById(R.id.list);
        ArrayAdapter<String> aa = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_multiple_choice, ((DialogTestActivity)getOwnerActivity()).getData());
//      ArrayAdapter<String> aa = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_multiple_choice, getData());
        list.setAdapter(aa);
        list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    }

    private List<String> getData(){
        List<String> data = new ArrayList<String>();
        data.add("1");
        data.add("2");
        return data;
    }
}

【问题讨论】:

    标签: android dialog


    【解决方案1】:

    我尝试在我的custom Dialog 的所有可能方法中使用getOwnerActivity() 方法。它总是返回 null (Android 2.3)。然后我检查了它的源代码,它返回的活动只在setOwnerActivity(Activity activity) 中设置,它不会在任何地方调用。所以如果你想让getOwnerActivity()返回不同于null的值,你必须这样做:

    public MyCustomDialog(Context context) {
        super(context);
        if (context instanceof Activity) {
            setOwnerActivity((Activity) context);
        }
    } 
    

    【讨论】:

      【解决方案2】:

      如果您考虑一下这种情况,您就会明白为什么。当您调用new DemoDialog(this) 时,您将执行构造函数中的所有代码。之后,您从onCreateDialog 返回它,Android 就会发挥它的魔力。如果你尝试从构造函数中获取所有者,Android 还没有钩住它,所以你还没有所有者。

      所以您可以执行以下任一操作:

      public class DemoDialog extends Dialog {
          public DemoDialog(Context context) {
              super(context);
      
              // chances of context not being an activity is very low, but better to check.
              Activity owner = (context instanceof Activity) ? (Activity)context : null;
              if (owner != null) {
                  // owner activity is defined here
              }
          }
      
          public void onAttachedToWindow() {
              super.onAttachedToWindow();
              // getOwnerActivity() should be defined here if called via showDialog(), so do the related init here
              Activity owner = getOwnerActivity();
              if (owner != null) {
                  // owner activity defined here
              }
          }
      }
      

      请注意,第二种方法是首选,因为

      【讨论】:

      • 注意:我的意思是对话框的 onCreate() 调用。但是,如果失败,您可能需要将其放入 onAttachedToWindow() 中,因为 Android 实际上可能会任意推迟它的魔力。也就是说,如果您需要从构造函数访问所有者,则所有者是“上下文”,所以只需使用“上下文”:)
      • 感谢您的回复,萨吉德。我尝试按照您的建议进行操作,但结果为空,您能否分享您的代码?
      • 添加为上面的编辑。毕竟你必须检查 onAttachToWindow()。
      • 无论我在哪里打电话给所有者,我都会收到 null。在 Moto G3 上的 Android 5.1 Lollipop 上测试。
      【解决方案3】:

      您可以从 AppCompatDialog 扩展您的自定义对话框,并通过此代码访问活动:

      public static Activity scanForActivity(Context context) {
          if (context == null)
              return null;
          else if (context instanceof Activity)
              return (Activity) context;
          else if (context instanceof ContextWrapper)
              return scanForActivity(((ContextWrapper) context).getBaseContext());
          return null;
      }
      

      【讨论】:

        【解决方案4】:

        下面的这个对我有用。

        private Activity activity;
        
        public MyCustomDialog(Activity activity) {
            super(activity);
            this.activity = activity;
        } 
        

        然后我使用活动而不是 getOwnerActivity()。

        【讨论】:

        • 这可能会导致循环引用,Dialog Activity?
        • 这是一个很好的替代答案。我不知道曼努埃尔在说什么。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-08
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多