Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom rotated EditText view with working selection, cursor location, etc

What I want to do

I want to make a rotated and flipped EditText view that has all of the properties of a normal EditText view.

My problem

I have successfully made (with much help from SO users) a custom EditText view that is both rotated and flipped. This was done by overriding the onDraw method. However, the cursor and highlighting are gone and a longtouch event still indicates the original text position. Basically, the view was redrawn but the touch events were not.

How do I get the touch events, highlighting, and cursor to also be rotated and flipped?

What I have read

EditText scale with selection (A similar problem but not quite the same.)

How to make a custom Edittext,so that it will look like as 45 degree rotated in android (@CommonsWare noted for one solution that addition work would need to be done with touch events. What is that work?)

http://developer.android.com/training/graphics/opengl/touch.html (Helpful, but I don't understand how to apply it in this situation.)

What I have tried

I made a custom view that extends EditText. In it overrode the onDraw method to rotate and flip the canvas. I overrode onMeasure to make the view have the right dimensions for the layout.

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.EditText;

public class MongolEditText extends EditText {

// Constructors
public MongolEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}
public MongolEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}
public MongolEditText(Context context) {
    super(context);
    init();
}

// This class requires the mirrored Mongolian font to be in the assets/fonts folder
private void init() {
    Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
            "fonts/MongolChagaanMirrored.ttf");
    setTypeface(tf);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(heightMeasureSpec, widthMeasureSpec);
    setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}

@Override
protected void onDraw(Canvas canvas) {
    TextPaint textPaint = getPaint();
    textPaint.setColor(getCurrentTextColor());
    textPaint.drawableState = getDrawableState();

    canvas.save();

    canvas.translate(getWidth(), 0);
    canvas.rotate(90);
    canvas.translate(0, getWidth());
    canvas.scale(1, -1);

    canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());

    getLayout().draw(canvas);
    canvas.restore();
}
}

There is nothing special for the layout xml.

(Update) This question is another attempt at it but in the end I couldn't get it to work: Does invalidateDrawable() need to be overridden in addition to onDraw()?

Further explanation

In case you are wondering why in the world I want to rotate and flip an EditText view, here is the reason. Traditional Mongolian is written vertically in left to right columns. In combination with a vertically mirrored Mongolian font, rotating the text 90 degrees clockwise and flipping it produces readable output with correct line wrapping.

This is not an obscure or isolated problem. There are millions of users of traditional Mongolian but very few Android apps. Of these, I haven't found any that are open source. If I can get this to work, I want to make the code available to other developers.

Where I am looking now

(update)

I was thinking about creating a custom view (that extends View) from scratch to create something like a TextView. This TextView could be updated from apps to act like an EditText view. In this case I would only need to rotate the text 90 degrees with a normal font but not flip it. However, I would have to do my own line wrapping.

However, after reading @Chitrang's answer I think I can do something similar by just extending a TextView. Then I can avoid the trouble of doing my own line wrapping.

Picture Update

enter image description here

Mongolian is written from top to bottom and left to right. Right now I am using this key pad to move a cursor around the text, but I would like to be able to touch the screen to move the cursor to a position.

like image 997
Suragch Avatar asked Jul 30 '14 12:07

Suragch


2 Answers

Tried to get the partial solution with minor changes, check if that's you want.

1) Set android:gravity="top|left" in your edittext declaration inside xml.

2) Noticed that without super method call inside onDraw method, not able to show cursor. So I called,

super.onDraw(canvas);

instead,

getLayout().draw(canvas);

3) For touch events, I tried to swap x and y coordinates. So that you can have cursor as per touch event.(Just tried and it was working, got lucky :) )

@Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub
    event.setLocation(event.getY(), event.getX());
    return super.onTouchEvent(event);
}

Comment this line inside onDraw method, for exact touch event(Found by trial and error).

canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());

4) I could not do any thing about highlighting or selecting text.

?) Another Solution : If you think that, some how you get RTL language support work on edittext then you just need to rotate it. But unfortunately its not working properly with android. Reference : How to handle RTL languages on pre 4.2 versions of Android? and Android setting with TextView for Hebrew text?

like image 85
Chitrang Avatar answered Nov 15 '22 03:11

Chitrang


An attribute is there for the EditText for rotation . It is is simple and also easy to use.It might help you I think.

<EditText
    android:id="@+id/editTextNumber"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:rotation="90"
    android:layout_marginBottom="10dp"
    android:hint="Enter Mobile Number"
    android:textAppearance="?android:attr/textAppearanceLarge" />
like image 35
Akash Avatar answered Nov 15 '22 04:11

Akash