从零开始打造一个新闻订阅APP之Android篇(四、实现仿微信发图界面)
2015-05-26 21:08
721 查看
在手机上发图大致分为拍照和选择手机图片两种类型:
拍照的步骤:如果不是专门的相机应用,直接调用系统相机,拍一张照片并返回即可;
选择手机图片的话,网上可以搜到很多相关文章,最常见的一种方式是,先遍历数据库,获取手机上全部缩略图,然后根据缩略图查找对应的原图路径;但我在小米4和htc M8两部手机上尝试了多种遍历所有缩略图的方式,发现并不是所有的原图都会有缩略图,这可能和应用程序或者android系统生成缩略图方式有关。
因此,只能换一种思路实现。一开始选择用缩略图做列表展示主要考虑的是大量展示原图可能存在内存开销较大和加载速度较慢,不过仔细思考后觉得既然这里的场景都是直接用从手机存储中读取图片,预估即使所有的图片不用缓存,全部直接从磁盘读取的速度应该都是可接受的,最终实现发现基本效果和微信的发图页面差不多,有一定的加载延迟,但是在可接受范围之类。
这里还是用universalImageLoader来作为加载图片的组件,定义一个gridView用来展示图片,gridView中定义两种不同布局,一个用来展示拍照,另一种用来展示遍历到的系统图片。
先看下实现效果:
布局文件:
java代码
有兴趣的同学也可以去豌豆荚搜索“布板”或扫描二维码下载android的demo版试用看看,欢迎小伙伴们和我一起讨论交流。
拍照的步骤:如果不是专门的相机应用,直接调用系统相机,拍一张照片并返回即可;
选择手机图片的话,网上可以搜到很多相关文章,最常见的一种方式是,先遍历数据库,获取手机上全部缩略图,然后根据缩略图查找对应的原图路径;但我在小米4和htc M8两部手机上尝试了多种遍历所有缩略图的方式,发现并不是所有的原图都会有缩略图,这可能和应用程序或者android系统生成缩略图方式有关。
因此,只能换一种思路实现。一开始选择用缩略图做列表展示主要考虑的是大量展示原图可能存在内存开销较大和加载速度较慢,不过仔细思考后觉得既然这里的场景都是直接用从手机存储中读取图片,预估即使所有的图片不用缓存,全部直接从磁盘读取的速度应该都是可接受的,最终实现发现基本效果和微信的发图页面差不多,有一定的加载延迟,但是在可接受范围之类。
这里还是用universalImageLoader来作为加载图片的组件,定义一个gridView用来展示图片,gridView中定义两种不同布局,一个用来展示拍照,另一种用来展示遍历到的系统图片。
先看下实现效果:
布局文件:
<? xml version= "1.0" encoding = "utf-8"?> < GridView xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http://schemas.android.com/tools" android:id= "@+id/gridView" android:paddingTop= "1dp" android:layout_width= "match_parent" android:layout_height= "match_parent" android:numColumns= "3" android:verticalSpacing= "2dp" android:horizontalSpacing= "2dp" android:stretchMode= "columnWidth" > </ GridView>
java代码
public class ThumbnailActivity extends Activity { public static String TAG = "Thumbnails"; public static final int TAKE_PHOTO = 10000; public static final int SELECT_PHOTO = 10001; private GridView gridView; private GridAdapter adapter; private int maxImageSelectCount; private List<String> selectedImages; private ImageLoader imageLoader = ImageLoader.getInstance(); DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.background_image_loading) //设置图片在下载期间显示的图片 .cacheInMemory(false)//设置下载的图片是否缓存在内存中 .cacheOnDisk(false)//设置下载的图片是否缓存在SD卡中 .considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转) .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示 .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型// .build();//构建完成 /** * 拍照后照片存储地址 */ private Uri takePhotoUri; // private static final String FILE_PATH = // Environment.getExternalStorageDirectory().getPath(); @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.thumbnail, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_confirm: Intent res = new Intent(); ArrayList<String> li = new ArrayList<String>(); for (String path : selectedImages) { if (path != null) li.add(path); } res.putExtra("tu_ji", li); setResult(SELECT_PHOTO, res); finish(); return true; default: return super.onOptionsItemSelected(item); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_thumbnail); selectedImages = new ArrayList<String>(); maxImageSelectCount = getIntent().getIntExtra("maxImageSelectCount", 1); gridView = (GridView) findViewById(R.id.gridView); adapter = new GridAdapter(); gridView.setAdapter(adapter); } class GridAdapter extends BaseAdapter implements OnItemClickListener { private ArrayList<PictureData> list; private TakePhotoClickListener takePhotoClickListener; private PhotoClickListener photoClickListener; private CheckBoxListener checkBoxListener; public GridAdapter() { checkBoxListener = new CheckBoxListener(); list = new ArrayList<PictureData>(); PictureData data = new PictureData(); list.add(data); String str[] = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DATA}; Cursor cursor = ThumbnailActivity.this.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, str, null, null, null); getColumnData(cursor); takePhotoClickListener = new TakePhotoClickListener(); photoClickListener = new PhotoClickListener(); } @Override public int getCount() { return list.size(); } public ArrayList<PictureData> getList() { return list; } public void setList(ArrayList<PictureData> list) { this.list = list; } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { switch (getItemViewType(position)) { case 0: if (convertView == null) { LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate( R.layout.thumbnail_grid_take_photo, parent, false); } convertView.setOnClickListener(takePhotoClickListener); break; case 1: ViewHolder holder; if (convertView == null) { LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.thumbnail_grid, parent, false); holder = new ViewHolder(); holder.imageView = (ImageView) convertView .findViewById(R.id.image); holder.checkBox = (CheckBox) convertView .findViewById(R.id.select); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.checkBox.setTag(list.get(position)); holder.checkBox.setOnCheckedChangeListener(checkBoxListener); holder.imageView.setOnClickListener(photoClickListener); imageLoader.displayImage("file://" + list.get(position).imagePath, holder.imageView, options); break; } return convertView; } private void getColumnData(Cursor cur) { if (cur.moveToLast()) { String image_path; do { image_path = cur.getString(2); // Do something with the values. PictureData data = new PictureData(); data.imagePath = image_path; list.add(data); } while (cur.moveToPrevious()); } } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) } class CheckBoxListener implements OnCheckedChangeListener { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { PictureData pictureData = (PictureData) buttonView.getTag(); pictureData.isSelected = isChecked; if (isChecked) { if (selectedImages.size() >= maxImageSelectCount) { Toast toast = Toast .makeText(ThumbnailActivity.this, String .format("最多可选 %d 张", maxImageSelectCount), Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); buttonView.setChecked(!isChecked); } else { selectedImages.add(pictureData.imagePath); } } else { selectedImages.remove(pictureData.imagePath); } } } class TakePhotoClickListener implements OnClickListener { @Override public void onClick(View v) { takePhotoUri = ImageManager.takePhoto(ThumbnailActivity.this, TAKE_PHOTO); } } class PhotoClickListener implements OnClickListener { @Override public void onClick(View v) { // Intent intent = new Intent(); // /* 开启Pictures画面Type设定为image */ // intent.setType("image/*"); // /* 使用Intent.ACTION_GET_CONTENT这个Action */ // intent.setAction(Intent.ACTION_GET_CONTENT); // /* 取得相片后返回本画面 */ // startActivityForResult(intent, 1); } } @Override public int getItemViewType(int position) { if (position == 0) { return 0; } else { return 1; } } @Override public int getViewTypeCount() { return 2; } class ViewHolder { ImageView imageView; CheckBox checkBox; } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { // 拍照返回 if (requestCode == TAKE_PHOTO) { Intent res = new Intent(); res.setData(takePhotoUri); setResult(TAKE_PHOTO, res); finish(); } } public GridAdapter getAdapter() { return adapter; } public void setAdapter(GridAdapter adapter) { this.adapter = adapter; } class PictureData { String imagePath; boolean isSelected; } }
有兴趣的同学也可以去豌豆荚搜索“布板”或扫描二维码下载android的demo版试用看看,欢迎小伙伴们和我一起讨论交流。
相关文章推荐
- 从零开始打造一个新闻订阅APP之Android篇(一、实现仿微信主界面效果)
- 从零开始打造一个新闻订阅APP之Android篇(二、从“逛”页面谈谈多种格式listview的实现细节)
- 从零开始打造一个新闻订阅APP之爬虫篇(二、实现一个简单的爬虫系统)
- 从零开始打造一个新闻订阅APP之Android篇(三、关于图片加载、展示的那些事)
- 从零开始打造一个新闻订阅APP之服务器篇(二、类时间片轮转算法+redis sorted set 实现“逛”功能)
- 从零开始打造一个新闻订阅APP之爬虫篇(一、背景介绍&需求分析)
- 从零开始打造一个新闻订阅APP之服务器篇(一、系统结构设计&开发流程简介)
- 一个android文本比对app的实现(二)--界面
- android中实现一个APP启动另一个APP并实现类似微信分享
- Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)
- Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)
- Android上实现一个简单的天气预报APP(六) 更新界面数据
- Android上实现一个简单的天气预报APP(七) 切换到新的界面(选择城市界面)
- Android之新闻客服端顶部导航栏Tab点击和左右滑动实现切换界面
- Android之新闻客服端顶部导航栏Tab点击和左右滑动实现切换界面
- Android上实现一个简单的天气预报APP(一) 设计
- Android上实现一个简单的天气预报APP(二) 配置布局
- Android上实现一个简单的天气预报APP(三) 获取网络数据
- Android上实现一个简单的天气预报APP(四) 添加按钮点击响应
- Android上实现一个简单的天气预报APP(五) 解析XML