使用photoview+viewpager实现图片缩放切换(类似微信朋友圈图片查看)

本文主要是介绍使用photoview+viewpager实现图片缩放切换(类似微信朋友圈图片查看),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先看一下最终效果


经过分析可知,整个页面布局应该是一个Listview,它的每一个条目item中包含原型头像(采用CircleImageVIew)一个数目可变的GridView和其他,Gridview不可滚动,图片查看可缩放使用photoview,图片切换使用viewpager,思路清晰之后,开始写。。。

导入依赖库:

compile 'com.google.code.gson:gson:2.2.4'
compile files('libs/circleimageview.jar')
compile files('libs/universal-image-loader-1.9.1.jar')

导入photoview源码https://github.com/chrisbanes/PhotoView

初始化ImageLoader

public class MyApplication extends Application {@Override
   public void onCreate() {super.onCreate();
      DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.empty_photo) .showImageOnFail(R.drawable.empty_photo) .cacheInMemory(true).cacheOnDisc(true).build();
      ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).defaultDisplayImageOptions(defaultOptions).discCacheSize(50 * 1024 * 1024)//
            .discCacheFileCount(100)//缓存一百张图片
            .writeDebugLogs().build();
      ImageLoader.getInstance().init(config);
   }
}
清单文件中修改


1.MainActivity

public class MainActivity extends ListActivity {public static final String TAG = "MainActivity";
   private ListAdapter mAdapter;

   @Override
   public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      //开启异步任务去模拟获取数据
      new LoderDataTask().execute();

   }class LoderDataTask extends AsyncTask<Void, Void, MessageModle> {@Override
      protected MessageModle doInBackground(Void... params) {Gson gson = new Gson();

         MessageModle msg = gson.fromJson(getData(), MessageModle.class);
         return msg;
      }@Override
      protected void onPostExecute(MessageModle result) {mAdapter = new ListAdapter(MainActivity.this, result.list);
         setListAdapter(mAdapter);

      }}private String getData() {// 模拟网络获取数据
      String json = "{\"code\":200,\"msg\":\"ok\",list:["
            + "{\"id\":110,\"avator\":\"http://img0.bdstatic.com/img/image/shouye/leimu/mingxing.jpg\",\"name\":\"赵薇\",\"content\":\"今天不开心!\",\"urls\":[]},"
            + "{\"id\":111,\"avator\":\"http://image.cnwest.com/attachement/jpg/site1/20110507/001372d8a36f0f2f4c953a.jpg\",\"name\":\"李晨\",\"content\":\"我们\","
            + "  \"urls\":[\"http://guangdong.sinaimg.cn/2015/0530/U11307P693DT20150530094310.jpg\"]},"

            + "{\"id\":114,\"avator\":\"http://img.hexun.com/2009-05-01/117287830.jpg\",\"name\":\"小马哥\",\"content\":\"今天淘宝了吗\",\"urls\":["
            + "\"http://g.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=ccd33b46d53f8794d7ff4b26e2207fc9/0d338744ebf81a4c0f993437d62a6059242da6a1.jpg\","
            
            + "\"http://f.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=6b62f61bac6eddc422e7b7f309e0c7c0/6159252dd42a2834510deef55ab5c9ea14cebfa1.jpg\","
            + "\"http://g.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=e58fb67bc8ea15ce45eee301863b4bce/a5c27d1ed21b0ef4fd6140a0dcc451da80cb3e47.jpg\","
            + "\"http://c.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=cdab1512d000baa1be2c44b3772bc82f/91529822720e0cf3855c96050b46f21fbf09aaa1.jpg\"]},"
            
            + "{\"id\":112,\"avator\":\"http://img3.yxlady.com/yl/UploadFiles_5361/20150528/20150528050208705.jpg\",\"name\":\"邓超\",\"content\":\"奔跑吧兄弟! 欢迎收看!\",\"urls\":[\"http://upload.cbg.cn/2015/0305/1425518659246.jpg\","
            + "\"http://www.people.com.cn/mediafile/pic/20150619/30/4179219540177204330.jpg\"]},"
            
            + "{\"id\":113,\"avator\":\"http://img4.imgtn.bdimg.com/it/u=945108765,1070109457&fm=21&gp=0.jpg\",\"name\":\"奥巴马\",\"content\":\"holle\",\"urls\":[\"http://f.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=6b62f61bac6eddc422e7b7f309e0c7c0/6159252dd42a2834510deef55ab5c9ea14cebfa1.jpg\",\"http://g.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=e58fb67bc8ea15ce45eee301863b4bce/a5c27d1ed21b0ef4fd6140a0dcc451da80cb3e47.jpg\",\"http://c.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=cdab1512d000baa1be2c44b3772bc82f/91529822720e0cf3855c96050b46f21fbf09aaa1.jpg\"]}]}";

      return json;
   }
}

