I am trying to select all text when double tapping on an EditText (not on the text itself but on the white space outside the text) by creating a GestureDetector and listener and in onDoubleTap perform the selecteAll.
Unfortunately, just after all text gets selected, the text gets de-selected.
How can I select all text when double tap on the EditText white space?
Thanks!
Custom EditText:
public class TextEditText : EditText, View.IOnTouchListener
{
GestureDetector gestureDetector;
public TextEditText(Context context) : base(context)
{
Init();
}
public TextEditText(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Init();
}
public TextEditText(Context context, IAttributeSet attrs, int defStyle) :
base(context, attrs, defStyle)
{
Init();
}
public TextEditText(IntPtr a, Android.Runtime.JniHandleOwnership b) : base(a, b)
{
Init();
}
void Init()
{
gestureDetector = new GestureDetector(new SelectTextDoubleTapListener(this));
SetOnTouchListener(this);
}
public bool OnTouch(View v, MotionEvent e)
{
return gestureDetector.OnTouchEvent(e);
}
}
then the listener:
public class SelectTextDoubleTapListener : GestureDetector.SimpleOnGestureListener
{
EditText editText;
public SelectTextDoubleTapListener(EditText et)
{
editText = et;
}
public override bool OnDoubleTap(MotionEvent e)
{
if (editText.Text.Length > 0)
{
editText.SetSelection(editText.Text.Length);
editText.SelectAll();
}
return false; // return true does not work either
}
}
Unfortunately, just after all text gets selected, the text gets de-selected.
I solve this by use SetSelectAllOnFocus(true) in the OnDoubleTap
For example:
public override bool OnDoubleTap(MotionEvent e)
{
if (editText.Text.Length > 0)
{
editText.SetSelectAllOnFocus(true);
editText.ClearFocus();
}
return true;
}
Related
I created this custom view extended from AppCompatEditText :
public class NoteEditText extends AppCompatEditText {
// INTERFACES ----------------------------------------------------------------------------------------------------
public interface OnKeyPreImeListener {
void onKeyPreIme(int keyCode, KeyEvent event);
}
// ATTRIBUTES ----------------------------------------------------------------------------------------------------
private MovementMethod movementMethod;
private KeyListener keyListener;
private OnKeyPreImeListener onKeyPreImeListener;
// CONSTRUCTORS ----------------------------------------------------------------------------------------------------
public NoteEditText(Context context) {
super(context);
this.movementMethod = this.getMovementMethod();
this.keyListener = this.getKeyListener();
}
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.movementMethod = this.getMovementMethod();
this.keyListener = this.getKeyListener();
}
public NoteEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.movementMethod = this.getMovementMethod();
this.keyListener = this.getKeyListener();
}
// SETTERS ----------------------------------------------------------------------------------------------------
public void setOnKeyPreImeListener(OnKeyPreImeListener onKeyPreImeListener) {
this.onKeyPreImeListener = onKeyPreImeListener;
}
// METHODS ----------------------------------------------------------------------------------------------------
public void enable() {
this.setMovementMethod(this.movementMethod);
this.setKeyListener(this.keyListener);
this.setFocusableInTouchMode(true);
this.setImeOptions(EditorInfo.IME_ACTION_DONE);
this.setRawInputType(InputType.TYPE_CLASS_TEXT);
}
public void disable() {
this.setMovementMethod(null);
this.setKeyListener(null);
}
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (this.onKeyPreImeListener != null)
this.onKeyPreImeListener.onKeyPreIme(keyCode, event);
return true;
}
}
I call it like this :
<com.company.adapters.items.NoteEditText
android:id="#+id/note"
style="#style/AppTheme.SubItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/content_margin_xs"
android:gravity="center_vertical"
android:hint=""
android:imeOptions="actionDone"
android:inputType="textMultiLine|textCapSentences|textNoSuggestions"
android:minHeight="#dimen/content_subitem_height"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/note_icon"
app:layout_constraintTop_toBottomOf="#+id/name" />
It works well, except the "textMultiLine|textCapSentences|textNoSuggestions" inputTypes. Neither "textCapSentences" nor "textNoSuggestions" are applied, although "textMultiLine" is working.
If I use the exact same configuration but with the original EditText view, all the inputTypes work... very strange.
this.setRawInputType(InputType.TYPE_CLASS_TEXT);
From your enable function. This is overriding the input type.
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()
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()
I want to disable recyclerview scrolling in landscape mode and enable it in the portrait mode.
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
// Stop only scrolling.
return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
}
});
I am using this method to disable scrolling but can't find a way to enable it again.
Thanks for any help!
You have to get it done using a custom RecyclerView. Initialize it programmatically when the user is in landscape mode and add this view to your layout:
public class MyRecycler extends RecyclerView {
private boolean verticleScrollingEnabled = true;
public void enableVersticleScroll (boolean enabled) {
verticleScrollingEnabled = enabled;
}
public boolean isVerticleScrollingEnabled() {
return verticleScrollingEnabled;
}
#Override
public int computeVerticalScrollRange() {
if (isVerticleScrollingEnabled())
return super.computeVerticalScrollRange();
return 0;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if(isVerticleScrollingEnabled())
return super.onInterceptTouchEvent(e);
return false;
}
public MyRecycler(Context context) {
super(context);
}
public MyRecycler(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecycler(Context context, #Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
For portrait mode keep using your normal RecyclerView.
For this issue, I use this one line solution! :)
myRecyclerView.isNestedScrollingEnabled = false
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();
}
}