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表示對這些消息不予關注,后續(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)可拖動層疊卡片布局
相關文章
Android App數(shù)據(jù)格式Json解析方法和常見問題
JSON數(shù)據(jù)格式,在Android中被廣泛運用于客戶端和網(wǎng)絡(或者說服務器)通信,非常有必要系統(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-06
Android TextView Marquee的應用實例詳解
這篇文章主要介紹了Android TextView Marquee的應用實例詳解的相關資料,這里說明使用方法及簡單實例和注意實現(xiàn),需要的朋友可以參考下2017-08-08
Android編程創(chuàng)建桌面快捷方式的常用方法小結(jié)【2種方法】
這篇文章主要介紹了Android編程創(chuàng)建桌面快捷方式的常用方法,結(jié)合實例形式總結(jié)分析了2種常見的實現(xiàn)方法與相關操作技巧,需要的朋友可以參考下2017-02-02
Android ReboundScrollView仿IOS拖拽回彈效果
這篇文章主要為大家詳細介紹了Android ReboundScrollView仿IOS拖拽回彈效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11

