微信发送图片有个功能,就是当你拍完照片,或者保存一个张照片的时候,你点击聊天框的“+”号,微信会有个提示,你可能要发送的图片,并且附上相应的图片。要实现这个功能,分两个步骤。

1,取数据,就是从多媒体库里取出最近的图片。

2,展示,把这张图片展示出来,其实就是做一个popWindow

下图展示我做的Demo:从今日头条随便保存了一张图片

下面我们就分两步走来一步一步实现这个功能:

1,从多媒体库中取出最近要使用的图片

先封装一个图片类 ImageItem:
public class ImageItem implements Serializable {public String name;       //图片的名字public String path;       //图片的路径public long size;         //图片的大小public int width;         //图片的宽度public int height;        //图片的高度public String mimeType;   //图片的类型public long addTime;      //图片的创建时间/** 图片的路径和创建时间相同就认为是同一张图片 */@Overridepublic boolean equals(Object o) {if (o instanceof ImageItem) {ImageItem item = (ImageItem) o;return this.path.equalsIgnoreCase(item.path) && this.addTime == item.addTime;}return super.equals(o);}
}

这里最主要的字段是path 和addTime。

再者实现自己的LoaderCallbacks:ImageDataSource
public class ImageDataSource implements LoaderManager.LoaderCallbacks<Cursor> {public static final int LOADER_ALL = 0;         //加载所有图片public static final int LOADER_CATEGORY = 1;    //分类加载图片private final String[] IMAGE_PROJECTION = {     //查询图片需要的数据列MediaStore.Images.Media.DISPLAY_NAME,   //图片的显示名称  aaa.jpgMediaStore.Images.Media.DATA,           //图片的真实路径  /storage/emulated/0/pp/downloader/wallpaper/aaa.jpgMediaStore.Images.Media.SIZE,           //图片的大小,long型  132492MediaStore.Images.Media.WIDTH,          //图片的宽度,int型  1920MediaStore.Images.Media.HEIGHT,         //图片的高度,int型  1080MediaStore.Images.Media.MIME_TYPE,      //图片的类型     image/jpegMediaStore.Images.Media.DATE_ADDED     //图片被添加的时间,long型  1450518608};private FragmentActivity activity;/*** 图片加载完成的回调接口*/private OnImagesLoadedListener loadedListener;/*** @param activity       用于初始化LoaderManager,需要兼容到2.3* @param path           指定扫描的文件夹目录,可以为 null,表示扫描所有图片* @param loadedListener 图片加载完成的监听*/public ImageDataSource(FragmentActivity activity, String path, OnImagesLoadedListener loadedListener) {this.activity = activity;this.loadedListener = loadedListener;LoaderManager loaderManager = activity.getSupportLoaderManager();if (path == null) {loaderManager.initLoader(LOADER_ALL, null, this);//加载所有的图片} else {//加载指定目录的图片Bundle bundle = new Bundle();bundle.putString("path", path);loaderManager.initLoader(LOADER_CATEGORY, bundle, this);}}@Overridepublic Loader<Cursor> onCreateLoader(int id, Bundle args) {CursorLoader cursorLoader = null;//扫描所有图片if (id == LOADER_ALL)//时间逆序cursorLoader = new CursorLoader(activity, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, null, null, IMAGE_PROJECTION[6] + " DESC");//扫描某个图片文件夹if (id == LOADER_CATEGORY)cursorLoader = new CursorLoader(activity, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, IMAGE_PROJECTION[1] + " like '%" + args.getString("path") + "%'", null, IMAGE_PROJECTION[6] + " DESC");return cursorLoader;}@Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {//imageFolders.clear();ImageItem imageItem = new ImageItem();//只取第一个if (data != null) {// ArrayList<ImageItem> allImages = new ArrayList<>();   //所有图片的集合,不分文件夹if (data.moveToFirst()) {//查询数据String imageName = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));String imagePath = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));long imageSize = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));int imageWidth = data.getInt(data.getColumnIndexOrThrow(IMAGE_PROJECTION[3]));int imageHeight = data.getInt(data.getColumnIndexOrThrow(IMAGE_PROJECTION[4]));String imageMimeType = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[5]));long imageAddTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[6]));//long imageTokenTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[7]));/*  SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");//前面的lSysTime是秒数,先乘1000得到毫秒数,再转为java.util.Date类型java.util.Date dt = new Date(imageAddTime*1000);String sDateTime = sdf.format(dt);  //得到精确到秒的表示:08/31/2006 21:08:00dt = new Date(imageTokenTime);String sTakenTime =  sdf.format(dt);Log.e("latestImage","imageAddTime=="+sDateTime+":::::"+imageTokenTime);*///封装实体//ImageItem imageItem = new ImageItem();imageItem.name = imageName;imageItem.path = imagePath;imageItem.size = imageSize;imageItem.width = imageWidth;imageItem.height = imageHeight;imageItem.mimeType = imageMimeType;imageItem.addTime = imageAddTime;}}//回调接口,通知图片数据准备完成//  ImagePicker.getInstance().setImageFolders(imageFolders);loadedListener.onImagesLoaded(imageItem);}@Overridepublic void onLoaderReset(Loader<Cursor> loader) {//System.out.println("--------");}/** 所有图片加载完成的回调接口 */public interface OnImagesLoadedListener {void onImagesLoaded(ImageItem imageItem);}
}

