Xamarin Android Editext wrapped text - android

I have a multine edittet control and need to get the text of this control with a carriage return. The problem is that i do not know where the text is wrapped.
Is ther a possibility to get the text formatted as seen in the control?
Or is there a OnWrapped event so that i can append then the /r/n on my own?
Thank you!

I found a dirty possibility which does nearly what I need
public sealed class CustomEditText : EditText
{
private int _prevLineCounter = 1;
public static bool DelIsPressed { get; set; }
private CustomEditText(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public CustomEditText(Context context) : base(context)
{
BeforeTextChanged += CustomEditText_BeforeTextChanged;
SetOnKeyListener(new KeyListner());
}
private void CustomEditText_BeforeTextChanged(object sender, TextChangedEventArgs e)
{
// not loaded yet
if (LineCount == 0)
return;
if (DelIsPressed)
{
DelIsPressed = false;
return;
}
// text got wrapped
if (_prevLineCounter < LineCount)
{
_prevLineCounter = LineCount;
// find last space an enter carriage return
int spaceIndex = Text.LastIndexOf(' ');
// just one long string
if (spaceIndex == -1)
spaceIndex = Text.Length - 2;
Text = Text.Insert(spaceIndex, "\r\n");
// set cursor to the end
SetSelection(Text.Length);
}
_prevLineCounter = LineCount;
}
public CustomEditText(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public CustomEditText(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs,
defStyleAttr)
{
}
public CustomEditText(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context,
attrs, defStyleAttr, defStyleRes)
{
}
}
public class KeyListner: Java.Lang.Object, View.IOnKeyListener
{
public bool OnKey(View v, Keycode keyCode, KeyEvent e)
{
CustomEditText.DelIsPressed = e.KeyCode == Keycode.Del;
return false;
}
}

Related

EditText has focus change event fired infinitely when changing compound drawable in focus listener

I have a custom edittext control which has a clear (x) icon set on the right when it's in focus and has text. Clicking the clear icon removes the text from the textbox. Unfortunately, when you click into the textbox, the focus change event is fired infinitely, as changing the compound drawable within the focus change listener seems to fire off two more focus change events, the first with the focus off, and the second with the focus back on. Any idea how I can get this working without the infinite loop?
Here is the code:
public class CustomEditText : EditText {
private Drawable clearButton;
protected CustomEditText (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {
}
public CustomEditText (Context context) : base (context) {
Init ();
}
public CustomEditText (Context context, IAttributeSet attrs) : base (context, attrs) {
Init (attrs);
}
public CustomEditText (Context context, IAttributeSet attrs, int defStyle) : base (context, attrs, defStyle) {
Init (attrs);
}
protected void Init (IAttributeSet attrs = null) {
// Set up clear button
SetupClearButton ();
SetupEvents ();
}
private void SetupClearButton () {
clearButton = ContextCompat.GetDrawable (Android.App.Application.Context, Resource.Drawable.forms_edit_text_clear_gray);
clearButton.SetBounds (0, 0, clearButton.IntrinsicWidth, clearButton.IntrinsicHeight);
}
private void SetupEvents () {
// Handle clear button visibility
this.TextChanged += (sender, e) => {
if (this.HasFocus)
UpdateClearButton ();
};
this.FocusChange += (object sender, FocusChangeEventArgs e) => {
UpdateClearButton (e.HasFocus);// Gets called infinitely
};
// Handle clearing the text
this.Touch += (sender, e) => {
if (this.GetCompoundDrawables ()[2] != null &&
e.Event.Action == MotionEventActions.Up &&
e.Event.GetX () > (this.Width - this.PaddingRight - clearButton.IntrinsicWidth)) {
this.Text = "";
UpdateClearButton ();
e.Handled = true;
} else
e.Handled = false;
};
}
private void UpdateClearButton (bool hasFocus = true) {
var compoundDrawables = this.GetCompoundDrawables ();
var compoundDrawable = this.Text.Length == 0 || !hasFocus ? null : clearButton;
if (compoundDrawables[2] != compoundDrawable)
this.SetCompoundDrawables (compoundDrawables[0], compoundDrawables[1], compoundDrawable, compoundDrawables[3]);
}
}
I ported DroidParts' ClearableEditText to Xamarin.Android to use when using the Android's Support Library widgets were not appropriate.
Note: DroidParts is under Apache 2.0 license so I can not post my C# derivative in full to StackOverflow, but the key to avoiding the continuous focus changing is in the OnTouch and OnFocusChange methods and the fact that the listeners are added to the base EditText Widget.
Full Code # https://gist.github.com/sushihangover/01a7965aae75d8ef0589697aa8f0e750
public bool OnTouch(View v, MotionEvent e)
{
if (GetDisplayedDrawable() != null)
{
int x = (int)e.GetX();
int y = (int)e.GetY();
int left = (loc == Location.LEFT) ? 0 : Width - PaddingRight - xD.IntrinsicWidth;
int right = (loc == Location.LEFT) ? PaddingLeft + xD.IntrinsicWidth : Width;
bool tappedX = x >= left && x <= right && y >= 0 && y <= (Bottom - Top);
if (tappedX)
{
if (e.Action == MotionEventActions.Up)
{
Text = "";
if (listener != null)
{
listener.DidClearText();
}
}
return true;
}
}
if (l != null)
return l.OnTouch(v, e);
return false;
}
public void OnFocusChange(View v, bool hasFocus)
{
if (hasFocus)
SetClearIconVisible(!string.IsNullOrEmpty(Text));
else
SetClearIconVisible(false);
if (f != null)
f.OnFocusChange(v, hasFocus);
}
Original StackOverflow Q/A: How to create EditText with cross(x) button at end of it?
In my opinion, the easiest implementation I have is this :
public class ClearableEditext : EditText
{
Context mContext;
Drawable imgX;
public ClearableEditext(Context context) : base(context)
{
init(context, null);
}
public ClearableEditext(Context context, Android.Util.IAttributeSet attrs) : base(context, attrs)
{
init(context, attrs);
}
public ClearableEditext(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
init(context, attrs);
}
public ClearableEditext(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
{
init(context, attrs);
}
public void init(Context ctx, Android.Util.IAttributeSet attrs)
{
mContext = ctx;
imgX = ContextCompat.GetDrawable(ctx, Android.Resource.Drawable.PresenceOffline);
imgX.SetBounds(0, 0, imgX.IntrinsicWidth, imgX.IntrinsicHeight);
manageClearButton();
this.SetOnTouchListener(new TouchHelper(this, imgX));
this.AddTextChangedListener(new TextListener(this));
}
public void manageClearButton()
{
if (this.Text.ToString().Equals(""))
removeClearButton();
else
addClearButton();
}
public void addClearButton()
{
this.SetCompoundDrawables(this.GetCompoundDrawables()[0],
this.GetCompoundDrawables()[1],
imgX,
this.GetCompoundDrawables()[3]);
}
public void removeClearButton()
{
this.SetCompoundDrawables(this.GetCompoundDrawables()[0],
this.GetCompoundDrawables()[1],
null,
this.GetCompoundDrawables()[3]);
}
}
public class TouchHelper : Java.Lang.Object, View.IOnTouchListener
{
ClearableEditext Editext;
public ClearableEditext objClearable { get; set; }
Drawable imgX;
public TouchHelper(ClearableEditext editext, Drawable imgx)
{
Editext = editext;
objClearable = objClearable;
imgX = imgx;
}
public bool OnTouch(View v, MotionEvent e)
{
ClearableEditext et = Editext;
if (et.GetCompoundDrawables()[2] == null)
return false;
// Only do this for up touches
if (e.Action != MotionEventActions.Up)
return false;
// Is touch on our clear button?
if (e.GetX() > et.Width - et.PaddingRight - imgX.IntrinsicWidth)
{
Editext.Text = string.Empty;
if (objClearable != null)
objClearable.removeClearButton();
}
return false;
}
}
public class TextListener : Java.Lang.Object, ITextWatcher
{
public ClearableEditext objClearable { get; set; }
public TextListener(ClearableEditext objRef)
{
objClearable = objRef;
}
public void AfterTextChanged(IEditable s)
{
}
public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
{
}
public void OnTextChanged(ICharSequence s, int start, int before, int count)
{
if (objClearable != null)
objClearable.manageClearButton();
}
}
Probably Sushi has a better answer but i would suggest you to try this one out.
To change the x icon as your custom one change the image in init()

ClearableEdittext for xamarin android

I have visited this link and many other links on the stack but I'm unable to find a similar solution for xamarin android :
https://stackoverflow.com/a/14470930/7462031
I have implemented the frame layout solution but I want this solution throughout my application So the Clearable Edittext Looked interesting but the droid parts library is not available for xamarin so I am wondering if anyone has a solution for this problem in case you do kindly Help.!
I achieved it by doing the following it might not be the best solution but I guess it is the only solution for Xamarin.Android available for this:
public class ClearableEditext : EditText
{
Context mContext;
Drawable imgX;
public ClearableEditext(Context context) : base(context)
{
init(context, null);
}
public ClearableEditext(Context context, Android.Util.IAttributeSet attrs) : base(context, attrs)
{
init(context, attrs);
}
public ClearableEditext(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
init(context, attrs);
}
public ClearableEditext(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
{
init(context, attrs);
}
public void init(Context ctx, Android.Util.IAttributeSet attrs)
{
mContext = ctx;
imgX = ContextCompat.GetDrawable(ctx, Android.Resource.Drawable.PresenceOffline);
imgX.SetBounds(0, 0, imgX.IntrinsicWidth, imgX.IntrinsicHeight);
manageClearButton();
this.SetOnTouchListener(new TouchHelper(this, imgX));
this.AddTextChangedListener(new TextListener(this));
}
public void manageClearButton()
{
if (this.Text.ToString().Equals(""))
removeClearButton();
else
addClearButton();
}
public void addClearButton()
{
this.SetCompoundDrawables(this.GetCompoundDrawables()[0],
this.GetCompoundDrawables()[1],
imgX,
this.GetCompoundDrawables()[3]);
}
public void removeClearButton()
{
this.SetCompoundDrawables(this.GetCompoundDrawables()[0],
this.GetCompoundDrawables()[1],
null,
this.GetCompoundDrawables()[3]);
}
}
public class TouchHelper : Java.Lang.Object, View.IOnTouchListener
{
ClearableEditext Editext;
public ClearableEditext objClearable { get; set; }
Drawable imgX;
public TouchHelper(ClearableEditext editext, Drawable imgx)
{
Editext = editext;
objClearable = objClearable;
imgX = imgx;
}
public bool OnTouch(View v, MotionEvent e)
{
ClearableEditext et = Editext;
if (et.GetCompoundDrawables()[2] == null)
return false;
// Only do this for up touches
if (e.Action != MotionEventActions.Up)
return false;
// Is touch on our clear button?
if (e.GetX() > et.Width - et.PaddingRight - imgX.IntrinsicWidth)
{
Editext.Text = string.Empty;
if (objClearable != null)
objClearable.removeClearButton();
}
return false;
}
}
public class TextListener : Java.Lang.Object, ITextWatcher
{
public ClearableEditext objClearable { get; set; }
public TextListener(ClearableEditext objRef)
{
objClearable = objRef;
}
public void AfterTextChanged(IEditable s)
{
}
public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
{
}
public void OnTextChanged(ICharSequence s, int start, int before, int count)
{
if (objClearable != null)
objClearable.manageClearButton();
}
}
To change the x icon as your custom one change the image in init()

Android custom control with translate animation

I'm pretty new in the android world.
I try to create in my app a custom control like the following description:
- Objects appears one by one (timer) at the right of that custom controls and are translated (with animation) to the left of the screen.
The rendering is the following right now:
And the code is like:
public abstract class SheetBase : SurfaceView
{
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
this.Update(canvas);
}
}
public class MusicSheet : SheetBase, ISurfaceHolderCallback
{
public MusicSheet(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public MusicSheet(Context context) : base(context)
{
}
public MusicSheet(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public MusicSheet(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
}
public MusicSheet(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
{
}
protected override void Update(Canvas canvas)
{
// Logic to draw staf on Canvas
}
public void SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
{
this.Invalidate();
}
public void SurfaceCreated(ISurfaceHolder holder)
{
this._thread = new Thread(this.Loop);
this._thread.Start();
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
this._thread?.Abort();
}
private void Loop()
{
while (true)
{
Canvas c = null;
try
{
c = this.Holder.LockCanvas();
c.DrawColor(Color.Transparent, PorterDuff.Mode.Clear);
// Draw content at the new position
}
finally
{
if (c != null)
this.Holder.UnlockCanvasAndPost(c);
}
Thread.Sleep(10);
}
}
}
What do you think about the solution / performances ?
You can use ViewPropertyAnimator to translate a View.
For example,
view.animate()
.translationX(100) // horizontal translation
.translationY(100) // vertical translation
To animate from right to left:
view.animate()
.translationX( - screenWidth )
Refer the doc for more info.

Detect end of fling on ScrollView

I've overridden ScrollView to pass MotionEvents to a GestureDetector to detect fling events on the ScrollView. I need to be able to detect when the scrolling stops. This doesn't coincide with the MotionEvent.ACTION_UP event because this usually happens at the start of a fling gesture, which is followed by a flurry of onScrollChanged() calls on the ScrollView.
So basically what we are dealing with here is the following events:
onFling
onScrollChanged, onScrollChanged, onScrollChanged, ... , onScrollChanged
There's no callback for when the onScrollChanged events are done firing. I was thinking of posting a message to the event queue using a Handler during onFling and waiting for the Runnable to execute to signal the end of the fling, unfortunately it fires after the first onScrollChanged call.
Any other ideas?
I've combined a few of the answers from here to construct a working listener that resembles the way AbsListView does it. It's essentially what you describe, and it works well in my testing.
Note: you can simply override ScrollView.fling(int velocityY) rather than use your own GestureDetector.
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
public class CustomScrollView extends ScrollView {
private static final int DELAY_MILLIS = 100;
public interface OnFlingListener {
public void onFlingStarted();
public void onFlingStopped();
}
private OnFlingListener mFlingListener;
private Runnable mScrollChecker;
private int mPreviousPosition;
public CustomScrollView(Context context) {
this(context, null, 0);
}
public CustomScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScrollChecker = new Runnable() {
#Override
public void run() {
int position = getScrollY();
if (mPreviousPosition - position == 0) {
mFlingListener.onFlingStopped();
removeCallbacks(mScrollChecker);
} else {
mPreviousPosition = getScrollY();
postDelayed(mScrollChecker, DELAY_MILLIS);
}
}
};
}
#Override
public void fling(int velocityY) {
super.fling(velocityY);
if (mFlingListener != null) {
mFlingListener.onFlingStarted();
post(mScrollChecker);
}
}
public OnFlingListener getOnFlingListener() {
return mFlingListener;
}
public void setOnFlingListener(OnFlingListener mOnFlingListener) {
this.mFlingListener = mOnFlingListener;
}
}
Thank you #PaulBurke +1
Xamarin Solution
using Android.Content;
using Android.Runtime;
using Android.Util;
using Android.Widget;
using System;
public class CustomScrollView : ScrollView
{
public event EventHandler FlingEnded;
public event EventHandler FlingStarted;
private Action ScrollChecker;
private int PreviousPosition;
private const int DELAY_MILLIS = 100;
public CustomScrollView(Context context) : base(context) => Init();
public CustomScrollView(Context context, IAttributeSet attrs) : base(context, attrs) => Init();
public CustomScrollView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) => Init();
public CustomScrollView(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes) => Init();
public CustomScrollView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { }
private void Init()
{
ScrollChecker = () =>
{
int position = ScrollY;
if (PreviousPosition - position == 0)
{
FlingEnded?.Invoke(this, new EventArgs());
RemoveCallbacks(ScrollChecker);
}
else
{
PreviousPosition = ScrollY;
PostDelayed(ScrollChecker, DELAY_MILLIS);
}
};
}
public override void Fling(int velocityY)
{
base.Fling(velocityY);
FlingStarted?.Invoke(this, new EventArgs());
Post(ScrollChecker);
}
}
Usage:
myCustomScrollView.FlingEnded += myCustomScrollView_FlingEnded;
protected void myCustomScrollView_FlingEnded(object sender, EventArgs e) =>
{
//Do onFlingEnded code here
};

Android Edittext with Button how to put action on the button

i just read this How can I add an image on EditText and want to know if it is possible to add action on the icon when clicked...
yes it's possible just create CustomEediTtext extends from EditText. check this solution
Create a customized EditText class CustomEditText.java:
public class CustomEditText extends EditText {
private Drawable dRight;
private Rect rBounds;
public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomEditText(Context context) {
super(context);
}
#Override
public void setCompoundDrawables(Drawable left, Drawable top,
Drawable right, Drawable bottom) {
if(right !=null)
{
dRight = right;
}
super.setCompoundDrawables(left, top, right, bottom);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP && dRight!=null) {
rBounds = dRight.getBounds();
final int x = (int)event.getX();
final int y = (int)event.getY();
if(x>=(this.getRight()-rBounds.width()) && x<=(this.getRight()-
this.getPaddingRight()) && y>=this.getPaddingTop() && y<=(this.getHeight()-
this.getPaddingBottom())) {
//System.out.println("touch");
this.setText("");
event.setAction(MotionEvent.ACTION_CANCEL);//use this to prevent the keyboard
}
}
return super.onTouchEvent(event);
}
#Override
protected void finalize() throws Throwable {
dRight = null;
rBounds = null;
super.finalize();
}
}

Categories

Resources