鲁班图片压缩实现仿微信九宫格选择图片效果
2017-01-20 14:30
288 查看
项目开发中碰到了类似微信的图片选择、图片压缩及上传,一开始利用一些第三方的进行修改,但是很容就出现内存溢出,而有些比较优秀的第三方的多半是采用远程依赖的方式集成开发的,很难对源码进行改动而达到自己的需求,后面在跟大牛的学习过程中,就写了一个简单的图片选择,已用于项目开发,并没有出现内存溢出。
简单的对实现做一个说明:
1、图片压缩采用的是第三方的鲁班图片压缩;
2、图片加载采用的是glide;
3、图片展示列表用的是recyclerview实现的;
4、实现了多选(可以随便控制图片选择的数量)、单选、隐藏拍照、删除、预览等功能;
5、已对android6.0读取和写入sd权限做了适配,android7.0访问相机权限做了适配;
效果如下:
图片压缩效果:
![](http://img.blog.csdn.net/20171226103601386?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3dvMTk5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
拍照的原图(大小是2.59M):
![](http://img.blog.csdn.net/20171226102320960?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3dvMTk5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
压缩的效果(75.33kb):
![](http://img.blog.csdn.net/20171226103653702?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3dvMTk5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
主要代码实现:
MainActivity类中主要是读取和写入sd卡权限的申请、选择图片的入口函数、选择图片后的展示、图片删除、图片预览入口、图片压缩等。
RequestAdapter是MainActivity类中RecyclerView的列表适配器,主要是根据position和选择图片的数量来显示图片和“+”选择更多、删除图片、图片点击的一些回调。
SelectImageActivity类主要是获取系统sd里面的图片并展示、android7.0访问相机适配、相机拍照后图片的刷新和保存等。
SelectImageAdapter类是SelectImageActivity类中RecyclerView的适配器,展示系统sd获取的图片、控制图片选择的数量等。
PreViewActivity类和ImageViewFragment类是图片预览,这里的图片预览效果做的不是很好,可以根据自己的需要进行修改。
ImageSelector类是一个工具类,里面提供了设置图片多选还是单选,选择图片的数量,是否显示相机等。
上面这些就是实现的主要代码,下面会提供源码,可以根据自己的需要对源码进行修改。
源码地址:
http://pan.baidu.com/s/1bp50kLT
简单的对实现做一个说明:
1、图片压缩采用的是第三方的鲁班图片压缩;
github:[https://github.com/Curzibn/Luban](https://github.com/Curzibn/Luban)
2、图片加载采用的是glide;
compile 'com.github.bumptech.glide:glide:3.7.0'
3、图片展示列表用的是recyclerview实现的;
compile 'com.android.support:recyclerview-v7:25.3.1'
4、实现了多选(可以随便控制图片选择的数量)、单选、隐藏拍照、删除、预览等功能;
5、已对android6.0读取和写入sd权限做了适配,android7.0访问相机权限做了适配;
效果如下:
图片压缩效果:
拍照的原图(大小是2.59M):
压缩的效果(75.33kb):
主要代码实现:
public class MainActivity extends AppCompatActivity { private static final int PHOTO_CAMERA = 1000; private static final int DELETE_CODE = 1002; private final int SELECT_IMAGE_REQUEST = 0x0011; private ArrayList<String> mImageList = new ArrayList<>(); private ArrayList<String> mRuquestList = new ArrayList<>(); @ViewById(R.id.image_list_rv) private RecyclerView imageListRv; private RequestAdapter adapter; private int maxChoice = 9; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewUtils.inject(this); adapter = new RequestAdapter(this, mImageList, maxChoice); imageListRv.setLayoutManager(new GridLayoutManager(MainActivity.this, 4)); imageListRv.setAdapter(adapter); //设置分割线 imageListRv.addItemDecoration(new DividerGridItemDecoration(MainActivity.this, R.drawable.item_dirver_02)); adapter.setOnItemClickListener(new ItemClickListener() { @Override public void onItemClick(Object obj, int position) { Log.e("position", "position---->" + position); if (mImageList.size() == position) { //动态申请权限 PermissionHelper.with(MainActivity.this). requestPermission(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}). requestCode(PHOTO_CAMERA). request(); } else { //跳转至删除或者预览页面 Intent intent = new Intent(MainActivity.this, PreViewActivity.class); Bundle bundle = new Bundle(); bundle.putInt("choicePosition", position); bundle.putSerializable("choiceList", mImageList); intent.putExtras(bundle); startActivity(intent); } } }); adapter.setOnDeleteClickListener(new DeleteListener() { @Override public void onDeleteClick(Object obj, int position) { removeList(position); } }); } /** * 删除图片 * * @param position */ private void removeList(int position) { mImageList.remove(position); adapter.nodfiyData(mImageList); } @PermissionSuccess(requestCode = PHOTO_CAMERA) private void toSelectImageActivity() { ImageSelector .create() .multi() .count(maxChoice) .showCamera(true) .origin(mImageList) .start(this, SELECT_IMAGE_REQUEST); } /** * 图片压缩 这里放在网络请求之前做好些,放在onActivityResult里面每次图片改动都要调用 * 这里没有网络请求环境就放在onActivityResult里面了 */ private void compressImg() { if (mRuquestList.size() != 0) { mRuquestList.clear(); } // 把选择好的图片做了一下压缩 for (String path : mImageList) { // 做优化 第一个decodeFile有可能会内存移除 // 一般后台会规定尺寸 800 小米 规定了宽度 720 // 上传的时候可能会多张 for循环 最好用线程池 (2-3) Bitmap bitmap = ImageUtil.decodeFile(960, path); // 调用写好的native方法 //压缩存储的路径 String imageViewUrl = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + new File(path).getName(); // 用Bitmap.compress压缩1/10 ImageUtil.compressBitmap(bitmap, 75, imageViewUrl); mRuquestList.add(imageViewUrl); } adapter.nodfiyData(mImageList); Log.e("mRuquestList", "mRuquestList----->" + mRuquestList.size()); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == SELECT_IMAGE_REQUEST && data != null) { mImageList = (ArrayList<String>) data.getSerializableExtra(SelectImageActivity.EXTRA_DEFAULT_SELECTED_LIST); adapter.nodfiyData(mImageList); } } } /** * 压缩点击事件 * * @param view */ public void tvCompress(View view) { compressImageView(); } /** * 使用鲁班压缩图片 * 在子线程中开启图片压缩 */ private void compressImageView() { new Thread(new Runnable() { @Override public void run() { if (mRuquestList.size() != 0) { mRuquestList.clear(); } for (String s : mImageList) { if (s == null) { s = ""; } File file = new File(s); Luban.with(MainActivity.this) .load(file)//传入要压缩的图片 这里采用的是单张压缩 也可以采用多张压缩 .ignoreBy(100) // 忽略不压缩图片的大小 如果原图片小于100kb不会进行压缩 // .putGear(Luban.Builder.)//设定压缩档次,默认三挡 .setCompressListener(new OnCompressListener() { //设置回调 @Override public void onStart() { // TODO 压缩开始前调用,可以在方法内启动 loading UI } @Override public void onSuccess(File file) { // TODO 压缩成功后调用,返回压缩后的图片文件 String absolutePath = file.getAbsolutePath(); mRuquestList.add(absolutePath); } @Override public void onError(Throwable e) { // TODO 当压缩过程出现问题时调用 } }).launch(); //启动压缩 } } }).start(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); PermissionHelper.requestPermissionsResult(this, requestCode, permissions, grantResults); } }
MainActivity类中主要是读取和写入sd卡权限的申请、选择图片的入口函数、选择图片后的展示、图片删除、图片预览入口、图片压缩等。
public class RequestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private ArrayList<String> mRequestList; private int mMaxNumber; private Context mContext; public RequestAdapter(Context context,ArrayList<String> requestList,int maxNumber){ this.mContext=context; this.mMaxNumber=maxNumber; this.mRequestList = new ArrayList<String>(); if(mRequestList!=null) { this.mRequestList.addAll(requestList); } } public void nodfiyData(List<String> list){ if(list!=null) { this.mRequestList.clear(); this.mRequestList.addAll(list); } notifyDataSetChanged(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.request_chooser_item, parent, false); return new Holder(view); } @Override public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) { Holder holder = (Holder) viewHolder; if(position==mRequestList.size()){ holder.ivDelete.setVisibility(View.GONE); int resourceId = R.drawable.icon_addpic_unfocused; //显示图片 利用Glide centerCrop() Glide.with(mContext).load(resourceId).centerCrop().into(holder.image); if(position==mMaxNumber){ holder.image.setVisibility(View.GONE); } }else{ holder.ivDelete.setVisibility(View.VISIBLE); //显示图片 利用Glide centerCrop() Glide.with(mContext).load(mRequestList.get(position)).centerCrop().into(holder.image); } //条目点击事件 if(mItemClickListener!=null){ holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(position==mMaxNumber){ return; } if(mRequestList.size()==position){ mItemClickListener.onItemClick("",position); }else { mItemClickListener.onItemClick(mRequestList.get(position), position); } } }); } if(mItemDeleteListener!=null){ holder.ivDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mItemDeleteListener.onDeleteClick(mRequestList.get(position), position); } }); } } @Override public int getItemCount() { return mRequestList.size()+1; } class Holder extends RecyclerView.ViewHolder{ SquareImageView image; ImageView ivDelete; public Holder(View itemView) { super(itemView); image = (SquareImageView) itemView.findViewById(R.id.image_show); ivDelete= (ImageView) itemView.findViewById(R.id.iv_delete); } } //使用接口回调点击事件 private ItemClickListener mItemClickListener; public void setOnItemClickListener(ItemClickListener itemClickListener){ this.mItemClickListener=itemClickListener; } //使用接口回调点击事件 private DeleteListener mItemDeleteListener; public void setOnDeleteClickListener(DeleteListener itemDeleteListener){ this.mItemDeleteListener=itemDeleteListener; } }
RequestAdapter是MainActivity类中RecyclerView的列表适配器,主要是根据position和选择图片的数量来显示图片和“+”选择更多、删除图片、图片点击的一些回调。
public class SelectImageActivity extends AppCompatActivity implements View.OnClickListener{ //相机 public static final String EXTRA_SHOW_CAMERA = "EXTRA_SHOW_CAMERA"; //选择张数 public static final String EXTRA_SELECT_COUNT = "EXTRA_SELECT_COUNT"; //原始的图片路径 public static final String EXTRA_DEFAULT_SELECTED_LIST = "EXTRA_DEFAULT_SELECTED_LIST"; //选择的模式 public static final String EXTRA_SELECT_MODE = "EXTRA_SELECT_MODE"; //返回选择图片的列表 public static final String EXTRA_RESULT = "EXTRA_RESULT"; //多选 public static final int MODE_MULTI = 0x0011; //单选 public static final int MODE_SINGLE = 0x0012; private static final int LOADER_TYPE = 0x0021; private static final int REQUEST_CAMERA = 0x0022; private static final int PHOTO_CAMERA = 1002; private static final int PREVIEW_CODE = 1003; //单选或多选 private int mMode = MODE_MULTI; //选择图片的张数 private int mMaxCount = 9; //是否显示拍照按钮 private boolean mShowCamera = true; //选择图片的list private ArrayList<String> mResultList; @ViewById(R.id.btn_back) private ImageView btnBack; @ViewById(R.id.image_list_rv) private RecyclerView imageListRv; //预览 @ViewById(R.id.select_preview) private TextView selectPreview; @ViewById(R.id.select_num) private TextView selectNum; @ViewById(R.id.select_finshi) private TextView selectFinshi; private File mTempFile; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_image); ViewUtils.inject(this); initData(); } /** * 初始化本地数据 */ private void initImageList() { //获取本地图片 耗时操作 getLoaderManager().initLoader(LOADER_TYPE, null, mLoaderCallBack); } private LoaderManager.LoaderCallbacks<Cursor> mLoaderCallBack = new LoaderManager.LoaderCallbacks<Cursor>() { private final String[] IMAGE_PROJECTION = { MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DATE_ADDED, MediaStore.Images.Media.MIME_TYPE, MediaStore.Images.Media.SIZE, MediaStore.Images.Media._ID, }; @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { CursorLoader cursorLoader = new CursorLoader(SelectImageActivity.this, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, IMAGE_PROJECTION[4] + ">0 AND " + IMAGE_PROJECTION[3] + "=? OR " + IMAGE_PROJECTION[3] + "=? ", new String[]{"image/jpeg", "image/png"}, IMAGE_PROJECTION[2] + " DESC"); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { //如果有数据变化 if (data != null && data.getCount() > 0) { ArrayList<String> images = new ArrayList<>(); //如果需要显示拍照就添加一条空数据 if (mShowCamera) { //封装数据对象 // ImageEntity photoImage = new ImageEntity("", "", 0); images.add(""); } //不断遍历循环 while (data.moveToNext()) { String path = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0])); // String name = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1])); // long dateTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2])); // Log.e("TAG", path + " " + name + " " + dateTime); // //判断文件是否存在 // if (!pathExist(path)) { // continue; // } // Log.e("TAG", path + " " + name + " " + dateTime); //封装数据对象 // ImageEntity image = new ImageEntity(path, name, dateTime); images.add(path); } //显示列表数据 showListData(images); } } /** * 判断文件是否存在 * * @param path * @return */ private boolean pathExist(String path) { if (!TextUtils.isEmpty(path)) { return new File(path).exists(); } return false; } @Override public void onLoaderReset(Loader<Cursor> loader) { } }; /** * 显示列表数据 * * @param images */ private void showListData(ArrayList<String> images) { SelectImageAdapter adapter = new SelectImageAdapter(SelectImageActivity.this, images, mResultList,mMaxCount, R.layout.media_chooser_item); imageListRv.setLayoutManager(new GridLayoutManager(SelectImageActivity.this, 4)); imageListRv.setAdapter(adapter); //设置分割线 imageListRv.addItemDecoration(new DividerGridItemDecoration(SelectImageActivity.this,R.drawable.item_dirver_01)); adapter.setOnSelectImageListener(new SelectImageListener() { @Override public void select(int number) { exchangViewShow(number); } }); //拍照回调 adapter.setTakePhotoListener(new TakePhotoListener() { @Override public void takePhoto() { //动态申请权限 PermissionHelper.with(SelectImageActivity.this). requestPermission(new String[]{Manifest.permission.CAMERA}). requestCode(PHOTO_CAMERA). request(); } }); } /** * 拍照这里要做Android6.0以下 Android6.0和Android7.0以上的适配 */ @PermissionSuccess(requestCode = PHOTO_CAMERA) private void takePhoto(){ mTempFile=new File(getInnerSDCardPath(), "imagephoto" + SystemClock.currentThreadTimeMillis() + ".jpg"); if (!mTempFile.getParentFile().exists()){ mTempFile.getParentFile().mkdirs(); } if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ //Android7.0 com.picchoice替换成自己的包名 Uri imageUri = FileProvider.getUriForFile(SelectImageActivity.this, "com.picchoice.fileprovider", mTempFile);//通过FileProvider创建一个content类型的Uri Intent intent = new Intent(); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件 intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照 intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI startActivityForResult(intent,REQUEST_CAMERA); }else { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile)); startActivityForResult(intent, REQUEST_CAMERA); } // File file=new File(Environment.getExternalStorageDirectory(), "/temp/"+System.currentTimeMillis() + ".jpg"); } /** * 获取内置SD卡路径 * @return */ public String getInnerSDCardPath() { return Environment.getExternalStorageDirectory().getPath(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); PermissionHelper.requestPermissionsResult(this,requestCode,permissions,grantResults); } @Click({R.id.btn_back,R.id.select_finshi}) private void Click(View view) { switch (view.getId()) { case R.id.btn_back: finish(); break; case R.id.select_finshi://确定 Intent intent=new Intent(); Bundle bundle=new Bundle(); bundle.putSerializable(SelectImageActivity.EXTRA_DEFAULT_SELECTED_LIST,mResultList); intent.putExtras(bundle); setResult(RESULT_OK,intent); finish(); break; } } /** * 获取传递过来的参数 */ private void initData() { Intent intent = getIntent(); mMode = intent.getIntExtra(EXTRA_SELECT_MODE, mMode); mMaxCount = intent.getIntExtra(EXTRA_SELECT_COUNT, mMaxCount); mShowCamera = intent.getBooleanExtra(EXTRA_SHOW_CAMERA, mShowCamera); mResultList = (ArrayList<String>) intent.getSerializableExtra(EXTRA_DEFAULT_SELECTED_LIST); if (mResultList == null) { mResultList = new ArrayList<>(); } //初始化本地数据 initImageList(); //改变显示 exchangViewShow(mResultList.size()); } /** * 改变显示 */ private void exchangViewShow(int numder) { if (numder> 0) { selectPreview.setTextColor(Color.parseColor("#FF4081")); selectFinshi.setTextColor(Color.parseColor("#FF4081")); selectPreview.setEnabled(true); selectPreview.setOnClickListener(this); } else { selectPreview.setTextColor(Color.parseColor("#ffffff")); selectFinshi.setTextColor(Color.parseColor("#ffffff")); selectPreview.setEnabled(false); selectPreview.setOnClickListener(null); } selectNum.setText(numder + "/" + mMaxCount); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.select_preview://预览 //跳转至删除或者预览页面 Intent intent=new Intent(SelectImageActivity.this,PreViewActivity.class); Bundle bundle=new Bundle(); bundle.putInt("choicePosition",0); bundle.putSerializable("choiceList",mResultList); intent.putExtras(bundle); startActivity(intent); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //第一个要把图片添加到集合 //调用Click方法 //通知系统本地有图片改变了 下次进来可以找到这张图片 if(resultCode==RESULT_OK){ if(requestCode==REQUEST_CAMERA){ sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(mTempFile))); mResultList.add(mTempFile.getAbsolutePath()); setResult(); } } } /** * 设置返回结果 */ private void setResult(){ Intent intent=new Intent(); Bundle bundle=new Bundle(); // bundle.putSerializable(EXTRA_RESULT,mResultList);//EXTRA_DEFAULT_SELECTED_LIST bundle.putSerializable(EXTRA_DEFAULT_SELECTED_LIST,mResultList); intent.putExtras(bundle); setResult(RESULT_OK,intent); //关闭当前页面 finish(); } }
SelectImageActivity类主要是获取系统sd里面的图片并展示、android7.0访问相机适配、相机拍照后图片的刷新和保存等。
public class SelectImageAdapter extends RecyclerCommonAdapter<String> { private Context mContext; private List<String> imageList; private int mMaxCount; public SelectImageAdapter(Context context, List<String> data, List<String> choice, int maxCount, int layoutId) { super(context, data, layoutId); this.mContext = context; this.imageList = choice; this.mMaxCount = maxCount; } @Override protected void bindData(ViewHolder holder, final String mPath, final int position) { if (TextUtils.isEmpty(mPath)) { //显示拍照 holder.setViewVisibility(R.id.camear_ll, View.VISIBLE); holder.setViewVisibility(R.id.media_selected_indicator, View.INVISIBLE); holder.setViewVisibility(R.id.image_show, View.INVISIBLE); //拍照 holder.getView(R.id.camear_ll).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //调用拍照 if(takePhotoListener!=null){ takePhotoListener.takePhoto(); } } }); } else { //显示图片 holder.setViewVisibility(R.id.camear_ll, View.INVISIBLE); holder.setViewVisibility(R.id.media_selected_indicator, View.VISIBLE); holder.setViewVisibility(R.id.image_show, View.VISIBLE); SquareImageView image = holder.getView(R.id.image_show); //显示图片 利用Glide centerCrop() Glide.with(mContext).load(mPath).centerCrop().into(image); ImageView selectImageView = holder.getView(R.id.media_selected_indicator); if (imageList.contains(mPath)) { //设置勾选图片 selectImageView.setSelected(true); } else { selectImageView.setSelected(false); } //给条目添加点击事件 image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //没有就加入集合 if (!imageList.contains(mPath)) { if (imageList.size() >= mMaxCount) { Toast.makeText(mContext, "最多只能选择" + mMaxCount + "张图片", Toast.LENGTH_LONG).show(); return; } imageList.add(mPath); } else { //有就移除 imageList.remove(mPath); } //刷新数据 notifyDataSetChanged(); //通知显示布局 if (selectImageListener != null) { selectImageListener.select(imageList.size()); } } }); } } private SelectImageListener selectImageListener; public void setOnSelectImageListener(SelectImageListener listener) { this.selectImageListener = listener; } private TakePhotoListener takePhotoListener; public void setTakePhotoListener(TakePhotoListener listener) { this.takePhotoListener = listener; } }
SelectImageAdapter类是SelectImageActivity类中RecyclerView的适配器,展示系统sd获取的图片、控制图片选择的数量等。
public class PreViewActivity extends AppCompatActivity implements View.OnClickListener { @ViewById(R.id.btn_back) private ImageView btnBack; @ViewById(R.id.viewpager) private ViewPager viewpager; private List<String> choiceList; private DeleteAdapter adapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_delete); ViewUtils.inject(this); choiceList = (List<String>) getIntent().getSerializableExtra("choiceList"); if(choiceList==null){ choiceList=new ArrayList<>(); } adapter=new DeleteAdapter(getSupportFragmentManager()); viewpager.setAdapter(adapter); btnBack.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_back: finish(); break; } } class DeleteAdapter extends FragmentPagerAdapter{ public DeleteAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return ImageViewFragment.newInstance(choiceList.get(position)); } @Override public int getCount() { return choiceList.size(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); } } }
public class ImageViewFragment extends Fragment{ public static ImageViewFragment newInstance(String item){ ImageViewFragment fragment=new ImageViewFragment(); Bundle bundle=new Bundle(); bundle.putString("url",item); fragment.setArguments(bundle); return fragment; } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_imageview, container, false); ImageView image = (ImageView) view.findViewById(R.id.image); Bundle bundle = getArguments(); String url = bundle.getString("url"); if(url==null){ url=""; } int screenWidth = getW(getActivity()); Bitmap diskBitmap = getDiskBitmap(url); if(diskBitmap!=null){ //获取Bitmap的宽高 int width = diskBitmap.getWidth(); int height = diskBitmap.getHeight(); //根据Bitmap的宽高和屏幕的宽高重新设置imageview显示的大小 RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) image.getLayoutParams(); layoutParams.width=screenWidth; layoutParams.height=screenWidth*height/width; image.setLayoutParams(layoutParams); } //显示图片 利用Glide centerCrop() Glide.with(this).load(url).centerCrop().into(image); return view; } /** * 根据url获取一个bitmap对象 * @param pathString 图片路径 * @return 返回对应的Bitmap对象 */ private Bitmap getDiskBitmap(String pathString) { Bitmap bitmap = null; try { File file = new File(pathString); if(file.exists()) { bitmap = BitmapFactory.decodeFile(pathString); } } catch (Exception e) { e.printStackTrace(); } return bitmap; } /* * 获取屏幕的宽度 */ private int getW(Context context){ DisplayMetrics dm = new DisplayMetrics(); WindowManager windowMgr = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); windowMgr.getDefaultDisplay().getMetrics(dm); return dm.widthPixels; } }
PreViewActivity类和ImageViewFragment类是图片预览,这里的图片预览效果做的不是很好,可以根据自己的需要进行修改。
public class ImageSelector { //选择图片张数 private int mMaxCount = 9; //选择图片的模式 private int mMode = SelectImageActivity.MODE_MULTI; //是否显示拍照的相机 private boolean mShowCamera = true; //原始的图片 private ArrayList<String> mOriginData; private ImageSelector() { } public static ImageSelector create() { return new ImageSelector(); } /** * 单选模式 * * @return */ public ImageSelector single() { mMode = SelectImageActivity.MODE_SINGLE; return this; } /** * 多选模式 * * @return */ public ImageSelector multi() { mMode = SelectImageActivity.MODE_MULTI; return this; } /** * 设置可以选择的图片张数 * * @param count * @return */ public ImageSelector count(int count) { mMaxCount = count; return this; } /** * 是否显示相机 * * @param showCamera * @return */ public ImageSelector showCamera(boolean showCamera) { mShowCamera = showCamera; return this; } /** * 选择好的图片 * * @param originList * @return */ public ImageSelector origin(ArrayList<String> originList) { this.mOriginData = originList; return this; } /** * 启动requestCode * * @param activity * @param requestCode */ public void start(Activity activity, int requestCode) { Intent intent = new Intent(activity, SelectImageActivity.class); addParmasByIntent(intent); activity.startActivityForResult(intent, requestCode); } /** * 启动requestCode * * @param fragment * @param requestCode */ public void start(Fragment fragment, int requestCode) { Intent intent = new Intent(fragment.getContext(), SelectImageActivity.class); addParmasByIntent(intent); fragment.startActivityForResult(intent, requestCode); } /** * 设置参数 * * @param intent */ private void addParmasByIntent(Intent intent) { Bundle bundle = new Bundle(); bundle.putInt(SelectImageActivity.EXTRA_SELECT_COUNT, mMaxCount); bundle.putInt(SelectImageActivity.EXTRA_SELECT_MODE, mMode); bundle.putBoolean(SelectImageActivity.EXTRA_SHOW_CAMERA, mShowCamera); if (mOriginData != null && mMode == SelectImageActivity.MODE_MULTI) { bundle.putSerializable(SelectImageActivity.EXTRA_DEFAULT_SELECTED_LIST, mOriginData); } intent.putExtras(bundle); } }
ImageSelector类是一个工具类,里面提供了设置图片多选还是单选,选择图片的数量,是否显示相机等。
上面这些就是实现的主要代码,下面会提供源码,可以根据自己的需要对源码进行修改。
源码地址:
http://pan.baidu.com/s/1bp50kLT
相关文章推荐
- Android用GridView排列相册,实现微信选择图片效果
- Android用GridView排列相册,实现微信选择图片效果
- 自己实现图片压缩技术,直接上代码,绝对好用(优化效果不错)
- Android开发 自定义ViewGroup 实现微信九格图功能(图片不同排布不同) 和 一种图片点击变暗效果
- 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器TZImagePickerController
- AngularJS1.x学习(仿微信图片手势缩放效果实现)
- Javascript实现的选择图片效果
- 实现仿照微信聊天气泡里显示图片效果的自定义View
- DevExpress PictrueEdit 实现图片 剪裁 , 缩放 , 压缩大小 效果
- 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-9系统,3行代码即可集成.
- python练习-实现图片类似微信未读信息数量效果
- java实现的图片缩放 压缩 裁剪工具!找了很久,市面上再也找不到比它缩放效果还好的代码了
- php实现微信中的图片合并 (圆角) -九宫格图片实现
- 自定义控件实现微博图片九宫格效果
- iOS软件开发实现类似微信上传图片选择
- 实现图片翻转效果--动态选择添加图片
- Android-图片选择,压缩,上传,加载 的实例(图片上传(多图也可),服务器端实现,图片加载(图片轮播实现))
- php实现微信中的图片合并-九宫格图片
- HTML+CSS实现图片下半部分遮罩文字效果(仿微信推送信息的图片文字效果)
- 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器