效果图如下:
Demo1
1.高斯模糊实现毛玻璃效果
/*
* @param
* 根据imagepath获取bitmap
* 得到本地或者网络上的bitmap url - 网络或者本地图片的绝对路径,比如:
*
* A.网络路径: url="http://.png" ;
*
* B.本地路径:url="file://.png";
*
* C.支持的图片格式 ,png, jpg,bmp,gif等等
* @return
*/
public static int IO_BUFFER_SIZE = 2 * 1024;
public static Bitmap getBitmapToBlur(String url, int scaleRatio) {
int blurRadius = 5;//通常设置为8就行。
if (scaleRatio <= 0) {
scaleRatio = 10;
}
Bitmap originBitmap = null;
InputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copy(in, out);
out.flush();
byte[] data = dataStream.toByteArray();
originBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,
originBitmap.getWidth() / scaleRatio,
originBitmap.getHeight() / scaleRatio,
false);
Bitmap blurBitmap = doBlur(scaledBitmap, blurRadius);
return blurBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static void copy(InputStream in, OutputStream out)
throws IOException {
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
// 把本地图片毛玻璃化
public static Bitmap bitmapToBlur(Bitmap originBitmap, int scaleRatio) {
// int scaleRatio = 10;
// 增大scaleRatio缩放比,使用一样更小的bitmap去虚化可以到更好的得模糊效果,而且有利于占用内存的减小;
int blurRadius = 5;
//增大blurRadius,可以得到更高程度的虚化,不过会导致CPU更加intensive
/* 其中前三个参数很明显,其中宽高我们可以选择为原图尺寸的1/10;
第四个filter是指缩放的效果,filter为true则会得到一个边缘平滑的bitmap,
反之,则会得到边缘锯齿、pixelrelated的bitmap。
这里我们要对缩放的图片进行虚化,所以无所谓边缘效果,filter=false。*/
if (scaleRatio <= 0) {
scaleRatio = 10;
}
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,
originBitmap.getWidth() / scaleRatio,
originBitmap.getHeight() / scaleRatio,
false);
Bitmap blurBitmap = doBlur(scaledBitmap, blurRadius);
return blurBitmap;
}
2.takephoto照片选择器
/**
* 上传单张图片
*
* @param context
* @param takePhoto
* @param type type=0 不裁剪 1 1:1裁剪 2 4:3裁剪 3 16:9裁剪
*/
public static void uploadPhoto(Context context, final TakePhoto takePhoto, final int type) {
final DialogVertical cameraDialog = buildDialogVertical(context, "选择照片", "拍照", "从手机相册选择");
final File file = new File(FileUtil.IMG_FILE_PATH + "/" + System.currentTimeMillis() + FileUtil.JPG_SUFFIX);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
final Uri imageUri = Uri.fromFile(file);
configCompress(takePhoto);
configTakePhotoOption(takePhoto);
cameraDialog.setOnBtn1Listener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (type!=0) {
takePhoto.onPickFromCaptureWithCrop(imageUri, getCropOptions(type));
} else {
takePhoto.onPickFromCapture(imageUri);
}
cameraDialog.dismiss();
}
});
cameraDialog.setOnBtn2Listener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (type!=0) {
takePhoto.onPickFromGalleryWithCrop(imageUri, getCropOptions(type));
} else {
takePhoto.onPickFromGallery();
}
cameraDialog.dismiss();
}
});
cameraDialog.show();
}
//裁剪
private static CropOptions getCropOptions(int type) {
boolean withWonCrop = false;
CropOptions.Builder builder = new CropOptions.Builder();
switch (type) {
case 1:
builder.setAspectX(1).setAspectY(1);
break;
case 2:
builder.setAspectX(4).setAspectY(3);
break;
case 3:
builder.setAspectX(16).setAspectY(9);
break;
}
builder.setWithOwnCrop(withWonCrop);
return builder.create();
}
3.头像放大预览使用共享元素动画
public class ShareElementManager {
private final long ANIMATOR_DURATION = 300;
private long mDuration = ANIMATOR_DURATION;
private ShareElementBean mInfo;
private AnimatorListenerAdapter mListener;
private ViewPropertyAnimator mAnimator;
private Interpolator mInterpolator;
private boolean mEnter;
private Context mContext;
private View mBgView;
public ShareElementManager(ShareElementBean info, Context context, View bgView) {
mInfo = info;
mContext = context;
mBgView = bgView;
}
/**
* convert target ImageView info and if enter animation to init
*
* @param tarView the second page share view
* @return Class self
*/
public ShareElementManager convert(final ImageView tarView) {
if (mInfo == null) {
throw new NullPointerException("ShareElementBean must not null");
}
tarView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
tarView.getViewTreeObserver().removeOnPreDrawListener(this);
mInfo.convertTargetInfo(tarView, mContext);
//init
if (mEnter) {
tarView.setPivotX(mInfo.getPivotX());
tarView.setPivotY(mInfo.getPivotY());
tarView.setTranslationX(mInfo.getCenterOffsetX());
tarView.setTranslationY(mInfo.getCenterOffsetY());
tarView.setScaleX(mInfo.getScaleX());
tarView.setScaleY(mInfo.getScaleY());
mAnimator = tarView.animate();
start();
startBackgroundAlphaAnimation(mBgView, new ColorDrawable(ContextCompat.getColor(mContext, R.color.white)));
}
return true;
}
});
return this;
}
public ShareElementManager setDuration(long duration) {
mDuration = duration;
return this;
}
public ShareElementManager setListener(AnimatorListenerAdapter listener) {
mListener = listener;
return this;
}
public ShareElementManager setInterpolator(Interpolator interpolator) {
mInterpolator = interpolator;
return this;
}
private void start() {
mAnimator.setDuration(mDuration)
.scaleX(1.0f)
.scaleY(1.0f)
.translationX(0)
.translationY(0);
if (mListener != null) {
mAnimator.setListener(mListener);
}
if (mInterpolator != null) {
mAnimator.setInterpolator(mInterpolator);
}
mAnimator.start();
}
public void startEnterAnimator() {
mEnter = true;
}
public void startExitAnimator() {
mEnter = false;
mAnimator.setDuration(mDuration)
.scaleX(mInfo.getScaleX())
.scaleY(mInfo.getScaleY())
.translationX(mInfo.getCenterOffsetX())
.translationY(mInfo.getCenterOffsetY());
if (mListener != null) {
mAnimator.setListener(mListener);
}
if (mInterpolator != null) {
mAnimator.setInterpolator(mInterpolator);
}
mAnimator.start();
startBackgroundAlphaAnimation(mBgView, new ColorDrawable(ContextCompat.getColor(mContext, R.color.white)), 255, 0);
}
private void startBackgroundAlphaAnimation(final View bgView, final ColorDrawable colorDrawable, int... value) {
if (bgView == null)
return;
if (value == null || value.length == 0) {
value = new int[]{0, 255};
}
ObjectAnimator animator = ObjectAnimator.ofInt(colorDrawable, "alpha", value);
animator.setDuration(mDuration);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
bgView.setBackground(colorDrawable);
}
});
animator.start();
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mImageView.setTransitionName("image");
} else {
ShareElementBean info= getIntent().getExtras().getParcelable("image");
mShareElement = new ShareElementManager(info, this, mImageView.getRootView());
mShareElement.convert(mImageView)
.setDuration(1000)
.setInterpolator(new LinearInterpolator())
.startEnterAnimator();
}
4.仿淘宝/京东地址选择
// 设置点击之后的事件
holder.mTitle.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 点击 分类别
switch (tabSelectPosition) {
case 0:
mSelectProvice = mRvData.get(position);
// 清空后面两个的数据
mSelectCity = null;
mSelectDistrict = null;
mSelectCityPosition = 0;
mSelectDistrictPosition = 0;
mTabLayout.getTabAt(1).setText(defaultCity);
if (pickerType==0) {
mTabLayout.getTabAt(2).setText(defaultDistrict);
}
// 设置这个对应的标题
mTabLayout.getTabAt(0).setText(mSelectProvice.getN());
// 跳到下一个选择
mTabLayout.getTabAt(1).select();
// 灰掉确定按钮
mTvSure.setTextColor(defaultSureUnClickColor);
mSelectProvicePosition = position;
break;
case 1:
mSelectCity = mRvData.get(position);
// 清空后面一个的数据
mSelectDistrict = null;
mSelectDistrictPosition = 0;
if (pickerType==0) {
mTabLayout.getTabAt(2).setText(defaultDistrict);
}
// 设置这个对应的标题
mTabLayout.getTabAt(1).setText(mSelectCity.getN());
if (pickerType == 0) {
// 跳到下一个选择
mTabLayout.getTabAt(2).select();
// 灰掉确定按钮
mTvSure.setTextColor(defaultSureUnClickColor);
} else {
mTvSure.setTextColor(defaultSureCanClickColor);
}
mSelectCityPosition = position;
break;
case 2:
mSelectDistrict = mRvData.get(position);
mTabLayout.getTabAt(2).setText(mSelectDistrict.getN());
notifyDataSetChanged();
// 确定按钮变亮
mTvSure.setTextColor(defaultSureCanClickColor);
mSelectDistrictPosition = position;
break;
}
}
});
其他文章链接地址:
(二)仿京东顶部伸缩渐变丶自定义viewpager指示器丶viewpager3D回廊丶recyclerview瀑布流
(三)RxJava2常用操作符merge、flatmap、zip--结合MVP架构讲解
(四)仿支付宝首页顶部伸缩滑动/中间层下拉刷新
(五)TabLayout+ViewPager悬浮吸顶及刷新数量动画显示
(六)仿QQ首页drawer/侧滑删除/浮动imgaeView/角标拖拽
(七)仿微信发布朋友圈拖拽删除
将持续更新.. 不喜勿喷,仅个人分享,希望能帮助到你
源码地址:Github传送门