Gallery + ViewPager实现图片浏览器
来源:互联网 发布:手机mac地址伪装 编辑:程序博客网 时间:2024/05/21 09:09
相信很多人在开发中都有做过图片浏览或者是预览的功能,但我想大多数人会和我一样,百度一下仿微信发说说,然后下载个demo,直接把demo拷到自己的代码进行一些简单的修改,完成该有的效果就ok了,从不去仔细的去看别人的代码。再随着越来越多开源框架的出来,我们已习惯了用别人的东西,渐渐的忘记了怎么去写。浑浑噩噩过了这么长时间了,反省了,我也想自己写点东西了,向csdn大神学习。本文参考http://blog.csdn.net/lmj623565791/article/details/39480503 鸿洋大神的博客,谢谢;先分析一下图片预览功能,能够切换并显示图片,对选中的图片进行缩放处理。首先来第一步:对图片进行切换和浏览上代码布局文件:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" ></android.support.v4.view.ViewPager> <Gallery android:id="@+id/gallery" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:unselectedAlpha="0.6" android:spacing="10dp" ></Gallery></LinearLayout>然后是代码,很简单,就是分别给gallery和viewpager设置设配器,然后两者中有一个改变时,切换另一个的=显示条目;package com.hpl.demo_application;import android.app.Activity;import android.os.Bundle;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.Gallery;import android.widget.ImageView;import java.util.ArrayList;/** * Created by 79115 on 2016/12/1. */public class TestActivity extends Activity { private int[] images = {R.drawable.icon_001, R.drawable.icon_002, R.drawable.icon_003, R.drawable.icon_004, R.drawable.icon_005, R.drawable.icon_006}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test); final Gallery gallery = (Gallery) findViewById(R.id.gallery); final ViewPager viewpager = (ViewPager) findViewById(R.id.viewpager); final ArrayList<View> views = new ArrayList<View>(); gallery.setAdapter(new BaseAdapter() { @Override public int getCount() { return images.length; } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ImageView imageView = new ImageView(TestActivity.this); imageView.setScaleType(ImageView.ScaleType.FIT_XY); imageView.setLayoutParams(new Gallery.LayoutParams(100, 75)); imageView.setImageResource(images[i % images.length]); return imageView; } }); viewpager.setAdapter(new PagerAdapter() { @Override public int getCount() { return images.length; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = new ImageView(TestActivity.this); imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); imageView.setImageResource(images[position % images.length]); views.add(imageView); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(views.get(position)); } }); viewpager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { int selectedItemPosition = gallery.getSelectedItemPosition(); if(position != selectedItemPosition) gallery.setSelection(position); } @Override public void onPageScrollStateChanged(int state) { } }); gallery.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { int currentItem = viewpager.getCurrentItem(); if(i != currentItem) viewpager.setCurrentItem(i); } @Override public void onNothingSelected(AdapterView<?> adapterView) { } }); }然后,自定义一个ZoomImageView,继承ImageView,直接上代码了,代码里注释的挺详细package com.hpl.demo_application;import android.annotation.TargetApi;import android.content.Context;import android.graphics.Matrix;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.os.Build;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.ScaleGestureDetector;import android.view.View;import android.view.ViewTreeObserver;import android.widget.ImageView;/** * 可缩放ImageView * Created by 79115 on 2016/12/1. */public class ZoomImageView2 extends ImageView implements ScaleGestureDetector.OnScaleGestureListener, View.OnTouchListener, ViewTreeObserver.OnGlobalLayoutListener { private final ScaleGestureDetector scaleGestureDetector; private Matrix scaleMatrix = new Matrix(); private final float MAX_SCALE = 4.0f; private float initScale = 1.0f; private final float[] values = new float[9]; private boolean once = true; public ZoomImageView2(Context context) { this(context, null); } public ZoomImageView2(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ZoomImageView2(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //设置图片的缩放模式为矩形显示 setScaleType(ScaleType.MATRIX); //创建ScaleGestureDetector实例 scaleGestureDetector = new ScaleGestureDetector(context, this); //设置图片的触摸监听 this.setOnTouchListener(this); } @Override public boolean onScale(ScaleGestureDetector scaleGestureDetector) { //此次放大的倍数 float scaleFactor = scaleGestureDetector.getScaleFactor(); //已经放大到的倍数 float scale = getScale(); if(getDrawable() == null){ return true; } if((scale < MAX_SCALE && scaleFactor > 1.0f) //小于最大放大倍数并且放大 || (scale > initScale && scaleFactor < 1.0f)){ //大于最小倍数并且缩小 //放大后超过放大倍数,做处理 if(scale * scaleFactor > MAX_SCALE){ scaleFactor = MAX_SCALE / scale; } if(scale * scaleFactor < initScale){ scaleFactor = initScale / scale; } //以缩放手势的中心点缩放 scaleMatrix.postScale(scaleFactor, scaleFactor, scaleGestureDetector.getFocusX(), scaleGestureDetector.getFocusY()); //检查边缘,当图片边缘放大后再缩小会仅有一部分显示在屏幕上,这时候需要将图片移到屏幕的中间来; checkBorder(); setImageMatrix(scaleMatrix); } return true; } private void checkBorder() { Matrix matrix = this.scaleMatrix; RectF rectF = new RectF(); float dx = 0, dy = 0; if(getDrawable() != null){ //设置范围 rectF.set(0, 0 ,getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight()); matrix.mapRect(rectF);if(rectF.width() > getWidth()){ if (rectF.left > 0) { dx = -rectF.left; } if (rectF.right < getWidth()) { dx = getWidth() - rectF.right; }}if (rectF.height() >= getHeight()) { if (rectF.top > 0) { dy = -rectF.top; } if (rectF.bottom < getHeight()) { dy = getHeight() - rectF.bottom; }}// 如果宽或高小于屏幕,则让其居中 if (rectF.width() < getWidth()) { dx = -((rectF.right + rectF.left) / 2) + getWidth() / 2; } if (rectF.height() < getHeight()) { dy = -((rectF.top + rectF.bottom) / 2) + getHeight() / 2; } scaleMatrix.postTranslate(dx, dy); } } private float getScale() { scaleMatrix.getValues(values); return values[Matrix.MSCALE_X]; } @Override public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) { return true; } @Override public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) { } @Override public boolean onTouch(View view, MotionEvent motionEvent) { //将触摸事件交给scaleGestureDetector处理 return scaleGestureDetector.onTouchEvent(motionEvent); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnGlobalLayoutListener(this); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getViewTreeObserver().removeOnGlobalLayoutListener(this); } @Override public void onGlobalLayout() { if(once){ Drawable drawable = getDrawable(); if(drawable != null){ //获取控件的宽高 int width = getWidth(); int height = getHeight(); //获取图片的宽高 int dw = drawable.getIntrinsicWidth(); int dh = drawable.getIntrinsicHeight(); //如果图片的宽大于控件的宽,改变初始的缩放比例 if(dw > width && dh <= height){ initScale = width * 1.0f / dw; } //如果图片的高大于控件的高,改变初始的缩放比例 if(dh > height && dw <= width){ initScale = height * 1.0f / dh; } //如果图片的宽高都大于控件的宽高,则取其中比例小的,这样才能将图片显示完全 if(dh > height && dw > width){ initScale = Math.min((width * 1.0f) / dw, (height * 1.0f) / dh); } //将图片移到屏幕中间 scaleMatrix.postTranslate((width - dw) / 2, (height - dh) / 2); //按初始比例以控件中心为原点缩放图片 scaleMatrix.postScale(initScale, initScale, width / 2, height / 2); setImageMatrix(scaleMatrix); } once = false; } }}将ViewPager构造器里的ImageView替换一下, 效果图如下,截图工具搞了老久,随便截取一下就挺大的,只能草草了事可以看到这样来我们的图片已经有可缩放能力,但不能够拖动下面我们开始做屏幕的拖动@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) { //将触摸事件交给scaleGestureDetector处理 scaleGestureDetector.onTouchEvent(motionEvent); if(getDrawable() == null){ return true; } switch (motionEvent.getAction()){ case MotionEvent.ACTION_DOWN: startX = motionEvent.getX(); startY = motionEvent.getY(); break; case MotionEvent.ACTION_MOVE: float x = motionEvent.getX(); float y = motionEvent.getY(); float dx = x - startX; float dy = y - startY; scaleMatrix.postTranslate(dx, dy); checkBorder(); setImageMatrix(scaleMatrix); startX = x; startY = y; break; case MotionEvent.ACTION_UP: break; } return true;}这里整个图片浏览器基本上算是完成了,但是还得解决一个冲突问题,那就是viewpager的滑动事件和图片的拖动事件的冲突。大家微信什么的用的应该不少,可以发现多数图片预览器是只有当你的图片小于屏幕的时候你才能左右的切换屏幕,所以我们可以在onTouch里面加上这样的判断;Matrix matrix = this.scaleMatrix;RectF rectF = new RectF(); //设置范围rectF.set(0, 0 ,getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight()); if(rectF.width() > getWidth() || rectF.height() > getHeight()){ //请求父类不拦截事件 getParent().requestDisallowInterceptTouchEvent(true);}这样冲突就解决了,下面来波福利好险,差点超过2M了
0 0
- Gallery + ViewPager实现图片浏览器
- 利用Gallery和ImageView实现图片浏览器
- Gallery实现幻灯片式的图片浏览器
- ViewPager实现Gallery效果
- 使用ViewPager实现gallery
- 图片浏览器。。Gallery
- 自定义Gallery控件实现简单3D图片浏览器
- Gallery实现ViewPager的页面切换效果、以及实现图片画廊效果
- 使用Gallery实现缩略图浏览器
- Android 使用ViewPager实现类似gallery画廊的效果(画廊效果之ViewPager显示多个图片)
- 【转】Android 使用ViewPager实现类似gallery画廊的效果(画廊效果之ViewPager显示多个图片)
- android ViewPager 替代 Gallery 实现手势切换
- android viewpager 无限循环实现gallery 效果
- 基于ViewPager实现Gallery画廊效果
- 利用ViewPager实现画廊Gallery效果
- 基于 Viewpager,实现了 Gallery 效果
- ViewPager+TimerTask实现Gallery画廊效果
- 【Android界面实现】自定义Gallery控件实现简单3D图片浏览器
- Jconsole与Jmx 分析JVM状况(下)
- firefox 安装Selenium IDE
- 过滤器的核心API、对指定的请求拦截
- mac 上安装redis
- 关于jQuery中isNumeric 方法判断数字的深刻理解
- Gallery + ViewPager实现图片浏览器
- android面试题
- volatile与synchronized
- ogre 引擎 框架追踪 第六章 渲染流程
- opencv环境搭建(linux)
- [leetcode] 421. Maximum XOR of Two Numbers in an Array 解题报告
- Android开发人员不得不收集的代码
- 第4章 Spring MVC基础
- web安全————XSS(预防篇)