Android 高仿微信 你可能要发送的图片
来源:互联网 发布:shell脚本与python 编辑:程序博客网 时间:2024/06/07 08:51
微信发送图片有个功能,就是当你拍完照片,或者保存一个张照片的时候,你点击聊天框的“+”号,微信会有个提示,你可能要发送的图片,并且附上相应的图片。要实现这个功能,分两个步骤。
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; //图片的创建时间 /** 图片的路径和创建时间相同就认为是同一张图片 */ @Override public 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.jpg MediaStore.Images.Media.DATA, //图片的真实路径 /storage/emulated/0/pp/downloader/wallpaper/aaa.jpg MediaStore.Images.Media.SIZE, //图片的大小,long型 132492 MediaStore.Images.Media.WIDTH, //图片的宽度,int型 1920 MediaStore.Images.Media.HEIGHT, //图片的高度,int型 1080 MediaStore.Images.Media.MIME_TYPE, //图片的类型 image/jpeg MediaStore.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); } } @Override public 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; } @Override public 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:00 dt = 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); } @Override public void onLoaderReset(Loader<Cursor> loader) { //System.out.println("--------"); } /** 所有图片加载完成的回调接口 */ public interface OnImagesLoadedListener { void onImagesLoaded(ImageItem imageItem); }}从cursor取出第一张图片并赋值到ImageItem上,那么这次取数据就完成了,然后回调到相应的Activity上,在Activity中这样调用:
new ImageDataSource(this, null, this);在回调接口中处理数据:
@Override public 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"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12sp" android:text="你可能要发送的照片:"/> <ImageView android: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() { @Override public 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"?><RelativeLayout xmlns: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" > <Button android: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" /> <ImageView android: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 ; @Override protected 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() { @Override public 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); } @Override public void onImagesLoaded(ImageItem imageItem) { latestImage = imageItem ; Glide.with(this).load(imageItem.path).into(imageView); } @Override public 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'
源码:高仿微信你可能要发送的图片
阅读全文
0 0
- Android 高仿微信 你可能要发送的图片
- android你可能要用到的自定义View分享
- Android 你可能需要的NiceDialog
- 公司邮箱发送到外域被拒,你的邮箱服务器可能被加入到黑名单
- Android中一些你可能不太知道的东西
- 10个你可能不知道的 Android Studio技巧
- 10个你可能不知道的 Android Studio技巧
- Android Studio你可能不知道的操作
- Android Studio 你可能不知道的使用技巧
- Android Studio 你可能不知道的使用技巧
- Android那些你可能没了解过的---碎片化
- 10个你可能不知道的 Android Studio技巧
- Android Studio你可能还不知道的操作
- Android保存图片(可能屏幕截图的)到系统图库
- 可能是 Android 平台上最快的图片压缩框架
- android socket发送图片
- 你可能是自由的
- 你可能不知道的
- NOIP2016提高组D1T2天天爱跑步(lca+树上差分)
- hdu 1847 Good Luck in CET-4 Everybody! (博弈论)
- 编程马拉松----走迷宫
- Hihocoder1014 Tire前缀树 很好的模板
- 4.x版eclipse在windows下启动报a java runtime environment(JRE)的有效解决办法
- Android 高仿微信 你可能要发送的图片
- leetcode 53. Maximum Subarray DP+最大子串和
- 进入DOS世界
- Docker+Gogs搭建个人Git服务
- PAT练习题002
- 使用json-lib将Java对象转json死循环问题
- git
- 重新编写IT笔记
- dfs+数学? 单