下面效果图:
1.点击进行图片选择
2.可以进行图片的放大或缩小
3.可以进行拍照等
就是一个图片进行选择跳转
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_IMAGE = 411;
ImageView iv;
//本地头像地址
String path;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//跳到选择图片页面
startActivityForResult(new Intent(getBaseContext(), SelectImageActivity.class), REQUEST_IMAGE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE && resultCode == RESULT_OK) {
path = data.getStringExtra("path");
File file = new File(path);
iv.setImageURI(Uri.fromFile(file));
}
}
}
//这里进行手机储存卡中照片的读取显示,存储,选择等一些操作
public class SelectImageActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private static final int REQUEST_CAMERA = 102;
public static final String IMAGE_PATH = Environment.getExternalStorageDirectory() + "/example";
TextView tv_cancel;
TextView tv_title;
TextView tv_finish;
ScrollView sv_context;
ScaleImageView siv_pic;
ScrollGridView sgv_content;
RelativeLayout rl_title;
//GridView adapter 的数据源
List imageList = new ArrayList<>();
CameraAdapter adapter;
String path = null;
String name = "";
private List dirList = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_image);
tv_cancel = (TextView) findViewById(R.id.tv_cancel);
tv_title = (TextView) findViewById(R.id.tv_title);
tv_finish = (TextView) findViewById(R.id.tv_finish);
sv_context = (ScrollView) findViewById(R.id.sv_context);
siv_pic = (ScaleImageView) findViewById(R.id.siv_pic);
sgv_content = (ScrollGridView) findViewById(R.id.sgv_content);
rl_title = (RelativeLayout) findViewById(R.id.rl_title);
tv_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
tv_title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showPopwindow();
}
});
tv_finish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
goBack();
}
});
new File(IMAGE_PATH).mkdirs();
List files = FileUtils.getAllImageFile();
// imageList.addAll(files);
Log.e("----","files.size()="+files.size());
MyApp.getInstance().setImgList(files);
initView();
}
private void goBack() {
new Thread() {
@Override
public void run() {
path = IMAGE_PATH + "/" + System.currentTimeMillis() + ".png";
siv_pic.getImagePath(path);
setResult(RESULT_OK, getIntent().putExtra("path", path));
finish();
}
}.start();
}
private void showPopwindow() {
tv_title.setSelected(true);
ShowDirPopWindow popwindow = new ShowDirPopWindow(this, dirList, new ShowDirPopWindow.OnPopwindowItemClick() {
@Override
public void onClick(String dirName) {
//需要开始修改dir
if (dirName.equals("所有图片")) {
for (ShowDirPopWindow.Dir dir : dirList) {
dir.setCheck(false);
}
dirList.get(0).setCheck(true);
imageList.clear();
imageList.addAll(MyApp.getInstance().getImgList());
tv_title.setText("所有图片");
} else {
//不是第0个所有图片被选中
dirList.get(0).setCheck(false);
for (int i = 1; i < dirList.size(); i++) {
ShowDirPopWindow.Dir dir = dirList.get(i);
//遍历判断 是否和用户选中的名称相同
if (dir.getFirstImage().getParent().equals(dirName)) {
dir.setCheck(true);
} else
dir.setCheck(false);
}
//开始遍历本地文件
//C:/aaa.jpg c:/aaaa/ddd/bbb.jpg
imageList.clear();
for (File file : MyApp.getInstance().getImgList()) {
if (file.getAbsolutePath().contains(dirName)) {
imageList.add(file);
}
}
tv_title.setText(new File(dirName).getName());
}
adapter.notifyDataSetChanged();
}
});
popwindow.showAsDropDown(rl_title, 0, 0);
popwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
tv_title.setSelected(false);
}
});
}
protected void initView() {
//判断本地图片是否缓存成功
if (MyApp.getInstance().getImgList() == null) {
Toast.makeText(getBaseContext(),"图片正在加载中,请稍后",Toast.LENGTH_SHORT).show();
finish();
}
//第一次加载所有图片
imageList.addAll(MyApp.getInstance().getImgList());
adapter = new CameraAdapter(this, imageList);
sgv_content.setAdapter(adapter);
sgv_content.setOnItemClickListener(this);
siv_pic.setImageBitmap(BitmapFactory.decodeFile(imageList.get(0).getAbsolutePath()));
initDir();
}
private void initDir() {
//key == dir名称
//value = dir中有多少图片
HashMap sizeMap = new HashMap<>();
HashMap firstMap = new HashMap<>();
//第一次添加
dirList.add(new ShowDirPopWindow.Dir(imageList.get(0), "所有图片", imageList.size(), true));
// C:/aaa/bb.jpg; C:/aaa/sadf.jpg firstImage
for (File file : imageList) {
//拿 file在HashMap中的数量
Integer size = sizeMap.get(file.getParentFile().getAbsolutePath());
//null
if (size == null) {
sizeMap.put(file.getParentFile().getAbsolutePath(), 1);
//图片
firstMap.put(file.getParentFile().getAbsolutePath(), file.getAbsolutePath());
} else {
sizeMap.put(file.getParentFile().getAbsolutePath(), size + 1);
}
}
Set set = sizeMap.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
String key = it.next();
int size = sizeMap.get(key);
String firstImage = firstMap.get(key);
String name = new File(key).getName();
File firstFile = new File(firstImage);
ShowDirPopWindow.Dir dir = new ShowDirPopWindow.Dir(firstFile, name, size, false);
dirList.add(dir);
}
}
@Override
public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
if (i != 0) {
view.setSelected(true);
siv_pic.setImageBitmap(BitmapFactory.decodeFile(imageList.get(i - 1).getAbsolutePath()));
sv_context.fullScroll(View.FOCUS_UP);
} else {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
name = System.currentTimeMillis() + ".jpg";
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(IMAGE_PATH, name)));
startActivityForResult(intent, REQUEST_CAMERA);
}
}
/**
* 得到所有的图片
*/
static class FileUtils {
public static final List getAllImageFile() {
List list = new ArrayList<>();
getDirImage(Environment.getExternalStorageDirectory(), list);
return list;
}
private static void getDirImage(File dir, List list) {
File[] files = dir.listFiles();
if (files == null)
return;
for (File file : files) {
if (file.isDirectory())
getDirImage(file, list);
else {
if (file.getName().endsWith(".png") || file.getName().endsWith(".jpg")) {
list.add(file);
}
}
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) {
path = IMAGE_PATH + "/" + name;
File file = new File(path);
MyApp.getInstance().getImgList().add(file);
siv_pic.setImageBitmap(BitmapFactory.decodeFile(path));
}
}
}
//第一个位置是给手机的照相机的
public class CameraAdapter extends BaseAdapter {
private int selectImage = -1;
private final Context context;
private final List list;
public CameraAdapter(Context context, List list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
@Override
public File getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
view = View.inflate(context, R.layout.item_camera, null);
holder = new ViewHolder(view);
int width = context.getResources().getDisplayMetrics().widthPixels / 3;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, width);
holder.iv_image.setLayoutParams(params);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
if (position == 0) {
holder.iv_image.setImageResource(R.mipmap.icon_camera_pick_ng);
} else {
File file = getItem(position - 1);
holder.iv_image.setImageURI(Uri.fromFile(file));
if (position == selectImage) {
holder.ll_image.setSelected(true);
}
}
return view;
}
class ViewHolder {
ImageView iv_image;
LinearLayout ll_image;
ViewHolder(View view) {
iv_image = view.findViewById(R.id.iv_image);
ll_image = view.findViewById(R.id.ll_image);
}
}
}
public class ScaleImageView extends ImageView {
Bitmap bmp;
Paint paint;
public static final int NONE = 1;
public static final int DRAG = 2;
public static final int SCALE = 3;
private int type = NONE;
//最大缩放
//最小缩放
public static final float MIN = 1f;
public static final float MAX = 3f;
//拖拽点
PointF dragPoint;
//缩放中心点
PointF centerPoint;
//当前缩放的长度
float distance;
Matrix matrix;
//是否画线
boolean isDrawLine;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
isDrawLine = false;
invalidate();
}
};
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isDrawLine) {
for (int i = 1; i < 3; i++) {
canvas.drawLine(0, getHeight() / 3 * i, getWidth(), getHeight() / 3 * i, paint);
canvas.drawLine(getWidth() / 3 * i, 0, getWidth() / 3 * i, getHeight(), paint);
}
}
}
public ScaleImageView(Context context) {
super(context);
init();
}
private void init() {
//必须设置
setScaleType(MATRIX);
matrix = new Matrix(); // 平移,旋转,缩放,倾斜
setImageMatrix(matrix);
paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2);
}
public ScaleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@Override
public void setImageBitmap(Bitmap bm) {
setBackgroundColor(Color.rgb(0x31, 0x33, 0x35));
int sceen = getResources().getDisplayMetrics().widthPixels;
//图片到底有多大
float width = bm.getWidth();
float height = bm.getHeight();
//如果图片的宽高比view小,那么需要放大
if (width < sceen || height < sceen) {
float min = width < height ? width : height;
float rate = sceen / min;
bmp = ThumbnailUtils.extractThumbnail(bm, (int) (width * rate), (int) (height * rate));
if (bm != null)
bm.recycle();
}
super.setImageBitmap(bmp);
matrix = new Matrix();
setImageMatrix(matrix);
}
//在sd卡中的名称
public String getImagePath(String name) {
//在子线程中操作
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getWidth(), Bitmap.Config.ARGB_8888);
//吧屏幕上的绘制进去
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bmp, matrix, null);
canvas.save();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(name);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return name;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
isDrawLine = true;
if (handler.hasMessages(1))
handler.removeMessages(1);
handler.sendEmptyMessageDelayed(1, 2000);
PointF pointf = new PointF(event.getX(), event.getY());
//多指运算
switch (event.getAction() & event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
//点上去 就显示出来
type = DRAG;
dragPoint = new PointF(event.getX(), event.getY());
break;
case MotionEvent.ACTION_POINTER_DOWN:
type = SCALE;
float x1 = event.getX();
float x2 = event.getX(1);
float y1 = event.getY();
float y2 = event.getY(1);
centerPoint = new PointF((x1 + x2) / 2, (y1 + y2) / 2);
distance = getDistance(event);
break;
case MotionEvent.ACTION_POINTER_UP:
//缩放复位
scaleReset();
break;
case MotionEvent.ACTION_UP:
//拖拽复位
dragReset();
type = NONE;
break;
case MotionEvent.ACTION_MOVE:
//根据状态来判断是缩放还是拖拽
if (type == DRAG) {
//当前的位置,移动的距离
matrix.postTranslate(pointf.x - dragPoint.x, pointf.y - dragPoint.y);
dragPoint = new PointF(event.getX(), event.getY());
} else if (type == SCALE) {
float rate = getDistance(event) / distance;
matrix.postScale(rate, rate, centerPoint.x, centerPoint.y);
}
break;
}
setImageMatrix(matrix);
invalidate();
return true;
}
private void scaleReset() {
//matrix 9个值
float[] value = new float[9];
matrix.getValues(value);
if (value[0] < MIN)
matrix.postScale(MIN, MIN, centerPoint.x
, centerPoint.y);
else if (value[0] > MAX)
matrix.postScale(MAX, MAX, centerPoint.x, centerPoint.y);
}
private void dragReset() {
//需要获取图片在哪里
RectF rectf = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
matrix.mapRect(rectf);
Log.e("TAG", "矩形的上" + rectf.top + " 矩形的下" + rectf.bottom + " 矩形的右" + rectf.right + " 矩形的左" + rectf.left);
Log.e("TAG", "view的高度" + getHeight() + " view的宽度" + getWidth());
//水平方向
float x = 0, y = 0;
if (rectf.top > 0) {
y = 0 - rectf.top;
} else if (rectf.bottom < getHeight()) {
y = getHeight() - rectf.bottom;//正 右和下
}
if (rectf.left > 0) {
x = 0 - rectf.left;
} else if (rectf.right < getWidth()) {
x = getWidth() - rectf.right;
}
matrix.postTranslate(x, y);
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
setImageBitmap(BitmapFactory.decodeResource(getResources(), resId));
}
public float getDistance(MotionEvent event) {
float x1 = event.getX();
float x2 = event.getX(1);
float y1 = event.getY();
float y2 = event.getY(1);
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}
//重写事件处理
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
//当父类与自己同时具有同一方向的滑动,会导致子控件无法获取焦点
//ViewPager嵌套ViewPager
//请求父窗体不要拦截事件
getParent().requestDisallowInterceptTouchEvent(true);
return super.dispatchTouchEvent(event);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rl_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/image_title">
<TextView
android:id="@+id/tv_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:text="取消"
android:textColor="@android:color/darker_gray" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:drawablePadding="5dp"
android:drawableRight="@drawable/title_arrow_selector"
android:text="所有图片"
android:textColor="@android:color/darker_gray" />
<TextView
android:id="@+id/tv_finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:text="完成"
android:textColor="@color/image_finish" />
RelativeLayout>
<ScrollView
android:id="@+id/sv_context"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.administrator.myapplication.ScaleImageView
android:id="@+id/siv_pic"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.example.administrator.myapplication.ScrollGridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/sgv_content"
android:numColumns="3"
/>
LinearLayout>
ScrollView>
LinearLayout>
部分代码没有上传,感兴趣的童靴可以下载整个demo:http://download.csdn.net/detail/dr_abandon/9906445
如有不足欢迎探讨,至无所畏惧的你。