bean类

public class MessageModle {public int code;
   public String msg;
   
   public ArrayList<InfoBean> list;

   @Override
   public String toString() {return "MyMessage [code=" + code + ", msg=" + msg + ", list=" + list + "]";
   }}
public class InfoBean {public int id;
   public String avator;
   public String name;
   public String content;
   public String time;
   public String[] urls;

   

}
布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="6dp" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@android:id/empty"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="暂无数据" />

</RelativeLayout>

2.ListAdapter

public class ListAdapter extends BaseAdapter{private ArrayList<InfoBean> mList;
   private LayoutInflater mInflater;
   private Context mContext;
   
   public ListAdapter(Context context, ArrayList<InfoBean> list) {mInflater = LayoutInflater.from(context);
      mContext=context;
      this.mList=list;
   }@Override
   public int getCount() {return mList==null?0:mList.size();
   }@Override
   public InfoBean getItem(int position) {return mList.get(position);
   }@Override
   public long getItemId(int position) {return getItem(position).id;
   }@Override
   public View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;
      if (convertView == null) {holder = new ViewHolder();
         convertView = mInflater.inflate(R.layout.list_item, null);
         holder.avator=(ImageView)convertView.findViewById(R.id.avator);
         holder.name=(TextView)convertView.findViewById(R.id.name);
         holder.content = (TextView) convertView.findViewById(R.id.content);
         holder.gridView=(NoScrollGridView)convertView.findViewById(R.id.gridView);
         convertView.setTag(holder);
      } else {holder = (ViewHolder) convertView.getTag();
      }final InfoBean bean = getItem(position);
      //加载网络图片
      ImageLoader.getInstance().displayImage(bean.avator, holder.avator);
      holder.name.setText(bean.name);
      holder.content.setText(bean.content);
      if(bean.urls!=null&&bean.urls.length>0){holder.gridView.setVisibility(View.VISIBLE);
         holder.gridView.setAdapter(new DynamicGridAdapter(bean.urls, mContext));
         holder.gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {imageBrower(position,bean.urls);
            }});
      }else{holder.gridView.setVisibility(View.GONE);
      }return convertView;
   }private void imageBrower(int position, String[] urls) {Intent intent = new Intent(mContext, ImagePagerActivity.class);
      // 图片url,为了演示这里使用常量,一般从数据库中或网络中获取
      intent.putExtra(ImagePagerActivity.EXTRA_IMAGE_URLS, urls);
      intent.putExtra(ImagePagerActivity.EXTRA_IMAGE_INDEX, position);
      mContext.startActivity(intent);
   }// 优化listview
   private static class ViewHolder {public TextView name;
      public ImageView avator;
      TextView content;
      NoScrollGridView gridView;
   }
}

DynamicGridAdapter

public class DynamicGridAdapter extends BaseAdapter {private String[] files;

   private LayoutInflater mLayoutInflater;

