如何在不实例化活动中每个实例的情况下处理子类视图事件?

发布于 2024-12-21 11:29:16 字数 4041 浏览 2 评论 0原文

在我的第一个 MonoDroid 应用程序中,我对 TextView 进行了子类化,以便可以在每个视图周围显示边框( Android - 在 TextView 上显示边框文本的方法? ),设法将其添加到我的布局 XML ( 使用 XML 声明自定义 Android UI 元素 ),并解决 NullReferenceExceptions由于 MonoDroid 对 Android 命名空间的小写化( 从子类创建自定义 Android UI 元素时避免 NullReferenceException文本视图)。

在此处输入图像描述

我现在要做的是处理每个 BorderedTextView 中的触摸事件。

我知道我可以使用 FindViewById<> 获取每个视图并创建一个委托来处理每个视图的 Click 事件。

BorderedTextView currentDate = FindViewById<BorderedTextView>(Resource.Id.currentdate);
currentDate.Click += delegate {
    Toast toast = Toast.MakeText(this, "CURRENT DATE tapped", ToastLength.Long);
    toast.Show();
}

BorderedTextView startTime = FindViewById<BorderedTextView>(Resource.Id.starttime);
startTime.Click += delegate {
    Toast toast = Toast.MakeText(this, "START TIME tapped", ToastLength.Long);
    toast.Show ();
};

在此处输入图像描述 在此处输入图像描述

更进一步,我可以在 BorderedTextView 中创建一个通用方法来处理点击(但我仍然必须实例化每个 BorderedTextView)。

// In Activity's OnCreate
BorderedTextView currentDate = FindViewById<BorderedTextView>(Resource.Id.currentdate);
currentDate.Click += delegate {
    BorderedTextView.HandleClicks(this);
}

BorderedTextView startTime = FindViewById<BorderedTextView>(Resource.Id.starttime);
startTime.Click += delegate {
    BorderedTextView.HandleClicks(this);
};

// In BorderedTextView
public static void HandleClicks(Context context)
{
    Toast toast = Toast.MakeText(context, "BorderedTextView tapped", ToastLength.Long);
    toast.Show();
}

由于 BorderedTextView 的数量会有所不同,并且我想处理单击事件,而不必在活动的 OnCreate 中实例化每个视图。我想我可以在布局 XML 文件中使用 android:clickable 和 android:onClick 属性做一些事情。

<mbta.BorderedTextView
    android:id="@+id/currentdate"
    android:text="CURRENT DATE"
    android:textSize="15pt"
    android:layout_width="fill_parent"
    android:layout_height="75dp"
    android:gravity="center_horizontal|center_vertical"
    android:layout_weight="1"
    android:clickable="true"
    android:onClick="HandleClicks"/>

但事实证明 MonoDroid 不支持以这种方式注册事件( ​​Mono Droid onClick 事件不发现)。

我目前已经尝试使用 SetOnClickListener 和视图的 OnTouchEvent 事件,但没有成功(使用 Xamarin 的 API 设计 页面)。

我想要的是一种使用 BorderedTextView 类中的单个方法来处理每个 BorderedTextView 单击事件的方法,而无需在 Activity 的 OnCreate 中实例化每个视图。这在 MonoDroid 中可能吗?或者我只是想做一些该工具目前不支持的事情。

提前致谢。

更新 - 12.16.11

jpobst 关于在 BorderedTextView 的构造函数中连接事件处理程序的建议有效。

public BorderedTextView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
    this.Click += delegate {
        HandleClicks (context);
    };

    this.Tag = this.Text;
}

public BorderedTextView(Context context, IAttributeSet attrs) : base(context, attrs)
{
    this.Click += delegate {
        HandleClicks (context);
    };

    this.Tag = this.Text;
}

public BorderedTextView(Context context) : base(context)
{
    this.Click += delegate {
        HandleClicks(context);
    };

    this.Tag = this.Text;
}

这是处理点击的实际方法

