Android如何創(chuàng)建可拖動(dòng)的圖片控件
本文實(shí)例為大家分享了Android創(chuàng)建可拖動(dòng)圖片控件的具體代碼,供大家參考,具體內(nèi)容如下
重載、自繪
1、從View派生一個(gè)控件類(lèi) ,構(gòu)造函數(shù)中調(diào)用父類(lèi)構(gòu)造器。
2、重載其onDraw函數(shù),在里面繪制圖片。(和windows的MFC有種似曾相識(shí)的感覺(jué),可能安卓借鑒了windows的模式吧)
消息處理
拖動(dòng)圖片的消息,主要是處理按下和移動(dòng)兩個(gè)消息,重載onTouchEvent。數(shù)學(xué)知識(shí)(平移):在ACTION_DOWN時(shí)記錄下坐標(biāo)點(diǎn),在ACTION_MOVE時(shí)根據(jù)當(dāng)前位置與按下時(shí)的位置算出平移量。刷新控件,導(dǎo)致控件重繪,重繪時(shí)移動(dòng)繪制的左上角坐標(biāo)即可。
剛開(kāi)始時(shí),只是收到了ACTION_DOWN消息,ACTION_MOVE消息就是捕捉不到,上網(wǎng)搜了下,原來(lái)是我在onTouchEvent最后調(diào)用了父類(lèi)函數(shù)return super.onTouchEvent(event);父類(lèi)里面返回false表示對(duì)這些消息不予關(guān)注,后續(xù)的ACTION_MOVE和ACTION_UP就不會(huì)進(jìn)來(lái)了。
代碼和配置
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,如果返回父類(lèi)方法即false,則后續(xù)的move up 消息都不會(huì)觸發(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ù)圖片尺寸計(jì)算適合屏幕居中的方法。
運(yùn)行程序


以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android Matrix實(shí)現(xiàn)圖片隨意放大縮小或拖動(dòng)
- Android實(shí)現(xiàn)ImageView圖片縮放和拖動(dòng)
- Android編程實(shí)現(xiàn)圖片的瀏覽、縮放、拖動(dòng)和自動(dòng)居中效果
- Android實(shí)現(xiàn)圖片拖動(dòng)效果
- Android通過(guò)自定義ImageView控件實(shí)現(xiàn)圖片的縮放和拖動(dòng)的實(shí)現(xiàn)代碼
- Android RecyclerView多類(lèi)型布局卡片解決方案
- Android實(shí)現(xiàn)簡(jiǎn)單卡片布局
- Android控件CardView實(shí)現(xiàn)卡片布局
- Android編程重寫(xiě)ViewGroup實(shí)現(xiàn)卡片布局的方法
- Android實(shí)現(xiàn)可拖動(dòng)層疊卡片布局
相關(guān)文章
Android App數(shù)據(jù)格式Json解析方法和常見(jiàn)問(wèn)題
JSON數(shù)據(jù)格式,在Android中被廣泛運(yùn)用于客戶(hù)端和網(wǎng)絡(luò)(或者說(shuō)服務(wù)器)通信,非常有必要系統(tǒng)的了解學(xué)習(xí)。恰逢本人最近對(duì)json做了一個(gè)簡(jiǎn)單的學(xué)習(xí),特此總結(jié)一下,以饗各位2014-03-03
Android編程實(shí)現(xiàn)號(hào)碼歸屬地查詢(xún)的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)號(hào)碼歸屬地查詢(xún)的方法,涉及Android xml文件的發(fā)送及WebService的操作技巧,需要的朋友可以參考下2016-01-01
解決Android SurfaceView繪制觸摸軌跡閃爍問(wèn)題的方法
這篇文章主要為大家詳細(xì)介紹了解決Android SurfaceView繪制觸摸軌跡閃爍問(wèn)題的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
android實(shí)現(xiàn)多點(diǎn)觸摸效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)多點(diǎn)觸摸效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
android 線性布局LinearLayout實(shí)例代碼
android 線性布局LinearLayout實(shí)例代碼,需要的朋友可以參考一下2013-05-05
解析Android中string-array數(shù)據(jù)源的簡(jiǎn)單使用
本篇文章是對(duì)Android中string-array數(shù)據(jù)源的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android TextView Marquee的應(yīng)用實(shí)例詳解
這篇文章主要介紹了Android TextView Marquee的應(yīng)用實(shí)例詳解的相關(guān)資料,這里說(shuō)明使用方法及簡(jiǎn)單實(shí)例和注意實(shí)現(xiàn),需要的朋友可以參考下2017-08-08
Android編程創(chuàng)建桌面快捷方式的常用方法小結(jié)【2種方法】
這篇文章主要介紹了Android編程創(chuàng)建桌面快捷方式的常用方法,結(jié)合實(shí)例形式總結(jié)分析了2種常見(jiàn)的實(shí)現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2017-02-02
Java操作Ant壓縮和解壓文件及批量打包Anroid應(yīng)用
這篇文章主要介紹了使用Java操作Ant壓縮和解壓文件以及批量打包Anroid應(yīng)用的教程,Ant是一個(gè)自動(dòng)化部署工具,用來(lái)處理zip和tar文件非常方便,需要的朋友可以參考下2016-02-02
Android ReboundScrollView仿IOS拖拽回彈效果
這篇文章主要為大家詳細(xì)介紹了Android ReboundScrollView仿IOS拖拽回彈效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11

