Android 高仿微信 你可能要发送的图片

2 篇文章 0 订阅

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

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'


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



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值