androidgetx
A. android中,不是用系統控制項,只使用event.getX();,event.getY();,怎麼實現文本跟隨手指上下或者左右移動
不短的根據event.getX();,event.getY(),來setLayoutparamter,也就是你自定義的文本的控制項的位置 或者 直接draw文本
B. 安卓裡面getTranslationX()和getX的區別,最好能詳細解析下這坐標的問題
先看Android官方相關API的介紹,在分析這兩個區別的時候先理解一下getLeft()函數。
getLeft():當前View相對於Parent的左邊距(單位為像素)
getTranslationX();當前View相對它左邊距的水平位置(單位為像素)
getX():當前View在X軸向的位置(單位為像素),而且getX() = getTranslationX() + getLeft()
通常我們設置好布局後,getTranslationX的值是0,所以大部分時候getX的值是等於getLeft的值的。但是getTranslationX是後布局式的,我們有時會根據情況來設定View發生變化,如Animation的設定或者認為設置TranslationX的值,但那個公式是不會變化的。
C. android view移動後為什麼getx不變
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.animdemo2.MainActivity" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="110px"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="70px"<--ImageView距其父容器左邊距離為70px--/>
android:src="@drawable/ic_launcher" />
</LinearLayout>
</RelativeLayout>
D. Android getXVelocity()可以為負嗎,即方向分右嗎
getXVelocity ()、 getYVelocity ()獲取速度。
通過ACTION_DOWN和ACTION_UP後坐標的差值來辨別方向。
E. 在android中,對於file中存儲的point(x,y),如何把point (x,y)提取到畫布上,,並使各坐標點用線連接起來
public void onDraw() {
Canvas canvas = mSurfaceHolder.lockCanvas();
canvas.drawColor(Color.WHITE);
if (mSurfaceHolder == null || canvas == null) {
return;
}
/*Paint xPaint = new Paint();
xPaint.setAntiAlias(true);
xPaint.setColor(Color.BLACK);
canvas.drawLine((screenWidth/2) ,0 , (screenWidth/2) , screenHeight , xPaint);
canvas.drawLine(0 ,(screenHeight/2) , screenWidth , (screenHeight/2) , xPaint);*/
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLUE);
for(int i = 0;i < path1.size() ;i++)
{
Node p = (Node) path1.get(i);
if(0 == i)
canvas.drawCircle(p.getx()*10, p.gety()*10, 2, mPaint);
else
{
Node p2 = (Node) path1.get(i-1);
canvas.drawCircle((screenWidth/2)-p.getx(), (screenHeight/2)-p.gety(), 2, mPaint);
//canvas.drawLine((screenWidth/2)-p2.getx(), (screenHeight/2)-p2.gety(), (screenWidth/2)-p.getx(), (screenHeight/2)-p.gety() ,mPaint);
}
}
}
首先是聲明一個Canvas 畫布,然後調用DrawLine()函數就可以了。DrawLine()函數三個參數,第一個參數是起點,第二個是終點,第三個是顏色值。。。網上demo,自己可以去找找。
F. Android如何較為精確獲取到當前移動速度
android.view.VelocityTracker主要用跟蹤觸摸屏事件(flinging事件和其他gestures手勢事件)的速率。用addMovement(MotionEvent)函數將Motion event加入到VelocityTracker類實例中.你可以使用getXVelocity() 或getXVelocity()獲得橫向和豎向的速率到速率時,但是使用它們之前請先調用computeCurrentVelocity(int)來初始化速率的單位 。
主要函數
Public Methods
void addMovement(MotionEvent event)
Add a user's movement to the tracker.
void clear()
Reset the velocity tracker back to its initial state.
void computeCurrentVelocity(int units, float maxVelocity)
Compute the current velocity based on the points that have been collected.
int unitis表示速率的基本時間單位。unitis值為1的表示是,一毫秒時間單位內運動了多少個像素, unitis值為1000表示一秒(1000毫秒)時間單位內運動了多少個像素
floatVelocity表示速率的最大值
void computeCurrentVelocity(int units)
Equivalent to invoking computeCurrentVelocity(int, float) with a maximum velocity of Float.MAX_VALUE.
abstract T getNextPoolable()
float getXVelocity()
Retrieve the last computed X velocity.
float getXVelocity(int id)
Retrieve the last computed X velocity.
float getYVelocity(int id)
Retrieve the last computed Y velocity.
float getYVelocity()
Retrieve the last computed Y velocity.
abstract boolean isPooled()
static VelocityTracker obtain()
Retrieve a new VelocityTracker object to watch the velocity of a motion.
void recycle()
Return a VelocityTracker object back to be re-used by others.
abstract void setNextPoolable(T element)
abstract void setPooled(boolean isPooled)
示例:
private VelocityTracker mVelocityTracker;//生命變數
//在onTouchEvent(MotionEvent ev)中
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();//獲得VelocityTracker類實例
}
mVelocityTracker.addMovement(ev);//將事件加入到VelocityTracker類實例中
//判斷當ev事件是MotionEvent.ACTION_UP時:計算速率
final VelocityTracker velocityTracker = mVelocityTracker;
// 1000 provides pixels per second
velocityTracker.computeCurrentVelocity(1, (float)0.01); //設置maxVelocity值為0.1時,速率大於0.01時,顯示的速率都是0.01,速率小於0.01時,顯示正常
Log.i("test","velocityTraker"+velocityTracker.getXVelocity());
velocityTracker.computeCurrentVelocity(1000); //設置units的值為1000,意思為一秒時間內運動了多少個像素
Log.i("test","velocityTraker"+velocityTracker.getXVelocity());
大體的使用是這樣的:
當你需要跟蹤觸摸屏事件的速度的時候,使用obtain()方法來獲得VelocityTracker類的一個實例對象
在onTouchEvent回調函數中,使用addMovement(MotionEvent)函數將當前的移動事件傳遞給VelocityTracker對象
使用computeCurrentVelocity (int units)函數來計算當前的速度,使用 getXVelocity ()、 getYVelocity ()函數來獲得當前的速度
G. android開發中如何實現手寫輸入的記事本
實現手寫功能的主要步驟:
1. 自定義兩個View,一個是TouchView,用於在上面畫圖,另一個是EditText,用於將手寫的字顯示在其中,並且,要將兩個自定義View通過FrameLayout幀式布局重疊在起,以實現全屏手寫的功能。
2 在TouchView中實現寫字,並截取畫布中的字以Bitmap保存。
3. 設置定時器,利用handle更新界面。
下面是實現的細節:
1. 手寫的界面設計:
如上圖所示,和上節的畫板界面一致,底部分選項菜單欄,有5個選項,分別是調整畫筆大小,畫筆顏色,撤銷,恢復,以及清空,對於這些功能,之後幾節再實現。
布局文件activity_handwrite.xml
<!--?xml version=1.0 encoding=utf-8?-->
<relativelayout android:background="@android:color/white" android:layout_height="match_parent" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"><imageview android:layout_above="@+id/paintBottomMenu" android:layout_height="wrap_content" android:layout_width="match_parent" android:src="@drawable/line">
</imageview></relativelayout>
可以看出,裡面有兩個自定義view,並且通過FrameLayout重疊在一起。
先來看com.example.notes.LineEditText,這個其實和添加記事中的界面一樣,就是自定義EditText,並且在字的下面畫一條線。
LineEditText.java
public class LineEditText extends EditText {
private Rect mRect;
private Paint mPaint;
public LineEditText(Context context, AttributeSet attrs) {
// TODO Auto-generated constructor stub
super(context,attrs);
mRect = new Rect();
mPaint = new Paint();
mPaint.setColor(Color.GRAY);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//得到EditText的總行數
int lineCount = getLineCount();
Rect r = mRect;
Paint p = mPaint;
//為每一行設置格式
for(int i = 0; i < lineCount;i++){
//取得每一行的基準Y坐標,並將每一行的界限值寫到r中
int baseline = getLineBounds(i, r);
//設置每一行的文字帶下劃線
canvas.drawLine(r.left, baseline+20, r.right, baseline+20, p);
}
}
}
另一個就是com.example.notes.TouchView,實現了繪制,及定時更新界面的功能,具體看代碼
TouchView.java
public class TouchView extends View {
private Bitmap mBitmap,myBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private Paint mPaint;
private Handler bitmapHandler;
GetCutBitmapLocation getCutBitmapLocation;
private Timer timer;
DisplayMetrics dm;
private int w,h;
public TouchView(Context context) {
super(context);
dm = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
w = dm.widthPixels;
h = dm.heightPixels;
initPaint();
}
public TouchView(Context context, AttributeSet attrs) {
super(context,attrs);
dm = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
w = dm.widthPixels;
h = dm.heightPixels;
initPaint();
}
//設置handler
public void setHandler(Handler mBitmapHandler){
bitmapHandler = mBitmapHandler;
}
//初始化畫筆,畫布
private void initPaint(){
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF00FF00);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(15);
getCutBitmapLocation = new GetCutBitmapLocation();
//畫布大小
mBitmap = Bitmap.createBitmap(w, h,
Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap); //所有mCanvas畫的東西都被保存在了mBitmap中
mCanvas.drawColor(Color.TRANSPARENT);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
timer = new Timer(true);
}
/**
* 處理屏幕顯示
*/
Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
myBitmap = getCutBitmap(mBitmap);
Message message = new Message();
message.what=1;
Bundle bundle = new Bundle();;
bundle.putParcelable(bitmap,myBitmap);
message.setData(bundle);
bitmapHandler.sendMessage(message);
RefershBitmap();
break;
}
super.handleMessage(msg);
}
};
/**
* 發送消息給handler更新ACTIVITY
*/
TimerTask task = new TimerTask() {
public void run() {
Message message = new Message();
message.what=1;
Log.i(線程, 來了);
handler.sendMessage(message);
}
};
//切割畫布中的字並返回
public Bitmap getCutBitmap(Bitmap mBitmap){
//得到手寫字的四周位置,並向外延伸10px
float cutLeft = getCutBitmapLocation.getCutLeft() - 10;
float cutTop = getCutBitmapLocation.getCutTop() - 10;
float cutRight = getCutBitmapLocation.getCutRight() + 10;
float cutBottom = getCutBitmapLocation.getCutBottom() + 10;
cutLeft = (0 > cutLeft ? 0 : cutLeft);
cutTop = (0 > cutTop ? 0 : cutTop);
cutRight = (mBitmap.getWidth() < cutRight ? mBitmap.getWidth() : cutRight);
cutBottom = (mBitmap.getHeight() < cutBottom ? mBitmap.getHeight() : cutBottom);
//取得手寫的的高度和寬度
float cutWidth = cutRight - cutLeft;
float cutHeight = cutBottom - cutTop;
Bitmap cutBitmap = Bitmap.createBitmap(mBitmap, (int)cutLeft, (int)cutTop, (int)cutWidth, (int)cutHeight);
if (myBitmap!=null ) {
myBitmap.recycle();
myBitmap= null;
}
return cutBitmap;
}
//刷新畫布
private void RefershBitmap(){
initPaint();
invalidate();
if(task != null)
task.cancel();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); //顯示舊的畫布
canvas.drawPath(mPath, mPaint); //畫最後的path
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
//手按下時
private void touch_start(float x, float y) {
mPath.reset();//清空path
mPath.moveTo(x, y);
mX = x;
mY = y;
if(task != null)
task.cancel();//取消之前的任務
task = new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what=1;
Log.i(線程, 來了);
handler.sendMessage(message);
}
};
getCutBitmapLocation.setCutLeftAndRight(mX,mY);
}
//手移動時
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, x, y);
// mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);//源代碼是這樣寫的,可是我沒有弄明白,為什麼要這樣?
mX = x;
mY = y;
if(task != null)
task.cancel();//取消之前的任務
task = new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what=1;
Log.i(線程, 來了);
handler.sendMessage(message);
}
};
getCutBitmapLocation.setCutLeftAndRight(mX,mY);
}
}
//手抬起時
private void touch_up() {
//mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
if (timer!=null) {
if (task!=null) {
task.cancel();
task = new TimerTask() {
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
timer.schele(task, 1000, 1000); //2200秒後發送消息給handler更新Activity
}
}else {
timer = new Timer(true);
timer.schele(task, 1000, 1000); //2200秒後發送消息給handler更新Activity
}
}
//處理界面事件
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate(); //刷新
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
這裡面的難點就是利用TimerTask和Handle來更新界面顯示,需要在onTouchEvent的三個事件中都要通過handle發送消息來更新顯示界面。
接下來就是在activity里通過handle來得到繪制的字,並添加在editText中。
關於配置底部菜單,以及頂部標題欄,這里不再贅述,直接如何將繪制的字得到,並添加在edittext中:
得到繪制字體的Bitmap
//處理界面
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle = new Bundle();
bundle = msg.getData();
Bitmap myBitmap = bundle.getParcelable(bitmap);
InsertToEditText(myBitmap);
}
};
其中myBitmap就是取得的手寫字,保存在Bitmap中, InsertToEditText(myBitmap);是將該圖片添加在edittext中,具體如下:
?
1
private LineEditText et_handwrite;
?
1
et_handwrite = (LineEditText)findViewById(R.id.et_handwrite);
//將手寫字插入到EditText中
private void InsertToEditText(Bitmap mBitmap){
int imgWidth = mBitmap.getWidth();
int imgHeight = mBitmap.getHeight();
//縮放比例
float scaleW = (float) (80f/imgWidth);
float scaleH = (float) (100f/imgHeight);
Matrix mx = new Matrix();
//對原圖片進行縮放
mx.postScale(scaleW, scaleH);
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, imgWidth, imgHeight, mx, true);
//將手寫的字插入到edittext中
SpannableString ss = new SpannableString(1);
ImageSpan span = new ImageSpan(mBitmap, ImageSpan.ALIGN_BOTTOM);
ss.setSpan(span, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
et_handwrite.append(ss);
}
H. android怎麼獲取bitmap左上角坐標
用ImageView來裝載這個bitmap並且填滿整個ImageView,再用imageview對象來獲取坐標值,getX(),getY(),獲取的就是左上角的坐標值
I. android MotionEvent中getX和getRawX的區別
androd中識別觸碰的點時,getX和getRawX的區別如下圖:
getRowX:觸摸點相對於屏幕的坐標
getX: 觸摸點相對於按鈕的坐標
getTop: 按鈕左上角相對於父view(LinerLayout)的y坐標
getLeft: 按鈕左上角相對於父view(LinerLayout)的x坐標
可以推斷: getRight()等同於下面的計算:getLeft()+getWidth()。
getX()是表示Widget相對於自身左上角的x坐標,而getRawX()是表示相對於屏幕左上角的x坐標值(注意:這個屏幕左上角是手機屏幕左上角,不管activity是否有titleBar或是否全屏幕),getY(),getRawY()一樣的道理