博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ViewPager 可左右滑动和缩放的图片浏览
阅读量:5124 次
发布时间:2019-06-13

本文共 29712 字,大约阅读时间需要 99 分钟。

最近因为要做一个项目,需要使用到图片的浏览。我就自己在网上找了些资料,然后加以修改整理后出来一个demo,希望可以帮助到需要的人。同时这也是我第一个技术博客。

在做之前首先需要了解一下什么是ViewPager,怎么使用ViewPager。我这里提供一篇文章给大家  http://www.2cto.com/kf/201411/353975.html   我这里不在赘述了。

好了  了解完可以开始了

 PS  我不知道怎么制作那种动态的效果图,如果有谁知道请告诉我  我将万分感谢

 

 

 

一步一步来

 

首先先要写个布局 ViewPager的布局   activity_main.xml

1 
8 9
16 17
23 24
25 26 27 28

对应的效果是这样的 请看 有点丑 不管啦。用了一张底图  在上面代码中的 LinearLayout

 

然后是图片详情布局     image_details.xml

1 
2
5 6
10
11 12
21 22

 

最后一个布局是缩放的布局  zoom_image_layout.xml

1 
2
7 8

 

 

 

 

 

 

基本的布局我们完成了

 

再看代码吧

 

我这里因为迎合大部分朋友的需求 ,改成了从网络上下载图片的方式作为图片来源

先模拟一个图片URL的类

1 package com.higgs.mviewpager; 2  3 public class Images { 4  5     public final static String[] imageUrls = new String[]{ 6             "https://img-my.csdn.net/uploads/201309/01/1378037235_3453.jpg", 7             "https://img-my.csdn.net/uploads/201309/01/1378037235_7476.jpg", 8             "https://img-my.csdn.net/uploads/201309/01/1378037235_9280.jpg", 9             "https://img-my.csdn.net/uploads/201309/01/1378037234_3539.jpg",10             "https://img-my.csdn.net/uploads/201309/01/1378037234_6318.jpg",11     };12 }

 

然后就是实现代码了

说一下思路, 先获取ViewPager 然后往ViewPager 添加图片,但是图片是网络上的 所以要先下载后在添加进去,这里处于防止加载比较多的图片时造成OOM问题 所以引入了 LruCache 类缓存技术。先讲下载的图片存入手机里并缓存下来,一为了节省用户的数据流量,二为了之后的加载速度。有了缓冲下次就不用在重复去网络上下载了。  代码如下

