Android 的自定义条目呈现器中的清除按钮问题
Clear Button issue in Custom Entry Renderer for Android
我正在为条目创建自定义渲染器。我主要是想在输入字段的左侧添加一个图标。我在 Android 中使用 SetCompoundDrawablesRelativeWithIntrinsicBounds() 并在 iOS 中使用 LeftView 实现了这一点。
当 ClearButtonVisibility 设置为 "while editing" 时会出现问题。在条目中输入内容并单击清除按钮后,左侧图标与文本一起被清除(这只发生在 Android 中。在 iOS 中,只有文本被清除。我意识到内置-in clear button image is in the compound drawables so I setting the compound drawables with my icon 以及内置图标。
最好的解决方法是什么?我希望这样当点击清除按钮时,只有文本被清除而不是图标。
注意:图标会暂时清除。当触发任何其他事件时,图标 returns.
CustomEntry - before click
CustomEntry - after click
CustomEntry - after some event
Android.Renderer:
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Styles.Android.Renderers
{
public class CustomEntryRenderer : EntryRenderer
{
public CustomEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// update control UI
UpdateControl();
base.OnElementPropertyChanged(sender, e);
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
// update control UI
UpdateControl();
base.OnElementChanged(e);
}
private void UpdateControl()
{
if (Element == null || Control == null)
return;
var entry = Element as CustomEntry;
// set border/background
var gradientBackground = new GradientDrawable();
gradientBackground.SetShape(ShapeType.Rectangle);
gradientBackground.SetColor(Element.BackgroundColor.ToAndroid());
gradientBackground.SetCornerRadius(entry.CornerRadius);
gradientBackground.SetStroke(entry.BorderWidth, entry.BorderColor.ToAndroid());
Control.SetBackground(gradientBackground);
// set appropriate icon
int resID = Resources.GetIdentifier("icon_image", "drawable", this.Context.PackageName);
var drawable = ContextCompat.GetDrawable(this.Context, resID);
Control.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, Control.GetCompoundDrawables()[2], null);
Control.CompoundDrawablePadding = entry.IconPadding;
paddingLeft = entry.IconPadding;
// set padding
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop, Control.PaddingRight, Control.PaddingBottom);
}
}
}
您将覆盖 OnTouchListener
以清理文本并再次 SetCompoundDrawable
。
像下面这样更改您的自定义渲染器:
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Styles.Android.Renderers
{
public class CustomEntryRenderer : EntryRenderer
{
static Drawable drawableLeft;
static Drawable drawableRight;
public CustomEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// update control UI
UpdateControl();
base.OnElementPropertyChanged(sender, e);
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
// update control UI
UpdateControl();
base.OnElementChanged(e);
}
private void UpdateControl()
{
if (Element == null || Control == null)
return;
var entry = Element as CustomEntry;
// set border/background
var gradientBackground = new GradientDrawable();
gradientBackground.SetShape(ShapeType.Rectangle);
gradientBackground.SetColor(Element.BackgroundColor.ToAndroid());
gradientBackground.SetCornerRadius(entry.CornerRadius);
gradientBackground.SetStroke(entry.BorderWidth, entry.BorderColor.ToAndroid());
Control.SetBackground(gradientBackground);
// set appropriate icon
int resID = Resources.GetIdentifier("icon_image", "drawable", this.Context.PackageName);
drawableLeft = ContextCompat.GetDrawable(this.Context, resID);
drawableRight = Control.GetCompoundDrawables()[2];
Control.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight , null);
Control.CompoundDrawablePadding = entry.IconPadding;
paddingLeft = entry.IconPadding;
// set padding
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop, Control.PaddingRight, Control.PaddingBottom);
Control.SetOnTouchListener(new OnDrawableTouchListener());
}
public class OnDrawableTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
{
public bool OnTouch(Android.Views.View v, MotionEvent e)
{
if (v is EditText && e.Action == MotionEventActions.Up)
{
EditText editText = (EditText)v;
editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight, null);
if (drawableRight != null)
{
bool touchable = e.GetX() > (editText.Width
- editText.PaddingRight - drawableRight.IntrinsicWidth)
&& (e.GetX() < ((editText.Width - editText.PaddingRight)));
if (touchable)
{
Console.WriteLine(editText.Text);
editText.Text = "";
editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight, null);
return true;
}
}
}
return false;
}
}
}
}
我正在为条目创建自定义渲染器。我主要是想在输入字段的左侧添加一个图标。我在 Android 中使用 SetCompoundDrawablesRelativeWithIntrinsicBounds() 并在 iOS 中使用 LeftView 实现了这一点。
当 ClearButtonVisibility 设置为 "while editing" 时会出现问题。在条目中输入内容并单击清除按钮后,左侧图标与文本一起被清除(这只发生在 Android 中。在 iOS 中,只有文本被清除。我意识到内置-in clear button image is in the compound drawables so I setting the compound drawables with my icon 以及内置图标。
最好的解决方法是什么?我希望这样当点击清除按钮时,只有文本被清除而不是图标。
注意:图标会暂时清除。当触发任何其他事件时,图标 returns.
CustomEntry - before click
CustomEntry - after click
CustomEntry - after some event
Android.Renderer:
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Styles.Android.Renderers
{
public class CustomEntryRenderer : EntryRenderer
{
public CustomEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// update control UI
UpdateControl();
base.OnElementPropertyChanged(sender, e);
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
// update control UI
UpdateControl();
base.OnElementChanged(e);
}
private void UpdateControl()
{
if (Element == null || Control == null)
return;
var entry = Element as CustomEntry;
// set border/background
var gradientBackground = new GradientDrawable();
gradientBackground.SetShape(ShapeType.Rectangle);
gradientBackground.SetColor(Element.BackgroundColor.ToAndroid());
gradientBackground.SetCornerRadius(entry.CornerRadius);
gradientBackground.SetStroke(entry.BorderWidth, entry.BorderColor.ToAndroid());
Control.SetBackground(gradientBackground);
// set appropriate icon
int resID = Resources.GetIdentifier("icon_image", "drawable", this.Context.PackageName);
var drawable = ContextCompat.GetDrawable(this.Context, resID);
Control.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, Control.GetCompoundDrawables()[2], null);
Control.CompoundDrawablePadding = entry.IconPadding;
paddingLeft = entry.IconPadding;
// set padding
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop, Control.PaddingRight, Control.PaddingBottom);
}
}
}
您将覆盖 OnTouchListener
以清理文本并再次 SetCompoundDrawable
。
像下面这样更改您的自定义渲染器:
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Styles.Android.Renderers
{
public class CustomEntryRenderer : EntryRenderer
{
static Drawable drawableLeft;
static Drawable drawableRight;
public CustomEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// update control UI
UpdateControl();
base.OnElementPropertyChanged(sender, e);
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
// update control UI
UpdateControl();
base.OnElementChanged(e);
}
private void UpdateControl()
{
if (Element == null || Control == null)
return;
var entry = Element as CustomEntry;
// set border/background
var gradientBackground = new GradientDrawable();
gradientBackground.SetShape(ShapeType.Rectangle);
gradientBackground.SetColor(Element.BackgroundColor.ToAndroid());
gradientBackground.SetCornerRadius(entry.CornerRadius);
gradientBackground.SetStroke(entry.BorderWidth, entry.BorderColor.ToAndroid());
Control.SetBackground(gradientBackground);
// set appropriate icon
int resID = Resources.GetIdentifier("icon_image", "drawable", this.Context.PackageName);
drawableLeft = ContextCompat.GetDrawable(this.Context, resID);
drawableRight = Control.GetCompoundDrawables()[2];
Control.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight , null);
Control.CompoundDrawablePadding = entry.IconPadding;
paddingLeft = entry.IconPadding;
// set padding
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop, Control.PaddingRight, Control.PaddingBottom);
Control.SetOnTouchListener(new OnDrawableTouchListener());
}
public class OnDrawableTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
{
public bool OnTouch(Android.Views.View v, MotionEvent e)
{
if (v is EditText && e.Action == MotionEventActions.Up)
{
EditText editText = (EditText)v;
editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight, null);
if (drawableRight != null)
{
bool touchable = e.GetX() > (editText.Width
- editText.PaddingRight - drawableRight.IntrinsicWidth)
&& (e.GetX() < ((editText.Width - editText.PaddingRight)));
if (touchable)
{
Console.WriteLine(editText.Text);
editText.Text = "";
editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight, null);
return true;
}
}
}
return false;
}
}
}
}