Xamarin Forms:支持内联标签的自定义条目
Xamarin Forms: custom entry with inline tag support
我正在尝试构建一个 XF 应用程序,它允许用户输入文本并标记地点列表(类似于您在 WhatsApp、Outlook 应用程序甚至 Twitter 的标签上标记某人的方式)。我仍然从 XF 开始。谁能指出我正确的方向?我发现最多的是 TagEntryView 插件,它很棒,但我需要能够在线标记“地点”。
示例:
我想明天见@Paris
,@Chennai。
我想提供一些关于我们自己用 XF 创建这样的控件的想法,而不是直接使用第三方库。 (顺便说一句,我不知道有什么第三方库支持这个功能。)
正如我们常说的那样:实现一个 Custom Renderers 以使用来自 PCL 的目标平台的本机控件。
所以这里根据您的要求,我们可以尝试定制一个Entry
。
在 PCL 中创建我们这样的条目:
public class TagEntry : Entry
{
}
然后,对于 Android 平台:
[assembly: ExportRenderer(typeof(TagEntry), typeof(TagEntryRenderer))]
namespace YourNameSpace.Droid
{
public class TagEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
Control.AfterTextChanged += Control_AfterTextChanged;
if (e.OldElement != null)
Control.AfterTextChanged -= Control_AfterTextChanged;
}
private void Control_AfterTextChanged(object sender, AfterTextChangedEventArgs e)
{
//detect if '@' is entered.
if (e.Editable.LastOrDefault() == '@')
{
//show a popup list for selection.
//I here use a simple menu for testing, you should be able to change it to your list popup.
PopupMenu popup = new PopupMenu(Xamarin.Forms.Forms.Context, Control);
popup.MenuInflater.Inflate(Resource.Menu.testmenu, popup.Menu);
popup.Show();
popup.MenuItemClick += (ss, ee) =>
{
var item = ee.Item.TitleFormatted;
e.Editable.Delete(e.Editable.Length() - 1, e.Editable.Length());
SpannableString spannable = new SpannableString("@" + item);
spannable.SetSpan(new ForegroundColorSpan(Android.Graphics.Color.Blue), 0, item.Length() + 1, SpanTypes.ExclusiveExclusive);
e.Editable.Append(spannable);
popup.Dismiss();
};
}
}
}
}
渲染图像:
订阅原生控件的TextChanged
事件是个思路,如果你也对UWP平台上的实现感兴趣,类似的,可以试试。对于 iOS 平台?抱歉,我也不熟...
我正在尝试构建一个 XF 应用程序,它允许用户输入文本并标记地点列表(类似于您在 WhatsApp、Outlook 应用程序甚至 Twitter 的标签上标记某人的方式)。我仍然从 XF 开始。谁能指出我正确的方向?我发现最多的是 TagEntryView 插件,它很棒,但我需要能够在线标记“地点”。
示例:
我想明天见@Paris
,@Chennai。
我想提供一些关于我们自己用 XF 创建这样的控件的想法,而不是直接使用第三方库。 (顺便说一句,我不知道有什么第三方库支持这个功能。)
正如我们常说的那样:实现一个 Custom Renderers 以使用来自 PCL 的目标平台的本机控件。
所以这里根据您的要求,我们可以尝试定制一个Entry
。
在 PCL 中创建我们这样的条目:
public class TagEntry : Entry
{
}
然后,对于 Android 平台:
[assembly: ExportRenderer(typeof(TagEntry), typeof(TagEntryRenderer))]
namespace YourNameSpace.Droid
{
public class TagEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
Control.AfterTextChanged += Control_AfterTextChanged;
if (e.OldElement != null)
Control.AfterTextChanged -= Control_AfterTextChanged;
}
private void Control_AfterTextChanged(object sender, AfterTextChangedEventArgs e)
{
//detect if '@' is entered.
if (e.Editable.LastOrDefault() == '@')
{
//show a popup list for selection.
//I here use a simple menu for testing, you should be able to change it to your list popup.
PopupMenu popup = new PopupMenu(Xamarin.Forms.Forms.Context, Control);
popup.MenuInflater.Inflate(Resource.Menu.testmenu, popup.Menu);
popup.Show();
popup.MenuItemClick += (ss, ee) =>
{
var item = ee.Item.TitleFormatted;
e.Editable.Delete(e.Editable.Length() - 1, e.Editable.Length());
SpannableString spannable = new SpannableString("@" + item);
spannable.SetSpan(new ForegroundColorSpan(Android.Graphics.Color.Blue), 0, item.Length() + 1, SpanTypes.ExclusiveExclusive);
e.Editable.Append(spannable);
popup.Dismiss();
};
}
}
}
}
渲染图像:
订阅原生控件的TextChanged
事件是个思路,如果你也对UWP平台上的实现感兴趣,类似的,可以试试。对于 iOS 平台?抱歉,我也不熟...