Android如何創(chuàng)建可拖動的圖片控件
本文實例為大家分享了Android創(chuàng)建可拖動圖片控件的具體代碼,供大家參考,具體內(nèi)容如下
重載、自繪
1、從View派生一個控件類 ,構(gòu)造函數(shù)中調(diào)用父類構(gòu)造器。
2、重載其onDraw函數(shù),在里面繪制圖片。(和windows的MFC有種似曾相識的感覺,可能安卓借鑒了windows的模式吧)
消息處理
拖動圖片的消息,主要是處理按下和移動兩個消息,重載onTouchEvent。數(shù)學知識(平移):在ACTION_DOWN時記錄下坐標點,在ACTION_MOVE時根據(jù)當前位置與按下時的位置算出平移量。刷新控件,導致控件重繪,重繪時移動繪制的左上角坐標即可。
剛開始時,只是收到了ACTION_DOWN消息,ACTION_MOVE消息就是捕捉不到,上網(wǎng)搜了下,原來是我在onTouchEvent最后調(diào)用了父類函數(shù)return super.onTouchEvent(event);父類里面返回false表示對這些消息不予關(guān)注,后續(xù)的ACTION_MOVE和ACTION_UP就不會進來了。
代碼和配置
activity的XML配置
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.example.timertest.DragImageView android:id="@+id/div" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
控件的自繪代碼
package com.example.timertest; import java.util.ArrayList; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; @SuppressLint("ClickableViewAccessibility") public class DragImageView extends View{ private Bitmap bmp = null; private PointF orgPos = new PointF(0, 0); private PointF downPos = new PointF(0, 0); private PointF movePos = new PointF(0, 0); private boolean bMove = false; private int nDstWidth = 0; private int nDstHeight = 0; private Rect rcSrc = new Rect(0, 0 , 0, 0); private RectF rcDst = new RectF(0, 0, 0, 0); private Paint paint = null; public DragImageView(Context context) { super(context); // TODO Auto-generated constructor stub paint = new Paint(Paint.ANTI_ALIAS_FLAG); //setOnClickListener(new DivOnClickListener()); //setOnTouchListener(l); } public DragImageView(Context context, AttributeSet attrs) { super(context, attrs); //bmp = img; paint = new Paint(Paint.ANTI_ALIAS_FLAG); } public DragImageView(Context context, AttributeSet attrs, int defStyleAttr){ super(context, attrs, defStyleAttr); paint = new Paint(Paint.ANTI_ALIAS_FLAG); } public void SetImage(Bitmap img){ if ( bmp != null ){ bmp = null; } bmp = img; } @Override public void addTouchables(ArrayList<View> views) { // TODO Auto-generated method stub super.addTouchables(views); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub float fPosX = event.getX(); float fPosY = event.getY(); int nAct = event.getAction(); switch ( nAct ){ case MotionEvent.ACTION_MOVE:{ if ( !bMove ) bMove = true; movePos.x = fPosX - downPos.x; movePos.y = fPosY - downPos.y; downPos.x = fPosX; downPos.y = fPosY; invalidate(); } break; case MotionEvent.ACTION_DOWN:{ downPos.x = fPosX; downPos.y = fPosY; } break; case MotionEvent.ACTION_UP: break; } //一定要返回ture,如果返回父類方法即false,則后續(xù)的move up 消息都不會觸發(fā)。 return true; //return super.onTouchEvent(event); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); if ( bmp == null ) return ; int nWidth = bmp.getWidth(); int nHeight = bmp.getHeight(); if ( !bMove ){ orgPos = GetCenterPos(); } else{ orgPos.x += movePos.x; orgPos.y += movePos.y; } rcSrc.right = nWidth; rcSrc.bottom = nHeight; rcDst.left = orgPos.x; rcDst.top = orgPos.y; rcDst.right = orgPos.x+nDstWidth; rcDst.bottom = orgPos.y+nDstHeight; canvas.drawBitmap(bmp, rcSrc, rcDst, paint); } protected PointF GetCenterPos(){ PointF pt = new PointF(0, 0); if ( bmp == null ) return pt; WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE); //wm.getDefaultDisplay().getSize(pt); int nScrWidth = wm.getDefaultDisplay().getWidth(); @SuppressWarnings("deprecation") int nScrHeight = wm.getDefaultDisplay().getHeight(); int nWidth = bmp.getWidth(); int nHeight = bmp.getHeight(); float fImgRate = nWidth/(float)nHeight; float fScrRate = nScrWidth/(float)nScrHeight; if ( nWidth>nScrWidth && nHeight>nScrHeight ){ if ( fImgRate > fScrRate ){ nDstWidth = nScrWidth; nDstHeight = (int)(nScrWidth/fImgRate); } else{ nDstHeight = nScrHeight; nDstWidth= (int)(nScrHeight*fImgRate); } } else if ( nWidth>nScrWidth ){ nDstWidth = nScrWidth; nDstHeight = nHeight; } else if ( nHeight>nScrHeight ){ nDstWidth = nWidth; nDstHeight = nScrHeight; } else{ nDstWidth = nWidth; nDstHeight = nHeight; } pt.y = (nScrHeight-nDstHeight)/2.0f; pt.x = (nScrWidth-nDstWidth)/2.0f; return pt; } }
其中GetCenterPos函數(shù)是根據(jù)圖片尺寸計算適合屏幕居中的方法。
運行程序
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- android Matrix實現(xiàn)圖片隨意放大縮小或拖動
- Android實現(xiàn)ImageView圖片縮放和拖動
- Android編程實現(xiàn)圖片的瀏覽、縮放、拖動和自動居中效果
- Android實現(xiàn)圖片拖動效果
- Android通過自定義ImageView控件實現(xiàn)圖片的縮放和拖動的實現(xiàn)代碼
- Android RecyclerView多類型布局卡片解決方案
- Android實現(xiàn)簡單卡片布局
- Android控件CardView實現(xiàn)卡片布局
- Android編程重寫ViewGroup實現(xiàn)卡片布局的方法
- Android實現(xiàn)可拖動層疊卡片布局
相關(guān)文章
Android App數(shù)據(jù)格式Json解析方法和常見問題
JSON數(shù)據(jù)格式,在Android中被廣泛運用于客戶端和網(wǎng)絡(luò)(或者說服務(wù)器)通信,非常有必要系統(tǒng)的了解學習。恰逢本人最近對json做了一個簡單的學習,特此總結(jié)一下,以饗各位2014-03-03解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法
這篇文章主要為大家詳細介紹了解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-03-03解析Android中string-array數(shù)據(jù)源的簡單使用
本篇文章是對Android中string-array數(shù)據(jù)源的使用進行了詳細的分析介紹,需要的朋友參考下2013-06-06Android TextView Marquee的應(yīng)用實例詳解
這篇文章主要介紹了Android TextView Marquee的應(yīng)用實例詳解的相關(guān)資料,這里說明使用方法及簡單實例和注意實現(xiàn),需要的朋友可以參考下2017-08-08Android編程創(chuàng)建桌面快捷方式的常用方法小結(jié)【2種方法】
這篇文章主要介紹了Android編程創(chuàng)建桌面快捷方式的常用方法,結(jié)合實例形式總結(jié)分析了2種常見的實現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2017-02-02Java操作Ant壓縮和解壓文件及批量打包Anroid應(yīng)用
這篇文章主要介紹了使用Java操作Ant壓縮和解壓文件以及批量打包Anroid應(yīng)用的教程,Ant是一個自動化部署工具,用來處理zip和tar文件非常方便,需要的朋友可以參考下2016-02-02Android ReboundScrollView仿IOS拖拽回彈效果
這篇文章主要為大家詳細介紹了Android ReboundScrollView仿IOS拖拽回彈效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11