The method dismissDialog(int) from the type Activity is deprecated

The method showDialog(int) from the type Activity is deprecated in android?


up vote6down votefavorite

The method showDialog(int) from the type Activity is deprecated.

What‘s the reason? and how to solve it?


7down voteaccepted

What‘s the reason?

http://developer.android.com/reference/android/app/Activity.html#showDialog(int)

Android DialogFragment vs Dialog

How to solve it?

Use the new DialogFragment class with FragmentManager instead; this is also available on older platforms through the Android compatibility package.

http://android-developers.blogspot.in/2012/05/using-dialogfragments.html


share|improve this answer

Android DialogFragment vs Dialog


up vote84down votefavorite

34

Google recommends that we use DialogFragment instead of a simple Dialog by using Fragments API, but it is absurd to use an isolated DialogFragment for a simple Yes-No confirmation message box. What is the best practice in this case?

android android-fragments android-dialog android-dialogfragment


share|improve this question

edited Jun 19 ‘13 at 21:50

samurai413x
72

asked Nov 2 ‘11 at 8:18

skayred
2,23432049

 
add a comment

4 Answers

activeoldestvotes


up vote30down voteaccepted

Yes use DialogFragment and in onCreateDialog you can simply use an AlertDialog builder anyway to create a simple AlertDialog with Yes/No confirmation buttons. Not very much code at all.

With regards handling events in your fragment there would be various ways of doing it but I simply define a message Handler in my Fragment, pass it into the DialogFragment via its constructor and then pass messages back to my fragment‘s handler as approprirate on the various click events. Again various ways of doing that but the following works for me.

In the dialog hold a message and instantiate it in the constructor:

private Message okMessage;
...
okMessage = handler.obtainMessage(MY_MSG_WHAT, MY_MSG_OK);