public static void HandleClicks(Context context)
{
    string typeName = ((Type)this.GetType()).Name;
    stirng selected = "Selected " + (string)this.Tag + " (" + typeName + ")";

    Toast.MakeText(context, selected, ToastLength.Short).Show();
}

In my first MonoDroid app I've subclassed TextView so I can display a border around each view ( Android - Way to appear bordered text on the TextView? ), managed to add it to my layout XML ( Declaring a custom android UI element using XML ), and get around NullReferenceExceptions due to MonoDroid's lowercasing of Android namespaces ( Avoiding a NullReferenceException when creating a custom Android UI element from subclassed TextView ).

enter image description here

What I'm trying to do now is handle touch events in each BorderedTextView.

I know I can get each view using FindViewById<> and create a delegate to handle each view's Click event.

BorderedTextView currentDate = FindViewById<BorderedTextView>(Resource.Id.currentdate);
currentDate.Click += delegate {
    Toast toast = Toast.MakeText(this, "CURRENT DATE tapped", ToastLength.Long);
    toast.Show();
}

BorderedTextView startTime = FindViewById<BorderedTextView>(Resource.Id.starttime);
startTime.Click += delegate {
    Toast toast = Toast.MakeText(this, "START TIME tapped", ToastLength.Long);
    toast.Show ();
};

enter image description here enter image description here

Taking that one step further, I can create a common method in BorderedTextView to handle clicks (but I still have to instantiate each BorderedTextView).

// In Activity's OnCreate
BorderedTextView currentDate = FindViewById<BorderedTextView>(Resource.Id.currentdate);
currentDate.Click += delegate {
    BorderedTextView.HandleClicks(this);
}

BorderedTextView startTime = FindViewById<BorderedTextView>(Resource.Id.starttime);
startTime.Click += delegate {
    BorderedTextView.HandleClicks(this);
};

// In BorderedTextView
public static void HandleClicks(Context context)
{
    Toast toast = Toast.MakeText(context, "BorderedTextView tapped", ToastLength.Long);
    toast.Show();
}

Since the number of BorderedTextViews is going to vary and I'd like to handle the click events without having to instantiate each view in the activity's OnCreate. I thought I could do something in the layout XML file with the android:clickable and android:onClick attributes.

<mbta.BorderedTextView
    android:id="@+id/currentdate"
    android:text="CURRENT DATE"
    android:textSize="15pt"
    android:layout_width="fill_parent"
    android:layout_height="75dp"
    android:gravity="center_horizontal|center_vertical"
    android:layout_weight="1"
    android:clickable="true"
    android:onClick="HandleClicks"/>

But it turns out MonoDroid doesn't support registering events in this way ( Mono Droid onClick event not found ).

I've currently experimented with SetOnClickListener and the view's OnTouchEvent event without success (using info from the Events and Listeners section on Xamarin's API Design page).

What I'd like is a way to handle every BorderedTextView click event with a single method in the BorderedTextView class without having to instantiate each view in the Activity's OnCreate. Is this possible in MonoDroid or am I simply trying to do something that the tool won't support at this time.

Thanks in advance.

Update - 12.16.11

jpobst's suggestion to hook up event handlers in BorderedTextView's constructors worked.

public BorderedTextView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
    this.Click += delegate {
        HandleClicks (context);
    };

    this.Tag = this.Text;
}

public BorderedTextView(Context context, IAttributeSet attrs) : base(context, attrs)
{
    this.Click += delegate {
        HandleClicks (context);
    };

    this.Tag = this.Text;
}

public BorderedTextView(Context context) : base(context)
{
    this.Click += delegate {
        HandleClicks(context);
    };

    this.Tag = this.Text;
}

And here's the actual method to handle the click

public static void HandleClicks(Context context)
{
    string typeName = ((Type)this.GetType()).Name;
    stirng selected = "Selected " + (string)this.Tag + " (" + typeName + ")";

    Toast.MakeText(context, selected, ToastLength.Short).Show();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦境 2024-12-28 11:29:16

您不能在 BorderedTextView 构造函数中连接事件处理程序吗?

Can't you just hook up your event handler in the BorderedTextView constructor?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文