适用于Android的Xamarin / Mono - 自定义标题视图时AlertDialog崩溃

时间:2013-03-09 00:22:09

标签: android xamarin.android alertdialog xamarin

我想自定义警告对话框标题背景和应用程序崩溃而不显示警告对话框。 (自定义视图仅填充消息区域,不包括标题面板和按钮面板。我想自定义默认的标题面板和按钮面板。这里我以标题为例。)

public static class MyAlertDialog
{
    private static AlertDialog _alertDialog;

    public static void Show(Context context)
    {
        var factory = LayoutInflater.From(context);
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context)
            .SetTitle("myTitle")
            .SetView(factory.Inflate(Resource.Layout.DialogRegister, null))
            .SetCancelable(true);

        _alertDialog = alertDialogBuilder.Create();
        var titleView = (TextView)_alertDialog.FindViewById(Android.Resource.Id.Title); //get title view from the Android resource not from my custom view
        //titleView.SetBackgroundResource(Resource.Color.PrimaryColor);
        titleView.SetBackgroundColor(Android.Graphics.Color.Red); 
        _alertDialog.Show();  

    }
}

我从主要的活动中调用对话框:

[Activity(Label = "My Activity", MainLauncher = true)]
public class HomeActivity : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        SetContentView(Resource.Layout.home);

        Button btnMyButton = FindViewById<Button>(Resource.Id.MyButton);
        btnMyButton.Click += (object sender, EventArgs e) =>
        {
            MyAlertDialog.Show(this);
        };

        ......
     }
 }

VS抛出运行时异常并要求我中断或继续。我点击继续。然后应用程序崩溃。日志:

03-09 11:10:47.057 E/mono    ( 1185): [0x4001f730:] EXCEPTION handling: Android.Util.AndroidRuntimeException: Exception of type 'Android.Util.AndroidRuntimeException' was thrown.
03-09 11:10:49.956 I/Email   (  451): ReconcilePopImapAccountsSync: start
03-09 11:10:50.276 I/Email   (  451): ReconcilePopImapAccountsSync: done
03-09 11:11:07.417 E/mono    ( 1185): [0x4001f730:] EXCEPTION handling: Java.Lang.NullPointerException: Exception of type 'Java.Lang.NullPointerException' was thrown.
03-09 11:11:07.727 E/mono    ( 1185): [0x4001f730:] EXCEPTION handling: Java.Lang.NullPointerException: Exception of type 'Java.Lang.NullPointerException' was thrown.
03-09 11:11:16.846 F/        ( 1185): * Assertion: should not be reached at /Users/builder/data/lanes/monodroid-lion-bigsplash/0e0e51f9/source/mono/mono/mini/debugger-agent.c:5980
03-09 11:11:16.846 I/mono    ( 1185): Stacktrace:
03-09 11:11:16.846 I/mono    ( 1185): 
03-09 11:11:16.866 E/mono    ( 1185): [0x2a118c70:] EXCEPTION handling: System.NullReferenceException: Object reference not set to an instance of an object
03-09 11:11:16.906 E/mono    ( 1185): 
03-09 11:11:16.906 E/mono    ( 1185): Unhandled Exception:
03-09 11:11:16.906 E/mono    ( 1185): System.NullReferenceException: Object reference not set to an instance of an object
03-09 11:11:16.937 I/mono    ( 1185): [ERROR] FATAL UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object

我在Android 4.1.2 armeabi-v7a的模拟器中测试它。 (该项目旨在支持架构armeabi,armeabi-v7a和x86。)

感谢您的帮助。 (我知道我可以在自定义内容视图中添加带有消息的标题。但我也想自定义其他部分。所以我只以标题为例。)

我注意到虽然我是SetTitle(“myTitle”),但titleView.text是一个空字符串。通过

获取默认标题视图时出错了吗?
var titleView = (TextView)_alertDialog.FindViewById(Android.Resource.Id.Title);

同样,我的自定义视图不包含标题视图。

3 个答案:

答案 0 :(得分:3)

您的代码很乱,可能存在多个问题,但我认为这一行是您的问题

txView.SetBackgroundResource(Resource.Color.PrimaryColor);

正如您在文档中看到here一样,您只应将对Drawable的引用作为参数传递给Color

您需要使用此方法here,如下所示: txView.SetBackgroundColor(Resource.Color.PrimaryColor);

此问题中的代码也无法编译,txView变量来自哪里?我假设它的意思是titleView?

另一件事;每次运行项目时都会显示您发布的日志条目,您可以忽略它。有关详细信息,请参阅here。您应该发布的实际日志条目将会更晚(并且之后单击Visual Studio中的继续)

答案 1 :(得分:1)

您需要告诉哪个视图可以找到ID。所以在获取view后实例化factory

var view = factory.Inflate(Resource.Layout.DialogRegister, null);

因为titleView将引用null,所以会导致崩溃,

然后,您可以使用刚创建的title找到view。需要指出的一点是,Android.Resource在Mono for Android中引用了Android框架的资源,Resource实际上是对你的布局,ID等的引用。所以,代码就像:

var titleView = view.FindViewById<TextView>(Resource.Id.title);

SetBackgroundResource只能将drawable作为有效参数,因此在这种情况下颜色不起作用。但是SetBackgroundColor会有效,因为Android.Graphics.Color.RedColor对象。

此外,您可以在构建对话框时SetView(view)

答案 2 :(得分:0)

我只会使用对话框。您重写OnCreateDialog方法。在那里,您可以设置内容视图并根据需要设置自定义标题。您还可以自定义对话框。这是一些示例代码,有一个SetTitle方法。这是一个简短的例子,可以在代码下面的链接找到更多。

此代码显示如何连接按钮单击以显示对话框。单击按钮后,将调用OnCreateDialog,系统将显示您的对话框。

const int NewGame = 1;
protected override Dialog OnCreateDialog(int id)
    {
        switch (id)
        {
            case NewGame:
                Dialog d = new Dialog(this);// Create the new dialog
                d.SetTitle("New Game");//Set the title.
                d.SetContentView(Resource.Layout.ActNewGame);//Set the layout resource.
                //here you can use d.FindViewById<T>(Resource)
             return d;
        }
        return null;
    }

}

// wire up a button click in the OnCreate method.
btnNewGame.Click += (o, e) =>
        {

                ShowDialog(NewGame);
        };

http://xandroid4net.blogspot.com/2014/09/xamarinandroid-ways-to-customize-dialogs.html