   public DynamicGridAdapter(String[] files, Context context) {this.files = files;
      mLayoutInflater = LayoutInflater.from(context);
   }@Override
   public int getCount() {return files == null ? 0 : files.length;
   }@Override
   public String getItem(int position) {return files[position];
   }@Override
   public long getItemId(int position) {return position;
   }@Override
   public View getView(int position, View convertView, ViewGroup parent) {MyGridViewHolder viewHolder;
      if (convertView == null) {viewHolder = new MyGridViewHolder();
         convertView = mLayoutInflater.inflate(R.layout.gridview_item,
               parent, false);
         
         viewHolder.imageView = (ImageView) convertView.findViewById(R.id.album_image);
         convertView.setTag(viewHolder);
      } else {viewHolder = (MyGridViewHolder) convertView.getTag();
      }String url = getItem(position);
      if (getCount() == 1) {viewHolder.imageView.setLayoutParams(new android.widget.AbsListView.LayoutParams(300, 250));
      }if (getCount() == 2 ||getCount() == 4) {viewHolder.imageView.setLayoutParams(new android.widget.AbsListView.LayoutParams(200, 200));
      }ImageLoader.getInstance().displayImage(url, viewHolder.imageView);

      return convertView;
   }private static class MyGridViewHolder {ImageView imageView;
   }
}

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="6dp" >

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/avator"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/empty_photo" />

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@id/avator"
        android:textColor="#576B95"
        android:textSize="16sp"
        android:text="name" />

    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/name"
        android:layout_marginLeft="10dp"
        android:textSize="12sp"
        android:layout_toRightOf="@id/avator"
        android:text="content" />

    <com.xxx.demo.image.NoScrollGridView
        
        android:id="@+id/gridView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:layout_below="@id/content"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@id/avator"
        android:horizontalSpacing="1dp"
        android:numColumns="3"
        
        android:visibility="gone"
        android:verticalSpacing="1dp" />

</RelativeLayout>

3.自定义无滚动的GridView

public class NoScrollGridView extends GridView {public NoScrollGridView(Context context) {super(context);
   }public NoScrollGridView(Context context, AttributeSet attrs) {super(context, attrs);
   }@Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int  expandSpec = 0;
       int  size = getAdapter().getCount();
       
      if (size == 1) {setNumColumns(1);
      } if ( size==2 || size == 4  ) {setNumColumns(2);
      }else {setNumColumns(3);
      }expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
      super.onMeasure(widthMeasureSpec,expandSpec);
   }}

4.图片查看Activiy

public class ImagePagerActivity extends FragmentActivity {private static final String STATE_POSITION = "STATE_POSITION";
   public static final String EXTRA_IMAGE_INDEX = "image_index";
   public static final String EXTRA_IMAGE_URLS = "image_urls";

   private HackyViewPager mPager;
   private int pagerPosition;
   private TextView indicator;

   @Override
   public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
      setContentView(R.layout.image_detail_pager);

      pagerPosition = getIntent().getIntExtra(EXTRA_IMAGE_INDEX, 0);
      String[] urls = getIntent().getStringArrayExtra(EXTRA_IMAGE_URLS);


