Sur*_*gch 18 android rotation android-edittext mongolian-vertical-script
我想创建一个旋转和翻转的EditText视图,该视图具有普通EditText视图的所有属性.
我已经成功地(在SO用户的帮助下)创建了一个自定义的EditText视图,该视图既可以旋转也可以翻转.这是通过重写onDraw方法完成的.但是,光标和突出显示消失,longtouch事件仍指示原始文本位置.基本上,视图被重绘,但触摸事件不是.
如何旋转和翻转触摸事件,突出显示和光标?
带选择的EditText比例(类似的问题,但不完全相同.)
如何制作一个自定义的Edittext,以便它看起来像在Android中旋转45度(@CommonsWare注意到一个解决方案,需要通过触摸事件完成添加工作.那是什么工作?)
http://developer.android.com/training/graphics/opengl/touch.html(有帮助,但我不明白如何在这种情况下应用它.)
我创建了一个扩展EditText的自定义视图.在其中覆盖onDraw方法以旋转和翻转画布.我重写onMeasure以使视图具有适合布局的尺寸.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
布局xml没有什么特别之处.
(更新)这个问题是另一种尝试,但最终我无法使它工作:除了onDraw()之外还需要覆盖invalidateDrawable()吗?
如果你想知道为什么在世界上我想旋转和翻转EditText视图,这就是原因.传统的蒙古语是从左到右垂直写的.结合垂直镜像蒙古字体,顺时针旋转文本90度并翻转它产生可读输出和正确的换行.
这不是一个模糊或孤立的问题.有数百万传统蒙古语用户,但很少有Android应用程序.其中,我还没有发现任何开源软件.如果我可以使用它,我想让其他开发人员可以使用该代码.
我正在考虑View从头开始创建一个自定义视图(扩展)来创建像TextView.这TextView可以从应用程序更新,就像一个EditText视图.在这种情况下,我只需要用正常字体旋转文本90度但不要翻转它.但是,我必须做自己的换行.
但是,在阅读@Chitrang的回答后,我想我可以通过扩展TextView来做类似的事情.然后我可以避免做自己换行的麻烦.
图片更新

蒙古语是从上到下,从左到右书写的.现在我正在使用此键盘在文本周围移动光标,但我希望能够触摸屏幕将光标移动到某个位置.
我最终从头开始开发了一个垂直脚本MongolEditText。它可以作为mongol-library。
这里它与两个不同的第三方键盘一起使用。
这仍然是一项正在进行的工作,所以我不会将其标记为已解决,但让我发布到目前为止的内容。它完成了我想做的大部分事情。基本上,我使用 TextView 而不是 EditText,因为 EditText 在旋转时会做很多奇怪的事情。
我有一个不闪烁的光标,可以响应触摸事件,但仍然不支持突出显示。这是代码:
public class MongolTextView extends TextView {
private TextPaint textPaint;
private Paint cursorPaint = new Paint();
private boolean mCursorIsVisible;
private CursorTouchLocationListener listener;
// Naming is based on pre-rotated/mirrored values
private float mCursorBaseY;
private float mCursorBottomY;
private float mCursorAscentY; // This is a negative number
private float mCursorX;
private static final float CURSOR_THICKNESS = 2f;
// Constructors
public MongolTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MongolTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MongolTextView(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/ChimeeWhiteMirrored.ttf");
//setTypeface(tf);
// Use the above commented code is using a single font in another application
Typeface tf = FontCache.get(SettingsActivity.FONT_DEFAULT, getContext());
if(tf != null) {
setTypeface(tf);
}
this.mCursorIsVisible = true;
cursorPaint.setStrokeWidth(CURSOR_THICKNESS);
cursorPaint.setColor(Color.BLACK); // TODO should be same as text color
}
// This interface may be deleted if touch functionality is not needed
public interface CursorTouchLocationListener {
/**
* Returns the touch location to be used for the cursor so you can update the insert
* location in a text string.
*
* @param glyphIndex
* You will need to translate glyphIndex into a Unicode index if you are using a
* Unicode string.
*/
public void onCursorTouchLocationChanged(int glyphIndex);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// swap the height and width
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
@Override
protected void onDraw(Canvas canvas) {
textPaint = getPaint();
textPaint.setColor(getCurrentTextColor());
textPaint.drawableState = getDrawableState();
canvas.save();
// flip and rotate the canvas
canvas.translate(getWidth(), 0);
canvas.rotate(90);
canvas.translate(0, getWidth());
canvas.scale(1, -1);
canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
// draw the cursor
if (mCursorIsVisible) {
canvas.drawLine(mCursorX, mCursorBottomY, mCursorX, mCursorBaseY + mCursorAscentY,
cursorPaint);
}
getLayout().draw(canvas);
canvas.restore();
}
public void showCursor(boolean visible) {
mCursorIsVisible = visible;
this.invalidate();
// TODO make the cursor blink
}
public void setCursorColor(int color) {
cursorPaint.setColor(color);
}
public void setCursorLocation(int characterOffset) {
Layout layout = this.getLayout();
if (layout!=null){
try {
// This method is giving a lot of crashes so just surrounding with
// try catch for now
int line = layout.getLineForOffset(characterOffset);
mCursorX = layout.getPrimaryHorizontal(characterOffset);
mCursorBaseY = layout.getLineBaseline(line);
mCursorBottomY = layout.getLineBottom(line);
mCursorAscentY = layout.getLineAscent(line);
this.invalidate();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class InputWindowTouchListener implements OnTouchListener {
@Override
public boolean onTouch(View view, MotionEvent event) {
Layout layout = ((TextView) view).getLayout();
// swapping x and y for touch events
int y = (int) event.getX();
int x = (int) event.getY();
if (layout != null) {
int line = layout.getLineForVertical(y);
int offset = layout.getOffsetForHorizontal(line, x);
mCursorX = layout.getPrimaryHorizontal(offset);
mCursorBaseY = layout.getLineBaseline(line);
mCursorBottomY = layout.getLineBottom(line);
mCursorAscentY = layout.getLineAscent(line);
//mCursorHeightY = layout.getLineTop(line);
view.invalidate();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//handler.postDelayed(mLongPressed, 1000);
listener.onCursorTouchLocationChanged(offset);
break;
case MotionEvent.ACTION_UP:
//handler.removeCallbacks(mLongPressed);
// notify the host activity of the new cursor location
break;
}
}
return false;
}
}
public void setCursorTouchLocationListener(CursorTouchLocationListener listener) {
this.listener = listener;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有更好的东西,请随意添加您自己的答案,或者如果您需要添加一些内容来改进此问题(添加突出显示、让光标闪烁等),请发表评论。该代码的最新版本应该位于github上。
| 归档时间: |
|
| 查看次数: |
2439 次 |
| 最近记录: |