上一篇文章基本上实现了图片的拖拉 放大等更能, 有缺点,经过今天的测试发现bug 不少:
一是: 在拖动的过程中效果很生硬,没有上一张下一张的效果 :下面将采用动画效果实现。
二是:在动态过去图片的过程浏览的过程中下一张浏览的信息依然保留了上一张图片图片浏览的信息,比如,我把上一张图片进行了放大的查看,而在拖动下一张查看的时候出现了上一上浏览的时的矩阵状态,放大的状态,原因是:没有进行初始化新图片信息。
三是:从服务器获取图片时候,有时候是获取不到图片,对获取不到图片进行的权限控制操作。
四是: 程序快速拖动查看图片的时很容易出现 内存溢出的问题 原因:没有对bitmap进行有效的释放,合理合时的的释放。
因为时间关系:先回家了,服务器也挂了,截图又不能给上传给你们看了,这是我写的,可能写的不是很好,忘指教
package com.jh.dongyi.activity; import java.util.ArrayList; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PointF; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.DisplayMetrics; import android.util.FloatMath; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.animation.AnimationUtils; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.ImageView.ScaleType; import com.jh.dongyi.entity.ProjectImage; import com.jh.dongyi.enumate.CustomerType; import com.jh.dongyi.impl.DBFunction; import com.jh.dongyi.util.BaseActivity; import com.jh.dongyi.util.Configuration; import com.jh.dongyi.util.ImageFactory; import com.jh.dongyi.util.POAException; import com.jh.dongyi.util.TakePhotoListener; /** * * <code>LocalePicDatailsActivity</code> * @description: TODO(查看原始图片信息) * @version 1.0 * @author liaoyp * @since 2011-12-14 */ public class LocalePicDatailsActivity extends BaseActivity implements OnTouchListener { private Button bt_back; private Button im_take_photo; private TextView title; private Button bt_save; // 材料科 private TextView tv_photo_type; // 工程部-巡检 熊洋亭//上传于 2009-8-7 14:54 private TextView tv_photo_job; private ProjectImage projectImage; private ProgressBar loadingpb; private String path; private Bitmap bitmap; private ImageView iv_work_photo; private Bundle bundle; // 是否下载图片 private boolean download =true;; // 动画显示 private boolean isShowNext =true;; // 手势监听 //private GestureDetector gestureDetector; //图像矩阵 Matrix matrix = new Matrix(); //Matrix savedMatrix = new Matrix(); // 记录第一个点 PointF first = new PointF(); PointF start = new PointF(); PointF mid = new PointF(); private float oldDist; static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; private long beginTime,endTime; //禁止拖动扩大 boolean forbidZoom =true; // 当前点击的是哪一张照片的位置 private int position; // 所有图片列表 private ArrayList<ProjectImage> projectImageList; // 是否是客户 private boolean isCustomer; // 拍照 private TakePhotoListener photoListener; // 数据库 private DBFunction function; // 设备高 宽 int dwidth ,dheight; Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 10){ loadingpb.setVisibility(View.GONE); if(bitmap != null){ forbidZoom = true; // 在下载完图片后初始画后一张图片的矩阵信息,对找不到服务器上的图片在本地进行默认图片替换 同时对其进行权限控制,使其不能扩大 缩小,拖动
initScaleBitmap(bitmap,true); //iv_work_photo.setImageBitmap(bitmap); }else{ forbidZoom = false; //iv_work_photo.setImageResource(R.drawable.file_broken); initScaleBitmap(bitmap,false); showToast("加载错误!"); } }else{ forbidZoom = false; loadingpb.setVisibility(View.GONE); //iv_work_photo.setImageResource(R.drawable.file_broken); initScaleBitmap(bitmap,false); showToast("没有你要看的图片"); } } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.work__photo_details); title = (TextView) findViewById(R.id.title); //gestureDetector = new GestureDetector(this); bt_back = (Button) findViewById(R.id.back); im_take_photo = (Button) findViewById(R.id.save); im_take_photo.setBackgroundResource(R.drawable.top_tackephoto_selector); //照片 iv_work_photo = (ImageView) findViewById(R.id.iv_work_photo); tv_photo_type = (TextView) findViewById(R.id.tv_photo_type); tv_photo_job = (TextView) findViewById(R.id.tv_photo_job); loadingpb = (ProgressBar) findViewById(R.id.loadingpb); bt_save = (Button) findViewById(R.id.save); // 获取点击状态 Bundle bundle = this.getIntent().getExtras(); if (bundle != null) { if (bundle.get("position") != null) { position = (Integer) bundle.get("position"); } if (bundle.get("projectimageList") != null) { projectImageList = (ArrayList<ProjectImage>) bundle.get("projectimageList"); } projectImage = projectImageList.get(position); path = projectImage.getOriginalImage(); } //获取手机屏幕的宽和高 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); dwidth = dm.widthPixels; dheight = dm.heightPixels; init(); } /** * * <code>initScaleBitmap</code> * @description: TODO(根据图片缩放图片) * @param bitmap * @since 2012-1-9 liaoyp */ public void initScaleBitmap(Bitmap bitmap,boolean ishave){ // matrix=new Matrix(); if(ishave){ int widOrg=bitmap.getWidth(); int heightOrg=bitmap.getHeight(); // 宽 高 比列 float scaleWid = (float)dwidth/widOrg; float scaleHeight = (float)dheight/heightOrg; float scale; // 如果宽的 比列大于搞的比列 则用高的比列 否则用宽的 if(scaleWid>scaleHeight) { scale = scaleHeight; } else scale = scaleWid; iv_work_photo.setImageBitmap(bitmap); matrix.setScale(scale,scale); iv_work_photo.setScaleType(ScaleType.MATRIX); iv_work_photo.setImageMatrix(matrix); }else{ iv_work_photo.setImageMatrix(null); iv_work_photo.setScaleType(ScaleType.CENTER); iv_work_photo.setImageResource(R.drawable.file_broken); } iv_work_photo.setOnTouchListener(this); iv_work_photo.setLongClickable(true); // savedMatrix.set(matrix); } @Override public void init() { bundle = LocalePicDatailsActivity.this.getIntent().getExtras(); bt_back.setOnClickListener(new OnClickListener() { public void onClick(View v) { LocalePicDatailsActivity.this.finish(); }}); if (bundle.getBoolean("FromTAB",false) == false && Configuration.customerType == CustomerType.EMPLOYEE.getValue() ) {//员工不是从TAB进入巡查记录 title.setText(Configuration.employee_customerListName+"的现场照片"); System.out.println("xiang xi form tab false"); isCustomer = true; } else { title.setText(getString(R.string.local_pic)); } im_take_photo.setVisibility(View.GONE); photoListener = new TakePhotoListener(LocalePicDatailsActivity.this,true); im_take_photo.setOnClickListener(photoListener); if(projectImage != null){ if(projectImage.getDescription() != null){ tv_photo_type.setText(projectImage.getDescription()); } if(projectImage.getDescription() != null){ tv_photo_job.setText(projectImage.getUploadInfo()); } }else{ showToast("加载错误!"); } if(path != null){ new Thread(){ public void run(){ try { String path1 = new DBFunction(LocalePicDatailsActivity.this).queryImagePath(path,Configuration.return_customerId); if (path1 != null) { bitmap = BitmapFactory.decodeFile(path1); } else { String p = null; p = ImageFactory.getURLBitmap(path, 2); if (p != null) { bitmap =ImageFactory.getBitmapByParh(p); } } } catch (POAException e) { handler.sendEmptyMessage(-1); } if (bitmap != null) { handler.sendEmptyMessage(10); } } }.start(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && data.getExtras() != null) { Intent intent = new Intent(getApplicationContext(),UploadPhotoActivity.class); intent.putExtra("Imagepath", photoListener.getFilePath()); startActivity(intent); } } class SaveClickListener implements OnClickListener { public void onClick(View v) { } } class BackClickListener implements OnClickListener { public void onClick(View v) { LocalePicDatailsActivity.this.finish(); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); tv_photo_type = null; tv_photo_job = null; if (projectImage != null) { projectImage = null; } if (bitmap != null) { bitmap = null; } if (projectImageList != null) { projectImageList.clear(); projectImageList = null; } if (iv_work_photo != null) { iv_work_photo.clearAnimation(); } } /** * * <code>initImageMessage</code> * @description: TODO(初始化图片信息) * @since 2012-1-6 liaoyp */ public void initImageMessage(){ // 如果是客户 ,变换标题 startShowAnimation(isShowNext); loadingpb.setVisibility(View.VISIBLE); iv_work_photo.setImageBitmap(null); function = new DBFunction(LocalePicDatailsActivity.this); // 开始动画 ProjectImage projectImage = projectImageList.get(position); if (projectImage != null) { String name = function.getCustomNameByID(String.valueOf(projectImage.getProjectID())); if(!isCustomer){ title.setText(name+"的现场照片"); } if(projectImage.getDescription() != null){ tv_photo_type.setText(projectImage.getDescription()); } if(projectImage.getDescription() != null){ tv_photo_job.setText(projectImage.getUploadInfo()); } path = projectImage.getOriginalImage(); if( path != null){ new Thread(){ public void run(){ try { String path1 = new DBFunction(LocalePicDatailsActivity.this).queryImagePath(path,Configuration.return_customerId); if(path1 != null){ System.out.println("havpath"+path1); bitmap =ImageFactory.getBitmapByParh(path1); System.out.println("load finish =="); }else{ String p = null; p = ImageFactory.getURLBitmap(path, 2); if(p != null){ bitmap =ImageFactory.getBitmapByParh(p); } } download = true; } catch (POAException e) { //e.printStackTrace(); handler.sendEmptyMessage(1); download =false; } if(download){ handler.sendEmptyMessage(10); } } }.start(); } }else{ showToast("加载错误!"); } } /** * * <code>startShowAnimation</code> * @description: TODO(启动动画) * @param isShowNext2 * @since 2012-1-6 liaoyp */ private void startShowAnimation(boolean isShowNext2) { iv_work_photo.clearAnimation(); if (isShowNext2) { iv_work_photo.startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in)); iv_work_photo.startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out)); }else{ iv_work_photo.startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in)); iv_work_photo.startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out)); } } // @Override // public boolean onTouchEvent(MotionEvent event) { // // TODO Auto-generated method stub // return gestureDetector.onTouchEvent(event); // } /*public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e1.getX() - e2.getX() > 120) { // 向左滑动 showNext(); return true; } else if (e1.getX() - e2.getX() < -120) { // 向右滑动 showPrevious(); return true; } return false; }*/ // 上一图片信息 private void showPrevious() { // 动画标识 isShowNext = false; getImageView(position - 1); // 初始化图片信息 initImageMessage(); } // 下一张图片信息 private void showNext() { // 动画标识 isShowNext = true; getImageView(position + 1); // 初始化图片信息 initImageMessage(); } private void getImageView(int Lposition) { position = Lposition; int bigSize = projectImageList.size()-1; if (Lposition >= bigSize) { showToast("已经是最后一张"); position = bigSize; } else if (Lposition < 0) { showToast("已经是第一张"); position = 0; } else {// 回收图片,为什么在这里回收,我也不多讲了,因为不管是浏览上一张还是下一张 都需要帮刚刚浏览的bitmap释放,否则很容易出现oo if(bitmap !=null){ bitmap.recycle(); } } } public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()& MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: beginTime = System.currentTimeMillis(); mode = DRAG; System.out.println("down"); first.set(event.getX(), event.getY()); start.set(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: endTime = System.currentTimeMillis(); System.out.println("endTime=="+(endTime - beginTime)); float x = event.getX(0) - first.x; float y = event.getY(0) - first.y; // 多长的距离 float move = FloatMath.sqrt(x * x + y * y); System.out.println(x+" move=="+(move)); // 方向 int direction = x > 0 ? 1 : -1; // 计算时间和移动的距离 来判断你想要的操作 if(endTime - beginTime<500&&move>20) { //这里就是做你上一页下一页 //Toast.makeText(this, "----do something-----", 1000).show(); // 下一页 if (direction > 0) { showPrevious(); return true; } //上一页 if (direction < 0) { showNext(); return true; } } break; case MotionEvent.ACTION_MOVE: System.out.println("move"); if(mode == DRAG) { if(forbidZoom){ matrix.postTranslate(event.getX()-start.x, event.getY()-start.y); } start.set(event.getX(), event.getY()); } else { float newDist = spacing(event); if (newDist > 10f) { // matrix.set(savedMatrix); float scale = newDist / oldDist; System.out.println("scale=="+scale); if (forbidZoom) { matrix.postScale(scale, scale, mid.x, mid.y); } } oldDist = newDist; } break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); if (oldDist > 10f) { midPoint(mid, event); mode = ZOOM; } System.out.println("ACTION_POINTER_DOWN"); break; case MotionEvent.ACTION_POINTER_UP: System.out.println("ACTION_POINTER_UP"); break; } if(forbidZoom){ iv_work_photo.setImageMatrix(matrix); } return false; } /** * 计算拖动的距离 * @param event * @return */ 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); } /** * 计算两点的之间的中间点 * @param point * @param event */ 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); } }