从cursor取出第一张图片并赋值到ImageItem上,那么这次取数据就完成了,然后回调到相应的Activity上,在Activity中这样调用:

  new ImageDataSource(this, null, this);

在回调接口中处理数据:

@Overridepublic void onImagesLoaded(ImageItem imageItem) {latestImage = imageItem ;}

2,把从库中取出的图片展示出来

展示图片用PopWindow ,自定义一个popWindow 来实现:
pop 的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="90dp"android:layout_height="135dp"android:orientation="vertical"android:background="@drawable/recommendphoto_bubble"android:padding="5dp"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="12sp"android:text="你可能要发送的照片:"/><ImageViewandroid:id="@+id/recommendphoto_img"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@drawable/recommendphoto_bg"android:layout_marginBottom="7dp"/></LinearLayout>

布局文件很简单,就两个控件和背景,pop 的具体实现:

/*** 推荐图片提示框 刚拍完照后,显示你可能要发送的图片**/
public class RecommendPhotoPop extends PopupWindow {/****/private ImageView iv;/****/private static Context context;public RecommendPhotoPop(Context context) {this.context = context;View view = LayoutInflater.from(context).inflate(R.layout.layout_recommendphoto_pop,null,false);iv = (ImageView) view.findViewById(R.id.recommendphoto_img);setContentView(view);setWidth(dip2px(90));setHeight(dip2px(135));setFocusable(false);setBackgroundDrawable(new BitmapDrawable());// 设置点击其他地方 就消失 (只设置这个,没有效果)setOutsideTouchable(true);}public  void setImgPath(final String path) {iv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {}});Glide.with(context).load(path).crossFade().centerCrop().into(iv);}/*** 显示图片提示* @param context* @param view*/public  static  RecommendPhotoPop recommendPhoto(Context context, View view,String path) {final RecommendPhotoPop recommendPhotoPop = new RecommendPhotoPop(context);recommendPhotoPop.setImgPath(path);int x = getScreenWidth(context) - dip2px(92);int y = getScreenHeight(context) - view.getMeasuredHeight() - dip2px(138);// recommendPhotoPop.showAsDropDown(view);recommendPhotoPop.showAtLocation(view, Gravity.NO_GRAVITY,x,y);return recommendPhotoPop;}/** dip转换px */public  static int dip2px(int dip) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dip * scale + 0.5f);}/** pxz转换dip */public static int px2dip(int px) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (px / scale + 0.5f);}/*** 获得屏幕高度** @param context* @return*/public  static int getScreenWidth(Context context) {WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.widthPixels;}/*** 获得屏幕宽度** @param context* @return*/public  static int getScreenHeight(Context context) {WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.heightPixels;}}

这里pop也实现了,看看主Activity 的实现:

布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/colorPrimary"><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="你想发送的图片"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_margin="5dp"/><ImageViewandroid:id="@+id/image"android:layout_width="400dp"android:layout_height="400dp" /></RelativeLayout>

代码:

public class MainActivity extends AppCompatActivity implements ImageDataSource.OnImagesLoadedListener {private ImageView imageView ;private Button btn ;private ImageItem latestImage ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageView = (ImageView)findViewById(R.id.image);btn = (Button)findViewById(R.id.btn);/*** 申请权限*/if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},0 );}else {new ImageDataSource(this, null, this);}btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {RecommendPhotoPop.recommendPhoto(MainActivity.this,btn,latestImage.path);}});//String url = "https://ws1.sinaimg.cn/large/610dc034ly1fiednrydq8j20u011itfz.jpg";// Glide.with(this).load(url).diskCacheStrategy(DiskCacheStrategy.ALL).into(imageView);}@Overridepublic void onImagesLoaded(ImageItem imageItem) {latestImage = imageItem ;Glide.with(this).load(imageItem.path).into(imageView);}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode){case 0:if(grantResults[0] == PackageManager.PERMISSION_GRANTED){new ImageDataSource(this, null, this);}break;}}