Implement the `onClickListener‘ in your dialog and then call the handler as appropriate:

public void onClick(.....
    if (which == DialogInterface.BUTTON_POSITIVE) {
        final Message toSend = Message.obtain(okMessage);
        toSend.sendToTarget();
    }
 }

Edit

And as Message is parcelable you can save it out in onSaveInstanceState and restore it

outState.putParcelable("okMessage", okMessage);

Then in onCreate

if (savedInstanceState != null) {
    okMessage = savedInstanceState.getParcelable("okMessage");
}

share|improve this answer

edited Nov 2 ‘11 at 12:41

answered Nov 2 ‘11 at 11:50

PJL
5,48234754

 

1  

How do you persist okMessage? The problem is that when the activity is restarted (orientation change or whatever), your custom constructor is not called and thus your okMessage will be null. –  hrnt Nov 2 ‘11 at 11:59
1  

The problem is not okMessage - the problem is okMessage‘s target which will be null if you load it from a Bundle. If the target of a Message is null, and you use sendToTarget, you will get a NullPointerException - not because the Message is null, but because its target is. –  hrnt Nov 2 ‘11 at 12:44
4  

Why We should be using DialogFragment instead of plain Dialogs ????? –  Amit Nov 10 ‘12 at 7:03
1  

What the advantages of using DialogFragment instead of a Dialog? –  Raphael Petegrosso Dec 7 ‘12 at 14:43
13  

The advantage of using a DialogFragment is that all the life cycle of the dialog will be handled for you. You will never get the error ‘dialog has leaked...‘ again. Go to DialogFragment and forget Dialogs. –  Snicolas Mar 13 ‘13 at 10:06

show 9 more comments


up vote15down vote

I would recommend using DialogFragment.

Sure, creating a "Yes/No" dialog with it is pretty complex considering that it should be rather simple task, but creating a similar dialog box with Dialog is surprisingly complicated as well.

(Activity lifecycle makes it complicated - you must let Activity manage the lifecycle of the dialog box - and there is no way to pass custom parameters e.g. the custom message to Activity.showDialog if using API levels under 8)

The nice thing is that you can usually build your own abstraction on top of DialogFragment pretty easily.


share|improve this answer

edited Dec 19 ‘11 at 11:23

answered Nov 2 ‘11 at 8:40

hrnt
5,8401728

 

    

How you will handle alert dialog callbacks (yes, no)? –  Alexey Zakharov Nov 2 ‘11 at 8:49 
    

The easiest way would be to implement a method in the hosting Activity that takes a String parameter. When the user clicks "Yes", for example, the dialog calls the Activity‘s method with parameter "agree". These parameters are specified when showing the dialog, for example AskDialog.ask("Do you agree to these terms?", "agree", "disagree"); –  hrnt Nov 2 ‘11 at 8:54
3  

But i need callback inside fragment, not activity. I can use setTargetFragment and cast it to interface. But it is hell. –  Alexey Zakharov Nov 2 ‘11 at 8:59
    

You could also fetch the target fragment by setting a tag to the target and using FragmentManager‘s findFragmentByTag. But yeah, it requires a fair bit of code. –  hrnt Nov 2 ‘11 at 9:53

add a comment


up vote8down vote

Use DialogFragment over AlertDialog:


  • Since the introduction of API level 13:

    the showDialog method from Activity is deprecated. Invoking a dialog elsewhere in code is not advisable since you will have to manage the the dialog yourself (e.g. orientation change).

  • Difference DialogFragment - AlertDialog

    Are they so much different? From Android reference regarding DialogFragment:

    A DialogFragment is a fragment that displays a dialog window, floating on top of its activity‘s window. This fragment contains a Dialog object, which it displays as appropriate based on the fragment‘s state. Control of the dialog (deciding when to show, hide, dismiss it) should be done through the APIhere, not with direct calls on the dialog.

  • Other notes
    • Fragments are a natural evolution in the Android framework due to the diversity of devices with different screen sizes.
    • DialogFragments and Fragments are made available in the support library which makes the class usable in all current used versions of Android.

share|improve this answer

answered Jun 14 ‘13 at 23:27

user1281750
2,64421442

 
add a comment

up vote7down vote

You can create generic DialogFragment subclasses like YesNoDialog and OkDialog, and pass in title and message if you use dialogs a lot in your app.

public class YesNoDialog extends DialogFragment
{
    public YesNoDialog()
    {

    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        Bundle args = getArguments();
        String title = args.getString("title", "");
        String message = args.getString("message", "");

        return new AlertDialog.Builder(getActivity())
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, null);
                }
            })
            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_CANCELED, null);
                }
            })
            .create();
    }
}

Then call it using the following:

    DialogFragment dialog = new YesNoDialog();
    Bundle args = new Bundle();
    args.putString("title", title);
    args.putString("message", message);
    dialog.setArguments(args);
    dialog.setTargetFragment(this, YES_NO_CALL);
    dialog.show(getFragmentManager(), "tag");

And handle the result in onActivityResult.


share|improve this answer

edited Jan 9 at 22:57

answered Jan 9 at 22:51

ashishduh
1,7241512

 

    

can it work after activity being recreated (screen rotated) –  Malachiasz Jan 30 at 10:22
    

Yes, DialogFragment handles all lifecycle events for you. –  ashishduh Jan 30 at 14:45
1  

I think it doesn‘t because after rotation old Dialog still exists and it keeps assignent to old not existing fragment (dialog.setTargetFragment(this, YES_NO_CALL);) so after rotation getTargetFragment().onActivityResult doesn‘t work –  Malachiasz Jan 30 at 15:21
    

I use this code for all my dialogs and they work fine when screen is rotated. setTargetFragment uses FragmentManager methods to retain state of Fragments. –  ashishduh Jan 30 at 19:32 
    

I think that only way for it to work is to have the Fragment setRetainInstance(true) or (Activity not being destroyed). And this is unwanted in many cases. –  Malachiasz Feb 3 at 10:20

时间: 2024-07-31 20:49:25

The method dismissDialog(int) from the type Activity is deprecated的相关文章

The method setBackgroundDrawable(Drawable) from the type View is deprecated

这表示方法:setBackgroundDrawable(Drawable)已被遗弃,用setBackgroundResource(resid)替换即可,并且使用更方便 eg: button[initial_i][initial_j].setBackgroundResource(R.drawable.hero);

hibernate3和4中 HibernateSessionFactory中不同之处 The method applySettings(Map) from the type ServiceRegistryBuilder is deprecated - The type ServiceRegistryBuilder is deprecated

hibernate3和4中 HibernateSessionFactory中不同之处 //serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); 新的写法 serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProper

错误:The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arguments (int, MyFragment)

Fragment newfragment =new MyFragment();fragmentTransaction.replace(R.layout.activity_main,newfragment ).commit(); 提示错误:The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arguments (int, MyFragment) 妈蛋,找了好久!一直以

The method setPositiveButton(int, DialogInterface.OnClickListener) in the type AlertDialog.Builder is not applicable for the arguments

The method setPositiveButton(int, DialogInterface.OnClickListener) in the type AlertDialog.Builder is not applicable for the arguments (String, new   View.OnClickListener(){}) .setNegativeButton("Don't Remind", new OnClickListener() .setNegative

Mapper method 'com.autoyol.mapper.trans.AccountLogMapper.getTotalIncomByMemNoLastest attempted to return null from a method with a primitive return type (int).解决方法

1.打开日志输出,降低日志级别. <AppenderRef ref="console" level="trace"></AppenderRef> 否则看不到报错.. 2.调整mysql语句,不能使用order by limit之类的 <!-- SELECT IFNULL(amt,1) FROM account_log WHERE mem_no=#{value} AND income_type != 4 ORDER BY id DESC

The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the

 The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the arguments (int, SettingFragment, String) 今天遇到这样一个很奇葩的错误信息,后来查到我导入的包有问题  import android.app.Fragment; import android.app.FragmentManager;   其实我应该使用的

attempted to return null from a method with a primitive return type (int).

错误信息: attempted to return null from a method with a primitive return type (int). 错误原因:实际查询sql并没有这个值,出现空值,就会报这个异常. 错误sql(发生问题): select sum(id) from post where post.author = ? 正确sql(解决问题): select IFNULL(sum(id),0) from post where post.author = ? 关键在于使用

The method sendKeys(CharSequence[]) in the type WebElement is not applicable for the arguments (String)

写了一段测试代码运行时一直报错:The method sendKeys(CharSequence[]) in the type WebElement is not applicable for the arguments (String) 测试代码: driver.findElement(By.name("wd")).sendKeys("selnium"); 原因:旧版本的Java不理解非随机变量参数 解决方法:在工程上点击右键选择Build Path -> 

Access restriction: The method createJPEGEncoder(OutputStream) from the type JPEGCodec is not access

准备使用Java进行图片压缩的时候,使用 import com.sun.image.codec.jpeg.*; 结果出现错误: Access restriction: The method createJPEGEncoder(OutputStream) from the type JPEGCodec is not accessible due to restriction on required library 上网查了一下,发现是IDE的设置问题,它默认把这些受访问限制的API设成了ERROR