Android自定義View實現圖片顯示,並實現縮放、拖拽、切換功能
阿新 • • 發佈:2019-02-12
這裡貼三個檔案的原始碼,第一個是main.java
package com.example.test; import java.util.ArrayList; import java.util.List; import com.example.test.MyXZ; import com.example.test.R; import com.example.test.ZoomListener; import com.example.test.test; import com.example.test.R.drawable; import com.example.test.R.id; import com.example.test.R.layout; import com.example.test.ZoomListener.Swiper; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; public class main extends Activity { /** Called when the activity is first created. */ private Bitmap mBitmap; private List<Bitmap> mlist; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bitmap m1=BitmapFactory.decodeResource(getResources(), R.drawable.m1); Bitmap m2=BitmapFactory.decodeResource(getResources(), R.drawable.m2); Bitmap m3=BitmapFactory.decodeResource(getResources(), R.drawable.m3); Bitmap m4=BitmapFactory.decodeResource(getResources(), R.drawable.m4); Bitmap m5=BitmapFactory.decodeResource(getResources(), R.drawable.m5); Bitmap m6=BitmapFactory.decodeResource(getResources(), R.drawable.m6); Bitmap m7=BitmapFactory.decodeResource(getResources(), R.drawable.m7); Bitmap m8=BitmapFactory.decodeResource(getResources(), R.drawable.m8); mlist=new ArrayList<Bitmap>(); mlist.add(m1); mlist.add(m2); mlist.add(m3); mlist.add(m4); mlist.add(m5); mlist.add(m6); mlist.add(m7); mlist.add(m8); final test tt=(test) this.getApplication(); this.setContentView(R.layout.activity_main); MyXZ iv=(MyXZ) findViewById(R.id.myXZ1); iv.setImage(mlist.get(tt.getCurr())); iv.update(); ZoomListener zl=new ZoomListener(); Swiper swp=new Swiper(){ @Override public void Swipe(View v, float length) { // TODO 自動生成的方法存根 if(Math.abs(length)>20){ int Curr=tt.getCurr(); int i=length>0?1:-1; if(Curr+i<0){ Curr=mlist.size()-1; }else if(Curr+i>=mlist.size()){ Curr=0; }else{ Curr+=i; } tt.setCurr(Curr); ((MyXZ)v).setImage(mlist.get(Curr)); } } }; zl.setSwp(swp); iv.setOnTouchListener(zl); } @Override protected void onDestroy() { super.onDestroy(); if (mBitmap != null) { mBitmap.recycle(); } } }
第二個未見為ZoomListenner.java
package com.example.test; import android.graphics.PointF; import android.util.FloatMath; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; public class ZoomListener implements OnTouchListener { float Ospace; PointF start = new PointF(0, 0); String Mode; private Swiper swp; @Override public boolean onTouch(View v, MotionEvent event) { // TODO 自動生成的方法存根 switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: start.set(event.getX(), event.getY()); Log.i("info", start.x + ":" + start.y); Mode = "DRAG"; break; case MotionEvent.ACTION_POINTER_DOWN: Ospace = spacing(event); Mode = "ZOOM"; Log.i("info", "原始面積" + Ospace); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: Mode = "NONE"; if(((MyXZ) v).getZoom() == 1){ float sx = start.x - event.getX(); float sy = start.y - event.getY(); if (Math.abs(sx) > Math.abs(sy)) { swp.Swipe(v, sx/10); } } start.set(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: if (Mode == "DRAG") { if (((MyXZ) v).getZoom() > 1) { float sx = start.x - event.getX(); float sy = start.y - event.getY(); if(Math.sqrt(sx*sx+sy*sy)>20){ ((MyXZ) v).setPan((int) (start.x - event.getX()), (int) (start.y - event.getY())); Log.i("info", "平移:" + ((MyXZ) v).getPan().x + ":" + ((MyXZ) v).getPan().y); start.set(event.getX(), event.getY()); } } } else if (Mode == "ZOOM") { float nspace = spacing(event); float zoom = 1 + (nspace - Ospace) / Ospace; if(Math.abs(nspace - Ospace)>3){ ((MyXZ) v).setZoom(zoom); Log.i("Info", "縮放為:" + ((MyXZ) v).getZoom()); Ospace=nspace; } } break; } 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); } public Swiper getSwp() { return swp; } public void setSwp(Swiper swp) { this.swp = swp; } public interface Swiper { public void Swipe(View v, float length); } }
第三個為自定義的View MyXZ.java
package com.example.test; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; public class MyXZ extends View { private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); private final Rect SrcRect = new Rect(); private final Rect DstRect = new Rect(); private float RecentZoom = 1; private float Zoom = 1; private Point Pan = new Point(0, 0); private Bitmap mBitmap; public MyXZ(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { if (mBitmap != null) { UpdateRZ(); canvas.drawBitmap(mBitmap, SrcRect, DstRect, mPaint); } } private void UpdateRZ() { if (mBitmap != null) { float bw = mBitmap.getWidth(); float bh = mBitmap.getHeight(); float Sw = getWidth(); float Sh = getHeight(); if (bw * (Sh / bh) <= Sw) { RecentZoom = Sh / bh; } if (bh * (Sw / bw) <= Sh) { RecentZoom = Sw / bw; } int DesX = (int) Math.min(mBitmap.getWidth() * RecentZoom * getZoom(), getWidth()); int DesY = (int) Math.min(mBitmap.getHeight() * RecentZoom * getZoom(), getHeight()); int ResX = Math.round(DesX / RecentZoom / getZoom()); int ResY = Math.round(DesY / RecentZoom / getZoom()); if (Pan.x + (bw - ResX) / 2 < 0) { Pan.x = -((int) (bw - ResX) / 2); } if (Pan.y + (bh - ResY) / 2 < 0) { Pan.y = -((int) ((bh - ResY) / 2)); } if (ResX + (Pan.x + (bw - ResX) / 2) > bw) { Pan.x = (int) ((bw - ResX) / 2); } if (ResY + Pan.y + (bh - ResY) / 2 > bh) { Pan.y = (int) ((bh - ResY) / 2); } SrcRect.left = (int) (Pan.x + (bw - ResX) / 2); SrcRect.top = (int) (Pan.y + (bh - ResY) / 2); SrcRect.right = (int) (ResX + (Pan.x + (bw - ResX) / 2)); SrcRect.bottom = (int) (ResY + Pan.y + (bh - ResY) / 2); DstRect.left = (getWidth() - DesX) / 2; DstRect.right = (getWidth() - DesX) / 2 + DesX; DstRect.top = (getHeight() - DesY) / 2; DstRect.bottom = (getHeight() - DesY) / 2 + DesY; } } public void setPan(int x, int y) { Pan.x += x * getZoom() * RecentZoom; Pan.y += y * getZoom() * RecentZoom; update(); } public Point getPan() { return Pan; } public void update() { UpdateRZ(); invalidate(); } public void setImage(Bitmap bitmap) { mBitmap = bitmap; UpdateRZ(); invalidate(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); UpdateRZ(); } public float getZoom() { return Zoom; } public void setZoom(float zoom) { if (RecentZoom < 1) { if (zoom * Zoom >= 1) { Zoom *= zoom; if (Zoom >= 1/ RecentZoom) { Zoom = 1/ RecentZoom; } } else { Zoom = 1; } } else { Zoom = 1; } update(); } }
詳細的就不多說了,有興趣想了解詳細內容的,可以到我的個人網站下載原始碼檢視:http://www.nuatar.com/Article.aspx?id=d69f35891c0840278bed7a2e12b7b050
轉載請註明出處!!