      mPager = (HackyViewPager) findViewById(R.id.pager);
      ImagePagerAdapter mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), urls);
      mPager.setAdapter(mAdapter);
      indicator = (TextView) findViewById(R.id.indicator);

      CharSequence text = getString(R.string.viewpager_indicator, 1, mPager
            .getAdapter().getCount());
      indicator.setText(text);
      // 更新下标
      mPager.setOnPageChangeListener(new OnPageChangeListener() {@Override
         public void onPageScrollStateChanged(int arg0) {}@Override
         public void onPageScrolled(int arg0, float arg1, int arg2) {}@Override
         public void onPageSelected(int arg0) {CharSequence text = getString(R.string.viewpager_indicator,
                  arg0 + 1, mPager.getAdapter().getCount());
            indicator.setText(text);
         }});
      if (savedInstanceState != null) {pagerPosition = savedInstanceState.getInt(STATE_POSITION);
      }mPager.setCurrentItem(pagerPosition);
   }@Override
   public void onSaveInstanceState(Bundle outState) {outState.putInt(STATE_POSITION, mPager.getCurrentItem());
   }private class ImagePagerAdapter extends FragmentStatePagerAdapter {public String[] fileList;

      public ImagePagerAdapter(FragmentManager fm, String[] fileList) {super(fm);
         this.fileList = fileList;
      }@Override
      public int getCount() {return fileList == null ? 0 : fileList.length;
      }@Override
      public Fragment getItem(int position) {String url = fileList[position];
         return ImageDetailFragment.newInstance(url);
      }}
}

viewpager

public class HackyViewPager extends ViewPager {private static final String TAG = "HackyViewPager";

   public HackyViewPager(Context context) {super(context);
   }public HackyViewPager(Context context, AttributeSet attrs) {super(context, attrs);
   }@Override
   public boolean onInterceptTouchEvent(MotionEvent ev) {try {return super.onInterceptTouchEvent(ev);
      } catch (IllegalArgumentException e) {return false;
      }catch(ArrayIndexOutOfBoundsException e ){return false;
      }}}
布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.xxx.demo.image.HackyViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/black" />

    <TextView
        android:id="@+id/indicator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:gravity="center"
        android:textSize="18sp"
        android:textColor="@android:color/white"
        android:text="@string/viewpager_indicator"
        android:background="@android:color/transparent" />

</FrameLayout>

5.图片显示Fragment

public class ImageDetailFragment extends Fragment {private String mImageUrl;
   private ImageView mImageView;
   private ProgressBar progressBar;
   private PhotoViewAttacher mAttacher;

   public static ImageDetailFragment newInstance(String imageUrl) {final ImageDetailFragment f = new ImageDetailFragment();

      final Bundle args = new Bundle();
      args.putString("url", imageUrl);
      f.setArguments(args);

      return f;
   }@Override
   public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
      mImageUrl = getArguments() != null ? getArguments().getString("url") : null;

   }@Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
      mImageView = (ImageView) v.findViewById(R.id.image);
      mAttacher = new PhotoViewAttacher(mImageView);
      
      mAttacher.setOnPhotoTapListener(new OnPhotoTapListener() {//点击图片关闭当前activiy
         @Override
         public void onPhotoTap(View arg0, float arg1, float arg2) {getActivity().finish();
         }});
      
      progressBar = (ProgressBar) v.findViewById(R.id.loading);
      return v;
   }@Override
   public void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);
      
      
      ImageLoader.getInstance().displayImage(mImageUrl, mImageView, new SimpleImageLoadingListener() {@Override
         public void onLoadingStarted(String imageUri, View view) {progressBar.setVisibility(View.VISIBLE);
         }@Override
         public void onLoadingFailed(String imageUri, View view, FailReason failReason) {String message = null;
            switch (failReason.getType()) {case IO_ERROR:message = "下载错误";
               break;
            case DECODING_ERROR:message = "图片无法显示";
               break;
            case NETWORK_DENIED:message = "网络有问题,无法下载";
               break;
            case OUT_OF_MEMORY:message = "图片太大无法显示";
               break;
            case UNKNOWN:message = "未知的错误";
               break;
            }Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
            progressBar.setVisibility(View.GONE);
         }@Override
         public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {progressBar.setVisibility(View.GONE);
            mAttacher.update();
         }});
      
   }}
布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="@color/black"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:contentDescription="@string/app_name"
        android:scaleType="centerCrop" />

    <ProgressBar
        android:id="@+id/loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone" />

</FrameLayout>

这篇关于使用photoview+viewpager实现图片缩放切换(类似微信朋友圈图片查看)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/872017

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time