android 大圖片拖拽并縮放實(shí)現(xiàn)原理
由于最近項(xiàng)目忙,博客一直沒有時(shí)間更新,今天有點(diǎn)時(shí)間就連續(xù)更新兩篇吧,過過癮。
這篇圖片拖拽縮放也是我在項(xiàng)目中用到的,今天整理一下,將源碼奉獻(xiàn)給大家,希望對(duì)大家以后碰到相似的問題有幫助。
這篇就不做過多介紹了,直接上源碼:
public class SpacePageActivity extends Activity {
private LinearLayout linnerLayout_spacepage;
private RelativeLayout relativeLayout_spacepage;
private Button btn_spacepage_back;
private Button btn_spacepage_save;
private static Boolean isTrue=false;
private static String IMAGE_MIME_TYPE ;
private ImageView image_spacePage;
private ProgressDialog dialog;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//隱藏標(biāo)題
setContentView(R.layout.spacepage);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
initHead();
if(isNetworkAvailable()){
image_spacePage=(ImageView) findViewById(R.id.image_spacepage);
btn_spacepage_save=(Button) findViewById(R.id.btn_spacepage_save);
image_spacePage.setOnTouchListener(new MulitPointTouchListener(image_spacePage));
image_spacePage.setScaleType(ScaleType.CENTER_INSIDE);
//加載成功
String urls="http://epaper.yzdsb.com.cn/201201/04/yz2104_7.jpg";
bitmap=returnBitMap(urls);
if(null!=bitmap){
image_spacePage.setImageBitmap(bitmap);
}
}
}
public Bitmap returnBitMap(String url) {
if(null==url || "".equals(url)){
return null;
}
URL myFileUrl = null;
Bitmap bitmap = null;
try {
myFileUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setConnectTimeout(2000);
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
public class MulitPointTouchListener implements OnTouchListener {
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
public ImageView image;
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
public MulitPointTouchListener(ImageView image) {
super();
this.image = image;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
this.image.setScaleType(ScaleType.MATRIX);
ImageView view = (ImageView) v;
// dumpEvent(event);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
Log.w("FLAG", "ACTION_DOWN");
matrix.set(view.getImageMatrix());
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
Log.w("FLAG", "ACTION_POINTER_DOWN");
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
Log.w("FLAG", "ACTION_UP");
case MotionEvent.ACTION_POINTER_UP:
Log.w("FLAG", "ACTION_POINTER_UP");
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
Log.w("FLAG", "ACTION_MOVE");
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
}
private void initHead() {
linnerLayout_spacepage = (LinearLayout) findViewById(R.id.linnerLayout_spacepage);
relativeLayout_spacepage=(RelativeLayout) findViewById(R.id.relativeLayout_spacepage);
btn_spacepage_back = (Button) findViewById(R.id.btn_spacepage_back);
btn_spacepage_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
btn_spacepage_save = (Button) findViewById(R.id.btn_spacepage_save);
}
protected boolean isNetworkAvailable() {
ConnectivityManager connectivity = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
Log.i("NetWorkState", "Unavailabel");
return false;
} else {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
Log.i("NetWorkState", "Availabel");
return true;
}
}
}
}
return false;
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
if(bitmap!=null){
if(!bitmap.isRecycled()){
bitmap.recycle(); //回收?qǐng)D片所占的內(nèi)存
bitmap=null;
System.gc(); //提醒系統(tǒng)及時(shí)回收
}
}
super.onStop();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if(bitmap!=null){
if(!bitmap.isRecycled()){
bitmap.recycle(); //回收?qǐng)D片所占的內(nèi)存
bitmap=null;
System.gc(); //提醒系統(tǒng)及時(shí)回收
}
}
}
}
因?yàn)槭谴髨D片,在onDestroy的時(shí)候要recycle掉,這樣系統(tǒng)才會(huì)定時(shí)回收掉,System.gc();是提醒系統(tǒng)回收,雖然java這種垃圾回收機(jī)制不用我們自己關(guān)心對(duì)象的回收,但是這也給android開發(fā)人員帶來了不好的一面,如果系統(tǒng)回收不及時(shí)很可能就造成了內(nèi)存溢出了。什么時(shí)候手機(jī)不擔(dān)心內(nèi)存使用了就好了。
運(yùn)行一下看看效果:


