主界面
去除标题栏
Manifests.xml中设置andriod:theme
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
如果想去除顶部状态栏,可以在单个activity中的setContentView之前增加:
/**
* 通过设置全屏,设置状态栏透明
*
* @param activity
*/
private void fullScreen(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色
Window window = activity.getWindow();
View decorView = window.getDecorView();
//两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
//导航栏颜色也可以正常设置
// window.setNavigationBarColor(Color.TRANSPARENT);
} else {
Window window = activity.getWindow();
WindowManager.LayoutParams attributes = window.getAttributes();
int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
attributes.flags |= flagTranslucentStatus;
// attributes.flags |= flagTranslucentNavigation;
window.setAttributes(attributes);
}
}
}
dialog的创建:
private void showBottomDialog(){
//1、使用Dialog、设置style
final Dialog dialog = new Dialog(this,R.style.DialogTheme);
//2、设置布局
View view = View.inflate(this,R.layout.dialog_buttom,null);
dialog.setContentView(view);
Window window = dialog.getWindow();
//设置弹出位置
window.setGravity(Gravity.BOTTOM);
//设置弹出动画
window.setWindowAnimations(R.style.main_menu_animStyle);
//设置对话框大小
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
dialog.show();
dialog.findViewById(R.id.tv_take_photo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.findViewById(R.id.tv_take_pic).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
}
dialog主题设置(styles.xml中):
<style name="DialogTheme" parent="@android:style/Theme.Dialog">
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 遮罩层 -->
<item name="android:backgroundDimAmount">0.5</item>
</style>
dialog的xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff">
<TextView
android:id="@+id/tv_take_photo"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="take photo"
android:gravity="center"
android:textSize="16sp"
android:background="?android:attr/selectableItemBackground"
android:textColor="@android:color/background_dark"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorbghomebg"/>
<TextView
android:id="@+id/tv_take_pic"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="select from album"
android:gravity="center"
android:textSize="16sp"
android:background="?android:attr/selectableItemBackground"
android:textColor="@android:color/background_dark"/>
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:background="@color/colorbghomebg"/>
<TextView
android:id="@+id/tv_cancel"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="cancel"
android:gravity="center"
android:textSize="16sp"
android:textColor="@android:color/background_dark"/>
</LinearLayout>
弹出动画设置(style.xml中增加一个名为main_menu_animStyle的样式):
<!-- dialog的动画 -->
<style name="main_menu_animStyle">
<item name="android:windowEnterAnimation">@anim/dialog_in_anim</item>
<item name="android:windowExitAnimation">@anim/dialog_out_anim</item>
</style>
anmi文件的新建:
在res文件夹右击,new->android resource file->resource type选为animator(如果你需要文件夹名称为anim而不是animator,可以修改directory name为anim,然后在下面选择root element选择动画类型即可):
in_amin.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="0"
android:fromYDelta="1000"
android:toXDelta="0"
android:toYDelta="0" />
</set>
out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="1000" />
</set>
参考了https://blog.csdn.net/xiaozhang0414/article/details/79382316这篇文章
水波纹效果可以参考一下https://www.jianshu.com/p/b8101b96246a
感谢你们的无私分享,省了很多事儿,嘿嘿^V^
接下来是实现拍照模块:
申请动态权限:
//获取系统版本
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
// 激活相机
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 判断存储卡是否可以用,可用进行存储
if (hasSdcard()) {
filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + timeInMillis + ".jpg";
tempFile = new File(filePath);
if (currentapiVersion < 24) {
// 从文件中创建uri
imageUri = Uri.fromFile(tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
} else {
//兼容android7.0 使用共享文件的形式
ContentValues contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, tempFile.getAbsolutePath());
//检查是否有存储权限,以免崩溃
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
Toast.makeText(this, "请开启存储权限", Toast.LENGTH_SHORT).show();
return;
}
imageUri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
}
}
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
判断是否有sd卡
public static boolean hasSdcard () {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
activity接受返回的图片结果
switch (requestCode) {
//打开相机后返回
case PHOTO_REQUEST_CAREMA:
if (resultCode == RESULT_OK) {
/**
* 这种方法是通过内存卡的路径进行读取图片,所以的到的图片是拍摄的原图
*/
displayImage(tempFile.getPath());
Log.i("tag", "拍照图片路径>>>>" + tempFile.getAbsolutePath());
}
break; //打开相册后返回
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
//判断手机系统版本号
if (Build.VERSION.SDK_INT > 19) {
//4.4及以上系统使用这个方法处理图片
handleImgeOnKitKat(data);
} else {
handleImageBeforeKitKat(data);
}
}
break;
}
图片的处理以及展示:
/**
* 拍完照和从相册获取玩图片都要执行的方法(根据图片路径显示图片)
*/
private void displayImage (String imagePath) {
allImagePaths.add(imagePath);
if (!TextUtils.isEmpty(imagePath)) {
//orc_bitmap = BitmapFactory.decodeFile(imagePath);//获取图片
orc_bitmap = comp(BitmapFactory.decodeFile(imagePath)); //压缩图片
ImgUpdateDirection(imagePath);//显示图片,并且判断图片显示的方向,如果不正就放正
} else {
Toast.makeText(this, "图片获取失败", Toast.LENGTH_LONG).show();
}
}
图片压缩:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//设置缩放比例
newOpts.inPreferredConfig = Bitmap.Config.RGB_565;//降低图片从ARGB888到RGB565
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
修饰图片:
int digree = 0;//图片旋转的角度
//根据图片的URI获取图片的绝对路径
Log.i("tag", ">>>>>>>>>>>>>开始");
//String filepath = ImgUriDoString.getRealFilePath(getApplicationContext(), uri);
Log.i("tag", "》》》》》》》》》》》》》》》" + filepath);
//根据图片的filepath获取到一个ExifInterface的对象
ExifInterface exif = null;
try {
exif = new ExifInterface(filepath);
Log.i("tag", "exif》》》》》》》》》》》》》》》" + exif);
if (exif != null) {
// 读取图片中相机方向信息
int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
// 计算旋转角度
switch (ori) {
case ExifInterface.ORIENTATION_ROTATE_90:
digree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
digree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
digree = 270;
break;
default:
digree = 0;
break;
}
}
//如果图片不为0
if (digree != 0) {
// 旋转图片
Matrix m = new Matrix();
m.postRotate(digree);
orc_bitmap = Bitmap.createBitmap(orc_bitmap, 0, 0, orc_bitmap.getWidth(),
orc_bitmap.getHeight(), m, true);
}
if (orc_bitmap != null) {
bitmapList.add(orc_bitmap);
if(bitmapList.size()>0){
gridPhotoAdapter = new PhotoAdapter(this,bitmapList);
rcvPhoto.setLayoutManager(new GridLayoutManager(this,3));
rcvPhoto.setAdapter(gridPhotoAdapter);
}
// ivAddImage.setImageBitmap(orc_bitmap);
}
} catch (IOException e) {
e.printStackTrace();
exif = null;
}
展示图片的RecyclerView
public class PhotoAdapter extends RecyclerView.Adapter<PhotoAdapter.VH> {
private Context context;
private List<Bitmap> bitmapList = new ArrayList<>(); //添加图片
public PhotoAdapter (Context context, List<Bitmap> bitmapList) {
this.context = context;
this.bitmapList = bitmapList;
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_photo,parent,false);
return new VH(v);
}
@Override
public void onBindViewHolder(@NonNull VH holder, int position) {
holder.imageView.setImageBitmap(bitmapList.get(position));
}
@Override
public int getItemCount() {
return bitmapList.size();
}
public class VH extends RecyclerView.ViewHolder {
private ImageView imageView;
public VH(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.iv_item_photo);
}
}
}
item_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<ImageView
android:id="@+id/iv_item_photo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
嗯 大概到这里就是结束了,这是一篇很详细的介绍,也是给自己备忘,老是丢三落四,嘿嘿^V^
如果你喜欢或者有什么想法,可以评论或者微信哦~
点个赞给个关注再走吧 Thanks♪(・ω・)ノ