1 package com.higgs.mviewpager;  2   3 import android.app.Activity;  4 import android.content.Intent;  5 import android.graphics.Bitmap;  6 import android.graphics.BitmapFactory;  7 import android.os.AsyncTask;  8 import android.os.Bundle;  9 import android.os.Environment; 10 import android.support.v4.view.PagerAdapter; 11 import android.support.v4.view.ViewPager; 12 import android.util.Log; 13 import android.view.View; 14 import android.view.ViewGroup; 15 import android.widget.ImageView; 16 import android.widget.Toast; 17  18 import java.io.BufferedInputStream; 19 import java.io.BufferedOutputStream; 20 import java.io.BufferedReader; 21 import java.io.File; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.InputStream; 25 import java.io.InputStreamReader; 26 import java.net.HttpURLConnection; 27 import java.net.URL; 28 import java.util.ArrayList; 29  30  31 public class MainActivity extends Activity { 32  33     private static final String TAG = "MainActivity"; 34     private ImageLoader  imageLoader = ImageLoader.getInstance();  //获取图片进行管理的工具类实例。 35  36     private ViewPager viewpager; 37     private ArrayList
viewList; 38 // private ImageView imageView1; 39 // private ImageView imageView2; 40 // private ImageView imageView3; 41 @Override 42 protected void onCreate(Bundle savedInstanceState) { 43 super.onCreate(savedInstanceState); 44 setContentView(R.layout.activity_main); 45 initView(); 46 } 47 48 49 private void initView() { 50 viewpager = (ViewPager) findViewById(R.id.viewpager); //获取viewpager 51 viewList = new ArrayList
(); //保存view,用于PagerAdapter 52 for(int i = 0; i
{ 81 82 /** 83 * 记录每个图片对应的位置 84 */ 85 private int mposition; 86 87 @Override 88 protected Bitmap doInBackground(Integer... params) { 89 90 mposition = params[0];//获取传过来的图片position (下标) 91 String strurl = Images.imageUrls[mposition]; //通过下标获得图片URL 92 File imageFile = new File(getImagePath(strurl)); //获取图片在本地手机中的位置路径 93 if (!imageFile.exists()) { //判断是否存在手机里 94 doPost(strurl);//如果没有就下载图片 95 } 96 if (strurl != null) { 97 Bitmap bitmap = ImageLoader.decodeSampledBitmapFromResource(imageFile.getPath(), 98 290); //压缩图片 我这里写的是290 99 if (bitmap != null) {100 imageLoader.addBitmapToMemoryCache(strurl, bitmap); //将图片加入缓冲 LruCache中101 return bitmap;102 }103 }104 105 106 return null;107 }108 109 @Override110 protected void onPostExecute(Bitmap o) {111 ImageView imageView = new ImageView(MainActivity.this);112 imageView.setImageBitmap(o);113 imageView.setOnClickListener(new View.OnClickListener() {114 @Override115 public void onClick(View v) {116 117 Intent intent = new Intent(MainActivity.this, ImageDetailsActivity.class);//打开图片详情类118 intent.putExtra("image_position", mposition);119 MainActivity.this.startActivity(intent);120 }121 });122 123 viewList.add(imageView);124 pagerAdapter.notifyDataSetChanged(); //这句话一定不能少 ,不然会有异常125 Log.e("TAG2", "" + viewList.size());126 127 128 }129 130 131 }132 133 /**134 * ViewPager的适配器 重写下面几个方法就可以了135 */136 137 PagerAdapter pagerAdapter = new PagerAdapter() {138 139 @Override140 public int getCount() {141 142 return viewList.size();143 }144 145 @Override146 public boolean isViewFromObject(View view, Object object) {147 return view == object;148 }149 150 @Override151 public void destroyItem(ViewGroup container, int position,152 Object object) {153 container.removeView(viewList.get(position));154 155 }156 157 @Override158 public int getItemPosition(Object object) {159 160 return super.getItemPosition(object);161 }162 163 @Override164 public Object instantiateItem(ViewGroup container, int position) {165 container.addView(viewList.get(position));166 return viewList.get(position);167 }168 169 };170 171 172 /**173 * 下载图片方法 并将图片缓冲至手机指定位置中174 * @param urlstr 图片URL175 */176 public void doPost(String urlstr){177 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {178 Log.d("TAG", "monted sdcard");179 } else {180 Log.d("TAG", "has no sdcard");181 }182 HttpURLConnection con = null;183 FileOutputStream fos = null;184 BufferedOutputStream bos = null;185 BufferedInputStream bis = null;186 File imageFile = null;187 try {188 URL url = new URL(urlstr);189 con = (HttpURLConnection) url.openConnection();190 con.setConnectTimeout(5 * 1000);191 con.setReadTimeout(15 * 1000);192 con.setDoInput(true);193 con.setDoOutput(true);194 bis = new BufferedInputStream(con.getInputStream());195 imageFile = new File(getImagePath(urlstr));196 fos = new FileOutputStream(imageFile);197 bos = new BufferedOutputStream(fos);198 byte[] b = new byte[1024];199 int length;200 while ((length = bis.read(b)) != -1) {
// 写入手机中201 bos.write(b, 0, length);202 bos.flush();203 }204 } catch (Exception e) {205 e.printStackTrace();206 } finally {207 try {208 if (bis != null) {209 bis.close();210 }211 if (bos != null) {212 bos.close();213 }214 if (con != null) {215 con.disconnect();216 }217 } catch (IOException e) {218 e.printStackTrace();219 }220 }221 if (imageFile != null) {222 Bitmap bitmap = ImageLoader.decodeSampledBitmapFromResource(imageFile.getPath(),223 290);224 if (bitmap != null) {225 imageLoader.addBitmapToMemoryCache(urlstr, bitmap);226 }227 }228 }229 230 /**231 * 获取图片的本地存储路径。232 *233 * @param imageUrl234 * 图片的URL地址。235 * @return 图片的本地存储路径。236 */237 private String getImagePath(String imageUrl) {238 int lastSlashIndex = imageUrl.lastIndexOf("/");239 String imageName = imageUrl.substring(lastSlashIndex + 1);240 String imageDir = Environment.getExternalStorageDirectory().getPath()241 + "/pwxceshibao/";242 File file = new File(imageDir);243 if (!file.exists()) {244 file.mkdirs();245 }246 String imagePath = imageDir + imageName;247 return imagePath;248 }249 250 }

 

下面是几个工具类。是我从网上找的。个人觉得非常有用。所以就拿过来了。注意了,下面几个工具类都用上了,所以不能少哦

在这里要感谢 http://blog.csdn.net/sziicool/article/details/18728187  博主,我是站在他的肩膀上修改的。

 

 

第一个是查看大图类  就是图片详情类

1 package com.higgs.mviewpager;  2   3 import android.app.Activity;  4 import android.graphics.Bitmap;  5 import android.graphics.BitmapFactory;  6 import android.os.Bundle;  7 import android.os.Environment;  8 import android.support.v4.view.PagerAdapter;  9 import android.support.v4.view.ViewPager; 10 import android.support.v4.view.ViewPager.OnPageChangeListener; 11 import android.view.LayoutInflater; 12 import android.view.View; 13 import android.view.ViewGroup; 14 import android.view.Window; 15 import android.widget.TextView; 16  17 import java.io.File; 18  19 /** 20  * 查看大图的Activity界面。 21  *  22  * @author guolin 23  */ 24 public class ImageDetailsActivity extends Activity implements 25         OnPageChangeListener { 26  27     /** 28      * 用于管理图片的滑动 29      */ 30     private ViewPager viewPager; 31  32     /** 33      * 显示当前图片的页数 34      */ 35     private TextView pageText; 36  37     @Override 38     protected void onCreate(Bundle savedInstanceState) { 39         super.onCreate(savedInstanceState); 40         requestWindowFeature(Window.FEATURE_NO_TITLE); 41         setContentView(R.layout.image_details); 42         int imagePosition = getIntent().getIntExtra("image_position", 0); 43         pageText = (TextView) findViewById(R.id.page_text); 44         viewPager = (ViewPager) findViewById(R.id.view_pager); 45         ViewPagerAdapter adapter = new ViewPagerAdapter(); 46         viewPager.setAdapter(adapter); 47         viewPager.setCurrentItem(imagePosition); 48         viewPager.setOnPageChangeListener(this); 49         viewPager.setEnabled(false); 50         // 设定当前的页数和总页数 51         pageText.setText((imagePosition + 1) + "/" + Images.imageUrls.length); 52     } 53  54     /** 55      * ViewPager的适配器 56      *  57      * @author guolin 58      */ 59     class ViewPagerAdapter extends PagerAdapter { 60  61         @Override 62         public Object instantiateItem(ViewGroup container, int position) { 63             String imagePath = getImagePath(Images.imageUrls[position]); 64             Bitmap bitmap = BitmapFactory.decodeFile(imagePath); 65             if (bitmap == null) { 66                 bitmap = BitmapFactory.decodeResource(getResources(), 67                         R.drawable.empty_photo); 68             } 69             View view = LayoutInflater.from(ImageDetailsActivity.this).inflate( 70                     R.layout.zoom_image_layout, null); 71             ZoomImageView zoomImageView = (ZoomImageView) view 72                     .findViewById(R.id.zoom_image_view); 73             zoomImageView.setImageBitmap(bitmap); 74             container.addView(view); 75             return view; 76         } 77  78         @Override 79         public int getCount() { 80             return Images.imageUrls.length; 81         } 82  83         @Override 84         public boolean isViewFromObject(View arg0, Object arg1) { 85             return arg0 == arg1; 86         } 87  88         @Override 89         public void destroyItem(ViewGroup container, int position, Object object) { 90             View view = (View) object; 91             container.removeView(view); 92         } 93  94     } 95  96     /** 97      * 获取图片的本地存储路径。 98      *  99      * @param imageUrl100      *            图片的URL地址。101      * @return 图片的本地存储路径。102      */103     private String getImagePath(String imageUrl) {104         int lastSlashIndex = imageUrl.lastIndexOf("/");105         String imageName = imageUrl.substring(lastSlashIndex + 1);106         String imageDir = Environment.getExternalStorageDirectory().getPath()107                 + "/pwxceshibao/";108         File file = new File(imageDir);109         if (!file.exists()) {110             file.mkdirs();111         }112         String imagePath = imageDir + imageName;113         return imagePath;114     }115 116     @Override117     public void onPageScrollStateChanged(int arg0) {118 119     }120 121     @Override122     public void onPageScrolled(int arg0, float arg1, int arg2) {123 124     }125 126     @Override127     public void onPageSelected(int currentPage) {128         // 每当页数发生改变时重新设定一遍当前的页数和总页数129         pageText.setText((currentPage + 1) + "/" + Images.imageUrls.length);130     }131 132 }

第二个是图片缩放工具类

1 package com.higgs.mviewpager;  2   3 import android.content.Context;  4 import android.graphics.Bitmap;  5 import android.graphics.Canvas;  6 import android.graphics.Matrix;  7 import android.util.AttributeSet;  8 import android.view.MotionEvent;  9 import android.view.View; 10  11 /** 12  * 自定义的ImageView控制,可对图片进行多点触控缩放和拖动 13  *  14  * @author guolin 15  */ 16 public class ZoomImageView extends View { 17  18     /** 19      * 初始化状态常量 20      */ 21     public static final int STATUS_INIT = 1; 22  23     /** 24      * 图片放大状态常量 25      */ 26     public static final int STATUS_ZOOM_OUT = 2; 27  28     /** 29      * 图片缩小状态常量 30      */ 31     public static final int STATUS_ZOOM_IN = 3; 32  33     /** 34      * 图片拖动状态常量 35      */ 36     public static final int STATUS_MOVE = 4; 37  38     /** 39      * 用于对图片进行移动和缩放变换的矩阵 40      */ 41     private Matrix matrix = new Matrix(); 42  43     /** 44      * 待展示的Bitmap对象 45      */ 46     private Bitmap sourceBitmap; 47  48     /** 49      * 记录当前操作的状态,可选值为STATUS_INIT、STATUS_ZOOM_OUT、STATUS_ZOOM_IN和STATUS_MOVE 50      */ 51     private int currentStatus; 52  53     /** 54      * ZoomImageView控件的宽度 55      */ 56     private int width; 57  58     /** 59      * ZoomImageView控件的高度 60      */ 61     private int height; 62  63     /** 64      * 记录两指同时放在屏幕上时,中心点的横坐标值 65      */ 66     private float centerPointX; 67  68     /** 69      * 记录两指同时放在屏幕上时,中心点的纵坐标值 70      */ 71     private float centerPointY; 72  73     /** 74      * 记录当前图片的宽度,图片被缩放时,这个值会一起变动 75      */ 76     private float currentBitmapWidth; 77  78     /** 79      * 记录当前图片的高度,图片被缩放时,这个值会一起变动 80      */ 81     private float currentBitmapHeight; 82  83     /** 84      * 记录上次手指移动时的横坐标 85      */ 86     private float lastXMove = -1; 87  88     /** 89      * 记录上次手指移动时的纵坐标 90      */ 91     private float lastYMove = -1; 92  93     /** 94      * 记录手指在横坐标方向上的移动距离 95      */ 96     private float movedDistanceX; 97  98     /** 99      * 记录手指在纵坐标方向上的移动距离100      */101     private float movedDistanceY;102 103     /**104      * 记录图片在矩阵上的横向偏移值105      */106     private float totalTranslateX;107 108     /**109      * 记录图片在矩阵上的纵向偏移值110      */111     private float totalTranslateY;112 113     /**114      * 记录图片在矩阵上的总缩放比例115      */116     private float totalRatio;117 118     /**119      * 记录手指移动的距离所造成的缩放比例120      */121     private float scaledRatio;122 123     /**124      * 记录图片初始化时的缩放比例125      */126     private float initRatio;127 128     /**129      * 记录上次两指之间的距离130      */131     private double lastFingerDis;132 133     /**134      * ZoomImageView构造函数,将当前操作状态设为STATUS_INIT。135      * 136      * @param context137      * @param attrs138      */139     public ZoomImageView(Context context, AttributeSet attrs) {140         super(context, attrs);141         currentStatus = STATUS_INIT;142     }143 144     /**145      * 将待展示的图片设置进来。146      * 147      * @param bitmap148      *            待展示的Bitmap对象149      */150     public void setImageBitmap(Bitmap bitmap) {151         sourceBitmap = bitmap;152         invalidate();153     }154 155     @Override156     protected void onLayout(boolean changed, int left, int top, int right,157             int bottom) {158         super.onLayout(changed, left, top, right, bottom);159         if (changed) {160             // 分别获取到ZoomImageView的宽度和高度161             width = getWidth();162             height = getHeight();163         }164     }165 166     @Override167     public boolean onTouchEvent(MotionEvent event) {168         if (initRatio == totalRatio) {169             getParent().requestDisallowInterceptTouchEvent(false);170         } else {171             getParent().requestDisallowInterceptTouchEvent(true);172         }173         switch (event.getActionMasked()) {174         case MotionEvent.ACTION_POINTER_DOWN:175             if (event.getPointerCount() == 2) {176                 // 当有两个手指按在屏幕上时,计算两指之间的距离177                 lastFingerDis = distanceBetweenFingers(event);178             }179             break;180         case MotionEvent.ACTION_CANCEL:181         case MotionEvent.ACTION_MOVE:182             if (event.getPointerCount() == 1) {183                 // 只有单指按在屏幕上移动时,为拖动状态184                 float xMove = event.getX();185                 float yMove = event.getY();186                 if (lastXMove == -1 && lastYMove == -1) {187                     lastXMove = xMove;188                     lastYMove = yMove;189                 }190                 currentStatus = STATUS_MOVE;191                 movedDistanceX = xMove - lastXMove;192                 movedDistanceY = yMove - lastYMove;193                 // 进行边界检查,不允许将图片拖出边界194                 if (totalTranslateX + movedDistanceX > 0) {195                     movedDistanceX = 0;196                 } else if (width - (totalTranslateX + movedDistanceX) > currentBitmapWidth) {197                     movedDistanceX = 0;198                 }199                 if (totalTranslateY + movedDistanceY > 0) {200                     movedDistanceY = 0;201                 } else if (height - (totalTranslateY + movedDistanceY) > currentBitmapHeight) {202                     movedDistanceY = 0;203                 }204                 // 调用onDraw()方法绘制图片205                 invalidate();206                 lastXMove = xMove;207                 lastYMove = yMove;208             } else if (event.getPointerCount() == 2) {209                 // 有两个手指按在屏幕上移动时,为缩放状态210                 centerPointBetweenFingers(event);211                 double fingerDis = distanceBetweenFingers(event);212                 if (fingerDis > lastFingerDis) {213                     currentStatus = STATUS_ZOOM_OUT;214                 } else {215                     currentStatus = STATUS_ZOOM_IN;216                 }217                 // 进行缩放倍数检查,最大只允许将图片放大4倍,最小可以缩小到初始化比例218                 if ((currentStatus == STATUS_ZOOM_OUT && totalRatio < 4 * initRatio)219                         || (currentStatus == STATUS_ZOOM_IN && totalRatio > initRatio)) {220                     scaledRatio = (float) (fingerDis / lastFingerDis);221                     totalRatio = totalRatio * scaledRatio;222                     if (totalRatio > 4 * initRatio) {223                         totalRatio = 4 * initRatio;224                     } else if (totalRatio < initRatio) {225                         totalRatio = initRatio;226                     }227                     // 调用onDraw()方法绘制图片228                     invalidate();229                     lastFingerDis = fingerDis;230                 }231             }232             break;233         case MotionEvent.ACTION_POINTER_UP:234             if (event.getPointerCount() == 2) {235                 // 手指离开屏幕时将临时值还原236                 lastXMove = -1;237                 lastYMove = -1;238             }239             break;240         case MotionEvent.ACTION_UP:241             // 手指离开屏幕时将临时值还原242             lastXMove = -1;243             lastYMove = -1;244             break;245         default:246             break;247         }248         return true;249     }250 251     /**252      * 根据currentStatus的值来决定对图片进行什么样的绘制操作。253      */254     @Override255     protected void onDraw(Canvas canvas) {256         super.onDraw(canvas);257         switch (currentStatus) {258         case STATUS_ZOOM_OUT:259         case STATUS_ZOOM_IN:260             zoom(canvas);261             break;262         case STATUS_MOVE:263             move(canvas);264             break;265         case STATUS_INIT:266             initBitmap(canvas);267         default:268             if (sourceBitmap != null) {269                 canvas.drawBitmap(sourceBitmap, matrix, null);270             }271             break;272         }273     }274 275     /**276      * 对图片进行缩放处理。277      * 278      * @param canvas279      */280     private void zoom(Canvas canvas) {281         matrix.reset();282         // 将图片按总缩放比例进行缩放283         matrix.postScale(totalRatio, totalRatio);284         float scaledWidth = sourceBitmap.getWidth() * totalRatio;285         float scaledHeight = sourceBitmap.getHeight() * totalRatio;286         float translateX = 0f;287         float translateY = 0f;288         // 如果当前图片宽度小于屏幕宽度,则按屏幕中心的横坐标进行水平缩放。否则按两指的中心点的横坐标进行水平缩放289         if (currentBitmapWidth < width) {290             translateX = (width - scaledWidth) / 2f;291         } else {292             translateX = totalTranslateX * scaledRatio + centerPointX293                     * (1 - scaledRatio);294             // 进行边界检查,保证图片缩放后在水平方向上不会偏移出屏幕295             if (translateX > 0) {296                 translateX = 0;297             } else if (width - translateX > scaledWidth) {298                 translateX = width - scaledWidth;299             }300         }301         // 如果当前图片高度小于屏幕高度,则按屏幕中心的纵坐标进行垂直缩放。否则按两指的中心点的纵坐标进行垂直缩放302         if (currentBitmapHeight < height) {303             translateY = (height - scaledHeight) / 2f;304         } else {305             translateY = totalTranslateY * scaledRatio + centerPointY306                     * (1 - scaledRatio);307             // 进行边界检查,保证图片缩放后在垂直方向上不会偏移出屏幕308             if (translateY > 0) {309                 translateY = 0;310             } else if (height - translateY > scaledHeight) {311                 translateY = height - scaledHeight;312             }313         }314         // 缩放后对图片进行偏移,以保证缩放后中心点位置不变315         matrix.postTranslate(translateX, translateY);316         totalTranslateX = translateX;317         totalTranslateY = translateY;318         currentBitmapWidth = scaledWidth;319         currentBitmapHeight = scaledHeight;320         canvas.drawBitmap(sourceBitmap, matrix, null);321     }322 323     /**324      * 对图片进行平移处理325      * 326      * @param canvas327      */328     private void move(Canvas canvas) {329         matrix.reset();330         // 根据手指移动的距离计算出总偏移值331         float translateX = totalTranslateX + movedDistanceX;332         float translateY = totalTranslateY + movedDistanceY;333         // 先按照已有的缩放比例对图片进行缩放334         matrix.postScale(totalRatio, totalRatio);335         // 再根据移动距离进行偏移336         matrix.postTranslate(translateX, translateY);337         totalTranslateX = translateX;338         totalTranslateY = translateY;339         canvas.drawBitmap(sourceBitmap, matrix, null);340     }341 342     /**343      * 对图片进行初始化操作,包括让图片居中,以及当图片大于屏幕宽高时对图片进行压缩。344      * 345      * @param canvas346      */347     private void initBitmap(Canvas canvas) {348         if (sourceBitmap != null) {349             matrix.reset();350             int bitmapWidth = sourceBitmap.getWidth();351             int bitmapHeight = sourceBitmap.getHeight();352             if (bitmapWidth > width || bitmapHeight > height) {353                 if (bitmapWidth - width > bitmapHeight - height) {354                     // 当图片宽度大于屏幕宽度时,将图片等比例压缩,使它可以完全显示出来355                     float ratio = width / (bitmapWidth * 1.0f);356                     matrix.postScale(ratio, ratio);357                     float translateY = (height - (bitmapHeight * ratio)) / 2f;358                     // 在纵坐标方向上进行偏移,以保证图片居中显示359                     matrix.postTranslate(0, translateY);360                     totalTranslateY = translateY;361                     totalRatio = initRatio = ratio;362                 } else {363                     // 当图片高度大于屏幕高度时,将图片等比例压缩,使它可以完全显示出来364                     float ratio = height / (bitmapHeight * 1.0f);365                     matrix.postScale(ratio, ratio);366                     float translateX = (width - (bitmapWidth * ratio)) / 2f;367                     // 在横坐标方向上进行偏移,以保证图片居中显示368                     matrix.postTranslate(translateX, 0);369                     totalTranslateX = translateX;370                     totalRatio = initRatio = ratio;371                 }372                 currentBitmapWidth = bitmapWidth * initRatio;373                 currentBitmapHeight = bitmapHeight * initRatio;374             } else {375                 // 当图片的宽高都小于屏幕宽高时,直接让图片居中显示376                 float translateX = (width - sourceBitmap.getWidth()) / 2f;377                 float translateY = (height - sourceBitmap.getHeight()) / 2f;378                 matrix.postTranslate(translateX, translateY);379                 totalTranslateX = translateX;380                 totalTranslateY = translateY;381                 totalRatio = initRatio = 1f;382                 currentBitmapWidth = bitmapWidth;383                 currentBitmapHeight = bitmapHeight;384             }385             canvas.drawBitmap(sourceBitmap, matrix, null);386         }387     }388 389     /**390      * 计算两个手指之间的距离。391      * 392      * @param event393      * @return 两个手指之间的距离394      */395     private double distanceBetweenFingers(MotionEvent event) {396         float disX = Math.abs(event.getX(0) - event.getX(1));397         float disY = Math.abs(event.getY(0) - event.getY(1));398         return Math.sqrt(disX * disX + disY * disY);399     }400 401     /**402      * 计算两个手指之间中心点的坐标。403      * 404      * @param event405      */406     private void centerPointBetweenFingers(MotionEvent event) {407         float xPoint0 = event.getX(0);408         float yPoint0 = event.getY(0);409         float xPoint1 = event.getX(1);410         float yPoint1 = event.getY(1);411         centerPointX = (xPoint0 + xPoint1) / 2;412         centerPointY = (yPoint0 + yPoint1) / 2;413     }414 415 }

最后一个是图片管理工具类  也是缓存核心类   这个就是上面提到的防止加载过多的图片时产生OOM

1 package com.higgs.mviewpager;  2   3 import android.graphics.Bitmap;  4 import android.graphics.BitmapFactory;  5 import android.util.LruCache;  6   7 /**  8  * 对图片进行管理的工具类。  9  *  10  * @author Tony 11  */ 12 public class ImageLoader { 13  14     /** 15      * 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。 16      */ 17     private static LruCache
mMemoryCache; 18 19 /** 20 * ImageLoader的实例。 21 */ 22 private static ImageLoader mImageLoader; 23 24 private ImageLoader() { 25 // 获取应用程序最大可用内存 26 int maxMemory = (int) Runtime.getRuntime().maxMemory(); 27 int cacheSize = maxMemory / 8; 28 // 设置图片缓存大小为程序最大可用内存的1/8 29 mMemoryCache = new LruCache
(cacheSize) { 30 @Override 31 protected int sizeOf(String key, Bitmap bitmap) { 32 return bitmap.getByteCount(); 33 } 34 }; 35 } 36 37 /** 38 * 获取ImageLoader的实例。 39 * 40 * @return ImageLoader的实例。 41 */ 42 public static ImageLoader getInstance() { 43 if (mImageLoader == null) { 44 mImageLoader = new ImageLoader(); 45 } 46 return mImageLoader; 47 } 48 49 /** 50 * 将一张图片存储到LruCache中。 51 * 52 * @param key 53 * LruCache的键,这里传入图片的URL地址。 54 * @param bitmap 55 * LruCache的键,这里传入从网络上下载的Bitmap对象。 56 */ 57 public void addBitmapToMemoryCache(String key, Bitmap bitmap) { 58 if (getBitmapFromMemoryCache(key) == null) { 59 mMemoryCache.put(key, bitmap); 60 } 61 } 62 63 /** 64 * 从LruCache中获取一张图片,如果不存在就返回null。 65 * 66 * @param key 67 * LruCache的键,这里传入图片的URL地址。 68 * @return 对应传入键的Bitmap对象,或者null。 69 */ 70 public Bitmap getBitmapFromMemoryCache(String key) { 71 return mMemoryCache.get(key); 72 } 73 74 public static int calculateInSampleSize(BitmapFactory.Options options, 75 int reqWidth) { 76 // 源图片的宽度 77 final int width = options.outWidth; 78 int inSampleSize = 1; 79 if (width > reqWidth) { 80 // 计算出实际宽度和目标宽度的比率 81 final int widthRatio = Math.round((float) width / (float) reqWidth); 82 inSampleSize = widthRatio; 83 } 84 return inSampleSize; 85 } 86 87 public static Bitmap decodeSampledBitmapFromResource(String pathName, 88 int reqWidth) { 89 // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小 90 final BitmapFactory.Options options = new BitmapFactory.Options(); 91 options.inJustDecodeBounds = true; 92 BitmapFactory.decodeFile(pathName, options); 93 // 调用上面定义的方法计算inSampleSize值 94 options.inSampleSize = calculateInSampleSize(options, reqWidth); 95 // 使用获取到的inSampleSize值再次解析图片 96 options.inJustDecodeBounds = false; 97 return BitmapFactory.decodeFile(pathName, options); 98 } 99 100 }

 

 

 

好了  大家照着自己做做就可以出来效果了,因为我已经把全部的源码贴出来了,如果你懒得连代码都不想敲。我觉得此文章对你没有什么作用。只有自己敲了就理解了

第一次写博客,感觉思路很乱,很多都没有讲明白。一个是时间不够,二是关键点都有注释,代码都贴上来了。共勉~~~~

转载于:https://www.cnblogs.com/anypwx/p/4711491.html

你可能感兴趣的文章
Python内置函数(29)——help
查看>>
【题解】[P4178 Tree]
查看>>
QML学习笔记之一
查看>>
WPF中实现多选ComboBox控件
查看>>
ionic2+ 基础
查看>>
GDOI DAY1游记
查看>>
MyBaits动态sql语句
查看>>
拉格朗日乘子法 那些年学过的高数
查看>>
vs code 的便捷使用
查看>>
用户空间与内核空间,进程上下文与中断上下文[总结]
查看>>
JAVA开发环境搭建
查看>>
Visual Studio基于CMake配置opencv1.0.0、opencv2.2
查看>>
SDN第四次作业
查看>>
django迁移数据库错误
查看>>
Data truncation: Out of range value for column 'Quality' at row 1
查看>>
字符串处理
查看>>
HtmlUnitDriver 网页内容动态抓取
查看>>
ad logon hour
查看>>
罗马数字与阿拉伯数字转换
查看>>
Eclipse 反编译之 JadClipse
查看>>