附上权限和依赖:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 compile 'com.github.bumptech.glide:glide:3.7.0'

源码: 高仿微信你可能要发送的图片

Android 高仿微信 你可能要发送的图片相关推荐

  1. android仿微信聊天功能,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  2. android 微信高仿,Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们 ...

  3. android+高仿视频录制,android高仿微信视频编辑页

    android高仿微信视频编辑页-视频多张图片提取 上一篇中介绍了有关视频提取图片的知识点,如果对这个不太了解 建议看下android提取视频多张图片和视频信息之前这篇. 这里实现的是仿微信的视频编辑 ...

  4. php支付密码控件,Android高仿微信支付密码输入控件实例代码

    这篇文章主要为大家详细介绍了Android高仿微信支付密码输入控件的具体实现代码,供大家参考,具体内容如下 像微信支付密码控件,在app中是一个多么司空见惯的功能.最近,项目需要这个功能,于是乎就实现 ...

  5. android高仿微信视频编辑页-视频多张图片提取

    android高仿微信视频编辑页-视频多张图片提取 上一篇中介绍了有关视频提取图片的知识点,如果对这个不太了解 建议看下android提取视频多张图片和视频信息之前这篇. 这里实现的是仿微信的视频编辑 ...

  6. android com.mylhyl,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. photopicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

  7. android高仿微信聊天页面,Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)

    目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图: 仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高 ...

  8. android仿微信充值布局,Android 高仿微信支付数字键盘功能

    现在很多app的支付.输入密码功能,都已经开始使用自定义数字键盘,不仅更加方便.其效果着实精致. 下面带着大家学习下,如何高仿微信的数字键盘,可以拿来直接用在自身的项目中. 先看下效果图: 1. 自定 ...

  9. android 微信高仿,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. PhotoPicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

最新文章

  1. 12.流水线设计方式
  2. 【C++grammar】访问控制与抽象类与纯虚函数
  3. 捐赠赞助单页HTML模板
  4. Atitit 关于微服务的思考与理解 attilax总结 1.1. 架构的历史 微服务发展历史 Web》soa》msa 1 1.2. 微服务最大特点 独立部署 1 2. 微服务的优点 1 2.1.
  5. 获取HG526超级密码
  6. html里表格做斜线表头,word表格斜线_Word2010怎么绘制斜线表头-太平洋IT百科
  7. ue4 迁移模型_UE4模型导入基础操作(MAX为例)
  8. conda管理python开发环境
  9. 服务器被穷举法暴力爆破、攻击的简单应对方案。
  10. linux装百度网盘不能运行,在Deepin系统中安装百度网盘的两种方法
  11. QMC5883L与msp430FG4618--IIC通信
  12. twitter_如何找回旧的Twitter网站
  13. Java-----投票系统
  14. 子线程设置的钩子(HOOK)为什么钩不到消息?
  15. 六年级计算机机器人考试试题,小学六年级下册信息技术教案:机器人行走
  16. 合理使用DTO(Data Transfer Object)
  17. 今天是值得纪念的一天!
  18. 【SEMrush教程】SEO关键词魔法工具使用技巧
  19. 什么是低功耗蓝牙技术
  20. 计算sin(x)的定积分

热门文章

  1. 生活中的定律之刺猬理念
  2. nodeJS学习之旅-----session的使用,cookie,webstorage的理解
  3. 画布实现动态太极图, 旋转太极图
  4. c#Reflect中MethodInfo使用方法(字符串反射调用函数方法的实现)
  5. Qt学习 第35节:模态对话框和非模态对话框
  6. linux下crontab allow,【Python】Linux crontab定时任务配置方法(详解)
  7. linux配置虚拟IP--VIP
  8. linux管道文件的实现原理,管道(无名管道)通信机制原理和实现详解
  9. oracel 报错ORA-00918: column ambiguously defined
  10. 爬虫入门经典(八) | 一文带你快速爬取股吧