Android 图片选择器
图片选择器,遍历系统所有图片并显示,点击查看大图,长按选中,并将结果返回
字体颜色res/color建立text_selecor.xml
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/white" android:state_enabled="true"/>
- <item android:color="@android:color/darker_gray" android:state_enabled="false"/>
- </selector>
text_selector.xml
图片选择按钮
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:drawable="@mipmap/sel_check"/>
- <item android:state_checked="false" android:drawable="@mipmap/sel_nor"/>
- </selector>
item_selector
遍历之后将所有图片显示
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:background="@android:color/background_dark"
- android:layout_height="match_parent">
- <ImageView
- android:id="@+id/iv_img"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="centerCrop"
- android:layout_margin="10dp"
- android:src="@mipmap/camera"/>
- <CheckBox
- android:id="@+id/cb_btn"
- android:layout_margin="15dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:button="@drawable/item_selector"/>
- </RelativeLayout>
item_image.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/activity_main"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="com.example.lesson10_picselectordemo.MainActivity">
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/holo_blue_dark"
- android:padding="10dp">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerHorizontal="true"
- android:text="图片选择"
- android:textColor="@android:color/white"
- android:textSize="18sp" />
- <TextView
- android:id="@+id/tv_finish"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:enabled="false"
- android:text="完成"
- android:textColor="@color/text_selector" />
- </RelativeLayout>
- <GridView
- android:id="@+id/gv_image"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:numColumns="4"/>
- </LinearLayout>
activity_main.xml
适配器,当适配数据类型不确定时,可以使用泛型.继承BaseAdapter都要重写那几个方法,这里将他们抽出来
- /**
- * 适配数据类型不确定,可以使用泛型
- * 也可以是使用extends限定泛型,比如接口IGetName有个getName()方法,只要T继承IGetName实现方法,就可以使用该方法
- * Created by Administrator on 2016/10/24 0024.
- */
- public abstract class ListItemAdapter<T> extends BaseAdapter {
- //适配器需要上下文,数据
- //使用ptotected修饰符,使子类也可以用
- protected Context mContext;
- protected List<T> mList;
- public ListItemAdapter(Context mContext,List<T> mList){
- this.mContext = mContext;
- this.mList = mList;
- }
- @Override
- public int getCount() {
- return mList.size();
- }
- @Override
- public T getItem(int position) {
- return mList.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- }
ListItemAdapter.java
然后ImageAdapter只要继承ListItemAdapter重写getView即可
- public class ImageAdapter extends ListItemAdapter<File> {
- private boolean select = false;
- public void open(int position){
- select = true;
- booleanArray.put(position,true);
- if(onImageCheckedListener != null){
- onImageCheckedListener.onImageChecked(true);
- }
- this.notifyDataSetChanged();
- }
- public void close(){
- select = false;
- booleanArray.clear();
- this.notifyDataSetChanged();
- }
- public ImageAdapter(Context mContext, List<File> mList) {
- super(mContext, mList);
- }
- @Override
- public int getCount() {
- //多出来的第一张为照相机,点击进入照相机
- return super.getCount()+1;
- }
- /**
- * 这里布局重用,使用checkbox会导致很多问题,
- * 勾选了一个,下拉之后发现下面也被勾选了一个
- * 这时,我们可以使用HashMap<Integer,Boolean>,是否被勾选
- *
- * 这里推荐使用另外一个类SparseBooleanArray
- *
- * @param position
- * @param convertView
- * @param parent
- * @return
- */
- SparseBooleanArray booleanArray = new SparseBooleanArray();
- public SparseBooleanArray getBooleanArray() {
- return booleanArray;
- }
- @Override
- public View getView(final int position, View convertView, ViewGroup parent) {
- ViewHolder viewHolder;
- if(convertView == null){
- convertView = View.inflate(mContext,R.layout.item_image,null);
- viewHolder = new ViewHolder(convertView);
- convertView.setTag(viewHolder);
- }
- viewHolder = (ViewHolder) convertView.getTag();
- if(position == 0){
- //照相机
- viewHolder.iv_img.setImageResource(R.mipmap.camera);
- viewHolder.cb_btn.setVisibility(View.GONE);
- }else{
- //设置图片
- viewHolder.iv_img.setImageURI(Uri.fromFile(mList.get(position - 1)));
- if(select) {
- viewHolder.cb_btn.setVisibility(View.VISIBLE);
- //是否需要勾选呢?
- Boolean b = booleanArray.get(position);
- if (b == null || b == false) {
- viewHolder.cb_btn.setChecked(false);
- } else {
- viewHolder.cb_btn.setChecked(true);
- }
- //checkbox不能设置onCheckChange监听,因为上面setChecked导致下面isCheck也会跟着变化
- /*viewHolder.cb_btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- booleanArray.put(position,isChecked);
- }
- });*/
- viewHolder.cb_btn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //position有可能不存在,为空,这里必须给Boolean
- Boolean b = booleanArray.get(position);
- if (b == null || b == false) {
- b = true;
- } else {
- b = false;
- }
- booleanArray.put(position, b);
- //判断所有boolean ,如果没有一个true,则关闭
- for (int i = 0; i <booleanArray.size() ; i++) {
- //i一定存在,所以可以给boolean
- boolean isChecked = booleanArray.get(booleanArray.keyAt(i));
- if(isChecked){
- //说明有被勾选的值
- if(onImageCheckedListener != null){
- onImageCheckedListener.onImageChecked(true);
- }
- return;
- }
- }
- //没有被勾选的值,
- if(onImageCheckedListener != null)
- onImageCheckedListener.onImageChecked(false);
- //关闭
- close();
- }
- });
- }else {
- viewHolder.cb_btn.setVisibility(View.GONE);
- }
- }
- return convertView;
- }
- //回调方法
- //写在需要执行方法的地方
- //实现,在需要返回的地方
- public interface OnImageCheckedListener{
- void onImageChecked(boolean b);
- }
- private OnImageCheckedListener onImageCheckedListener;
- //alt + insert
- public void setOnImageCheckedListener(OnImageCheckedListener onImageCheckedListener) {
- this.onImageCheckedListener = onImageCheckedListener;
- }
- class ViewHolder{
- ImageView iv_img;
- CheckBox cb_btn;
- public ViewHolder(View convertView){
- iv_img = (ImageView) convertView.findViewById(R.id.iv_img);
- int width = mContext.getResources().getDisplayMetrics().widthPixels / 4 -2;
- RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width,width);
- iv_img.setLayoutParams(params);
- cb_btn = (CheckBox) convertView.findViewById(R.id.cb_btn);
- }
- }
- }
ImageAdapter.java
点击查看大图
- public class ShowBigImage extends AppCompatActivity{
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- ImageView img = new ImageView(this);
- File file = (File) getIntent().getSerializableExtra("img");
- img.setImageURI(Uri.fromFile(file));
- setContentView(img);
- }
- }
ShowBigImage.java
- public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, ImageAdapter.OnImageCheckedListener, View.OnClickListener {
- private static final int CAMERA_CODE = 1;
- //SD卡所有图片
- List<File> filesList = new ArrayList<>();
- ProgressDialog dialog;
- GridView gv_image;
- TextView tv_finish;
- ImageAdapter adapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //加载数据
- loadData();
- //初始化视图
- initView();
- }
- private void initView() {
- gv_image = (GridView) findViewById(R.id.gv_image);
- tv_finish = (TextView) findViewById(R.id.tv_finish);
- adapter = new ImageAdapter(this,filesList);
- tv_finish.setOnClickListener(this);
- adapter.setOnImageCheckedListener(this);
- gv_image.setAdapter(adapter);
- //点击图片查看大图
- gv_image.setOnItemClickListener(this);
- //长按选择图片
- gv_image.setOnItemLongClickListener(this);
- }
- public ProgressDialog showDialog(){
- //显示Dialog
- dialog = new ProgressDialog(this);
- dialog.setTitle("加载数据");
- dialog.setMessage("正在加载数据,请稍等...");
- dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
- dialog.show();
- return dialog;
- }
- public void loadData(){
- dialog = showDialog();
- //数据加载不能阻塞UI
- //在子线程中加载
- new Thread(){
- @Override
- public void run() {
- super.run();
- //开始递归遍历SD卡根目录
- /*public static File getExternalStorageDirectory() {
- throwIfUserRequired();
- return sCurrentUser.getExternalDirs()[0];//获取第0张SD卡如果想要其他SD卡,只要重写这个方法即可
- }*/
- File SDDir = Environment.getExternalStorageDirectory();
- getFiles(SDDir);
- //数据加载完毕,要关闭Dialog
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- dialog.dismiss();
- //刷新适配器
- adapter.notifyDataSetChanged();
- }
- });
- }
- }.start();
- }
- public void getFiles(File dir){
- File[] files = dir.listFiles();
- if(files == null){
- return;
- }
- //开始遍历
- for (File file : files) {
- if(file.isDirectory()){
- getFiles(file);
- }else{
- if(file.getName().endsWith("jpg") || file.getName().endsWith("png")){
- filesList.add(file);
- }
- }
- }
- }
- File cameraFile;
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- //点击查看大图
- if(position == 0){
- //getAbsolutePath默认没有带"/"
- cameraFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/DCIM/"+System.currentTimeMillis()+".png");
- //打开照相机
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- //图片保存位置
- intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
- startActivityForResult(intent,CAMERA_CODE);
- }else{
- //打开大图
- File file = filesList.get(position - 1);
- //带数据点开大图
- Intent intent = new Intent(this,ShowBigImage.class);
- intent.putExtra("img",file);
- startActivity(intent);
- }
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if(requestCode == requestCode && resultCode == RESULT_OK){
- //照相机的图片永远放在第一个
- filesList.add(0,cameraFile);
- adapter.notifyDataSetChanged();
- }
- }
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- //长按选择图片
- //照相机不能长按
- if(position == 0){
- return false;
- }else{
- adapter.open(position);
- }
- return true;
- }
- @Override
- public void onImageChecked(boolean b) {
- //b代表适配器中有没有被勾选的值
- tv_finish.setEnabled(b);
- }
- @Override
- public void onClick(View v) {
- //选择的图片
- //不能使用泛型,ArrayList才实现了序列化,List没有实现
- ArrayList<File> resultList = new ArrayList<>();
- //点击完成,带参返回
- //需要知道哪些数据被选中
- //通过是是适配器中的boolArray的为true的选中项来加载file
- SparseBooleanArray booleanArray = adapter.getBooleanArray();
- for (int i = 0; i <booleanArray.size() ; i++) {
- boolean isSelected = booleanArray.get(booleanArray.keyAt(i));
- if(isSelected){
- int position = booleanArray.keyAt(i);
- //剔除掉第一张照相机图片
- resultList.add(filesList.get(position-1));
- }
- }
- Intent intent = new Intent();
- intent.putExtra("list",resultList);
- //返回数据
- setResult(RESULT_OK,intent);
- finish();
- }
- }
MainActivity.java
AndroidManifest.xml设置权限,注册活动
设置intent-filter <action> 并设置出口exported
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.lesson10_picselectordemo">
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- <application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
- <activity android:name=".MainActivity"
- android:exported="true">
- <intent-filter>
- <action android:name="SelectPicture"/>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity android:name=".ShowBigImage"/>
- </application>
- </manifest>
AndroidManifest.xml
测试类
点击Buttong,打开图片选择器
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/activity_main"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.example.lesson10_picselectordemotest.MainActivity">
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:onClick="toPicSelectorDemo"
- android:layout_centerInParent="true"
- android:text="图片选择器启动另一个Module" />
- </RelativeLayout>
activity_main.xml
- public class MainActivity extends AppCompatActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void toPicSelectorDemo(View v){
- startActivityForResult(new Intent("SelectPicture"),1);
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if(resultCode == RESULT_OK){
- ArrayList<File> file = (ArrayList<File>) data.getSerializableExtra("list");
- Toast.makeText(this,file.toString(),Toast.LENGTH_SHORT).show();
- }
- }
- }
MainActivity.java
Android 图片选择器的更多相关文章
- Android图片选择器--仿QQ
当做一款APP,需要选择本地图片时,首先考虑的无疑是系统相册,但是Android手机五花八门,再者手机像素的提升,大图无法返回等异常因数,导致适配机型比较困难,微信.QQ都相继的在自己的APP里集成了 ...
- 016 Android 图片选择器(在选中和未选中的过程中,切换展示图片)
1.目标效果 在选中和未选中的过程中,切换展示图片 2.实现方法 (1)在app--->res--->drawable 右击drawable文件夹右键,new ---->drawab ...
- Android图片选择器
1.概述 应公司项目需求,要做一个图片选择器,网上搜索了一些源码,我在别人的基础上进行了修改,另外页面也进行了重整,我的是先加载图片文件夹列表,然后再进入选择图片. 参考博客地址 ...
- Android之仿微信图片选择器
先上效果图.第一张图显示的是“相机”文件夹中的所有图片:通过点击多张图片可以到第二张图所示的效果(被选择的图片会变暗,同时选择按钮变亮):点击最下面的那一栏可以到第三张图所示的效果(显示手机中所有包含 ...
- [转]Android 超高仿微信图片选择器 图片该这么加载
快速加载本地图片缩略图的方法: 原文地址:Android 超高仿微信图片选择器 图片该这么加载 其示例代码下载: 仿微信图片选择器 ImageLoader
- Android 高级UI设计笔记06:仿微信图片选择器(转载)
仿微信图片选择器: 一.项目整体分析: 1. Android加载图片的3个目标: (1)尽可能的去避免内存溢出. a. 根据图片的显示大小去压缩图片 b. 使用缓存对我们图片进行管理(LruCache ...
- Android 超高仿微信图片选择器 图片该这么加载
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39943731,本文出自:[张鸿洋的博客] 1.概述 关于手机图片加载器,在当今像 ...
- Android 超高仿微信图片选择器 图片该这么载入
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39943731,本文出自:[张鸿洋的博客] 1.概述 关于手机图片载入器,在当今像 ...
- Android开发之高仿微信图片选择器
记得刚开始做Andriod项目那会,经常会碰到一些上传图片的功能需求,特别是社交类的app,比如用户头像,说说配图,商品配图等功能都需要让我们到系统相册去选取图片,但官方却没有提供可以选取多张图片的相 ...
随机推荐
- CentOS 6.5 IP 设置
DEVICE=eth0TYPE=EthernetUUID=7d6d54e0-054d-472b-8cc1-080f16ef36c1ONBOOT=yesNM_CONTROLLED=yesBOOTPROT ...
- JS自执行函数的几种写法
一:整体写在一个括号中 代码如下: (function Show(){alert("hello");}()) 二:function函数整体外加括号 代码如下: (function ...
- dedecms设置文章分页后,标题会带有序号的解决方法
至于删除分页后标题后面的序号,找到include/arc.archives.class.php 打开,找到 if($i>1) $this->Fields['title'] = $this- ...
- wordpress 更改 "Home"为"首页"
要怎麼更改wordpress的 menu上 那一直顯示著"首頁"的頁籤呢這問題我實在是找好久終於給我找到 在 wp-includes 的 post-template.php 這檔案 ...
- javascript 设为首页 | 加入收藏夹 JS代码
我们介绍一个可兼容所有浏览器的加入收藏代码代码,大概原理是这样的我们根据获取用户navigator.userAgent.toLowerCase()信息来判断浏览器,根据浏览器是否支持加入收藏js命令, ...
- 分享29个超赞的响应式Web设计
原文自:http://www.csdn.net/article/2013-01-16/2813678-responsive-design-websites 最近几年,响应式Web设计不断印入人们眼帘, ...
- jQuery简单的轮播特效
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 关于pcre正则表达式库libpcre
gcc 4.8中已经包含了std regex的头文件 可是没有实现,所以链接是失败的 gcc 4.9完整的支持了c++ 11的regex. 在4.9以前,可以寻求boost的regex. 不过,我更熟 ...
- install ubuntu
http://wenku.baidu.com/link?url=Cq6nB1ArObV1liMUT13ZB9o16NQ0-FpELt37R6NuPvz7zoKlz14Mu_k-8CwqQodWpRC8 ...
- WAMP集成环境
WAMP Windows下的Apache+Mysql/MariaDB+Perl/PHP/Python,一组常用来搭建动态网站或者服务器的开源软件,本身都是各自独立的程序,但是因为常被放在一起使用,拥有 ...