- Android實(shí)現(xiàn)讓圖片在屏幕上任意移動(dòng)的方法(拖拽功能)
- Android使用RecycleView實(shí)現(xiàn)拖拽交換item位置
- Android自定義View實(shí)現(xiàn)可以拖拽的GridView
- Android DragVideo實(shí)現(xiàn)播放視頻時(shí)任意拖拽的方法
- Android中利用matrix 控制圖片的旋轉(zhuǎn)、縮放、移動(dòng)
- android 多點(diǎn)觸摸圖片縮放的具體實(shí)現(xiàn)方法
- Android 圖片縮放與旋轉(zhuǎn)的實(shí)現(xiàn)詳解
- Android開發(fā)之圖形圖像與動(dòng)畫(二)Animation實(shí)現(xiàn)圖像的漸變/縮放/位移/旋轉(zhuǎn)
- Android應(yīng)用中實(shí)現(xiàn)手勢(shì)控制圖片縮放的完全攻略
- Android自定義View實(shí)現(xiàn)可拖拽縮放的矩形框
相關(guān)文章
android監(jiān)控sim卡有沒有服務(wù)示例(sim卡管理)
android監(jiān)聽SIM卡有沒有服務(wù),可以使用android.telephony.PhoneStateListener類來實(shí)現(xiàn),下面是一個(gè)簡(jiǎn)單的小例子,大家參考使用吧2014-01-01
Android如何自定義EditText光標(biāo)與下劃線顏色詳解
在android開發(fā)中 EditTextText是我們經(jīng)常用到的,我們使用時(shí)會(huì)有一些小問題,下面這篇文章主要給大家介紹了關(guān)于利用Android如何自定義EditText光標(biāo)與下劃線顏色的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-08-08
淺談Android Studio如何Debug對(duì)應(yīng)so文件C/C++代碼
本篇文章主要介紹了淺談Android Studio如何Debug對(duì)應(yīng)so文件C/C++代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12
關(guān)于Android Activity之間跳轉(zhuǎn)問題(Intent)
這篇文章主要介紹了Android Activity之間跳轉(zhuǎn)Intent,當(dāng)一個(gè)Acitivity需要啟動(dòng)另一個(gè)Activity時(shí),通過Intent來表達(dá)自己的意圖,告知系統(tǒng)啟動(dòng)哪個(gè)Activity,本文給大家詳細(xì)講解,需要的朋友可以參考下2022-10-10
Android下拉列表(Spinner)效果(使用C#和Java分別實(shí)現(xiàn))
這篇文章主要介紹了Android下拉列表(Spinner)效果(使用C#和Java分別實(shí)現(xiàn)),本文直接給出效果圖和兩種語言的實(shí)現(xiàn)代碼及布局代碼,需要的朋友可以參考下2015-06-06
通過WIFI(不用數(shù)據(jù)線)連接Android手機(jī)調(diào)試
本文主要介紹WIFI 鏈接手機(jī)調(diào)試,這里詳細(xì)介紹了WIFI 鏈接Android手機(jī)實(shí)現(xiàn)調(diào)試的過程,有需要的小伙伴可以參考下2016-08-08
淺談Android實(shí)踐之ScrollView中滑動(dòng)沖突處理解決方案
涉及到了ViewPager,MapView,ListView,就需要ScrollView來做一下支援,這篇文章主要介紹了淺談Android實(shí)踐之ScrollView中滑動(dòng)沖突處理解決方案,有需要的可以來了解一下。2016-12-12
Android編程UI設(shè)計(jì)之GridView和ImageView的用法
這篇文章主要介紹了Android編程UI設(shè)計(jì)之GridView和ImageView的用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android中GridView和ImageView組件的相關(guān)方法使用技巧,需要的朋友可以參考下2016-01-01
AndroidStudio替換項(xiàng)目圖標(biāo)ic_launcher操作
這篇文章主要介紹了AndroidStudio替換項(xiàng)目圖標(biāo)ic_launcher操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08

