上传设置头像
来源:互联网 发布:网络thug life什么意思 编辑:程序博客网 时间:2024/06/05 18:32
大晚上的,夜深人静!闲来无聊!决定再玩一玩头像上传,众所周知,app的个人资料那一页具有更换头像,上传头像的功能,当然,这已经不是什么新鲜事了~有些人就是不喜欢应用自带的那种默认头像,有些其丑无比,就想换成自己喜欢的头像!可以从相册中选图片,也可以调用相机来美美的摆个pose,伸出剪刀手~自拍一张再上传也可以~
本篇博客实现的功能就是点击头像,然后可以换头像!例子中的头像为圆形头像,点击头像后,会从底部弹出一个PopupWindow,然后选择相机或者相册都可以,然后设置头像就行了~当然显示的也是圆形的!ok!不啰嗦了!
package com.example.lenovo.demo.activity;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.ImageView;import android.widget.PopupWindow;import android.widget.Toast;import com.example.lenovo.demo.R;import java.io.File;public class MainActivity extends Activity implements View.OnClickListener{ private ImageView head_portrait_icon; private Button camera,album,cancel; private PopupWindow popupWindow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); icon = (ImageView) findViewById(R.id.icon); icon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showPopupWindow(); } }); } /** * 显示弹窗 */ private void showPopupWindow() { View popupView = View.inflate(MainActivity.this,R.layout.popup_view,null); camera = (Button) popupView.findViewById(R.id.camera); album = (Button) popupView.findViewById(R.id.album); cancel = (Button) popupView.findViewById(R.id.cancel); camera.setOnClickListener(this); album.setOnClickListener(this); cancel.setOnClickListener(this); popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); popupWindow.setFocusable(true); popupWindow.setOutsideTouchable(false); popupWindow.setAnimationStyle(android.R.style.Animation_InputMethod); popupWindow.showAtLocation(popupView, Gravity.BOTTOM,0,0); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.camera: if (!issdkard())break; openCamera(); break; case R.id.album: openAlbum(); break; case R.id.cancel: popupWindow.dismiss(); break; } } /** * 拍照作为头像 */ public void openCamera() { imgFile = new File(destDir, getPhotoFileName()); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imgFile)); startActivityForResult(intent, 1); } public static String SDPATH = Environment.getExternalStorageDirectory() + "/hsyfm/recordimg/"; public static File destDir = new File(SDPATH); // 创建一个以当前系统时间为名称的文件,防止重复 private File imgFile; // 使用系统当前日期加以调整作为照片的名称 private String getPhotoFileName() { Date date = new Date(System.currentTimeMillis()); SimpleDateFormat sdf = new SimpleDateFormat("'PNG'_yyyyMMdd_HHmmss"); return sdf.format(date) + ".png"; }/** * 判断SD卡是否存在 */ private boolean issdkard() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { if (!destDir.exists()) { destDir.mkdirs(); } return true; } else { showToastShort("SD卡不存在"); return false; } } /** * 相册中选择图片作为头像 */ public void openAlbum() { Intent intent = new Intent(Intent.ACTION_PICK, null); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(intent, 2); } /** * Intent请求回调函数 */ protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case 1: if (imgFile.exists()) { startPhotoZoom(Uri.fromFile(imgFile), 300); } break; case 2: if (null != data) { startPhotoZoom(data.getData(), 300); } break; case 3: if (null != data) { Bundle bundle = data.getExtras(); final Bitmap bmp = bundle.getParcelable("data"); saveCropPic(bmp); head_portrait_icon.setImageBitmap(bmp); } break; } } /** * 图片进行裁剪 */ private void startPhotoZoom(Uri uri, int size) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", true); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", size); intent.putExtra("outputY", size); intent.putExtra("return-data", true); startActivityForResult(intent, 3); }// 把裁剪后的图片保存到sdcard上 private void saveCropPic(Bitmap bmp) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); FileOutputStream fis = null; bmp.compress(Bitmap.CompressFormat.PNG, 100, baos); try { fis = new FileOutputStream(imgFile); fis.write(baos.toByteArray()); fis.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != baos) { baos.close(); } if (null != fis) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } upImgFile();//将图片文件上传服务器 } /** * 上传图片到服务器 */ private void upImgFile() { }
至于弹窗的xml布局显示,相信你们都会,就不贴了!CircleImageView呢!网上也有 so many 例子!OK 结束!!算了,还是贴一下圆形的ImageView吧!
—————————————————————————————————————————————————————————————————
首先是自定义属性:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="CircleImageView"> <attr name="riv_corner_radius" format="dimension" /> <attr name="riv_corner_radius_top_left" format="dimension" /> <attr name="riv_corner_radius_top_right" format="dimension" /> <attr name="riv_corner_radius_bottom_left" format="dimension" /> <attr name="riv_corner_radius_bottom_right" format="dimension" /> <attr name="riv_border_width" format="dimension" /> <attr name="riv_border_color" format="color" /> <attr name="riv_mutate_background" format="boolean" /> <attr name="riv_oval" format="boolean" /> <attr name="android:scaleType" /> <attr name="riv_tile_mode"> <enum name="clamp" value="0" /> <enum name="repeat" value="1" /> <enum name="mirror" value="2" /> </attr> <attr name="riv_tile_mode_x"> <enum name="clamp" value="0" /> <enum name="repeat" value="1" /> <enum name="mirror" value="2" /> </attr> <attr name="riv_tile_mode_y"> <enum name="clamp" value="0" /> <enum name="repeat" value="1" /> <enum name="mirror" value="2" /> </attr> </declare-styleable></resources>
然后是3个相关类
package com.mirrorflower.idolfans.view;import android.support.annotation.IntDef;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.SOURCE)@IntDef({ Corner.TOP_LEFT, Corner.TOP_RIGHT, Corner.BOTTOM_LEFT, Corner.BOTTOM_RIGHT})public @interface Corner { int TOP_LEFT = 0; int TOP_RIGHT = 1; int BOTTOM_RIGHT = 2; int BOTTOM_LEFT = 3;}
package com.mirrorflower.idolfans.view;import android.content.res.ColorStateList;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ColorFilter;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PixelFormat;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.graphics.drawable.LayerDrawable;import android.support.annotation.ColorInt;import android.support.annotation.NonNull;import android.util.Log;import android.widget.ImageView.ScaleType;import java.util.HashSet;import java.util.Set;@SuppressWarnings("UnusedDeclaration")public class RoundedDrawable extends Drawable { public static final String TAG = "RoundedDrawable"; public static final int DEFAULT_BORDER_COLOR = Color.BLACK; private final RectF mBounds = new RectF(); private final RectF mDrawableRect = new RectF(); private final RectF mBitmapRect = new RectF(); private final Bitmap mBitmap; private final Paint mBitmapPaint; private final int mBitmapWidth; private final int mBitmapHeight; private final RectF mBorderRect = new RectF(); private final Paint mBorderPaint; private final Matrix mShaderMatrix = new Matrix(); private final RectF mSquareCornersRect = new RectF(); private Shader.TileMode mTileModeX = Shader.TileMode.CLAMP; private Shader.TileMode mTileModeY = Shader.TileMode.CLAMP; private boolean mRebuildShader = true; // [ topLeft, topRight, bottomLeft, bottomRight ] private float mCornerRadius = 0f; private final boolean[] mCornersRounded = new boolean[] { true, true, true, true }; private boolean mOval = false; private float mBorderWidth = 0; private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR); private ScaleType mScaleType = ScaleType.FIT_CENTER; public RoundedDrawable(Bitmap bitmap) { mBitmap = bitmap; mBitmapWidth = bitmap.getWidth(); mBitmapHeight = bitmap.getHeight(); mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight); mBitmapPaint = new Paint(); mBitmapPaint.setStyle(Paint.Style.FILL); mBitmapPaint.setAntiAlias(true); mBorderPaint = new Paint(); mBorderPaint.setStyle(Paint.Style.STROKE); mBorderPaint.setAntiAlias(true); mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR)); mBorderPaint.setStrokeWidth(mBorderWidth); } public static RoundedDrawable fromBitmap(Bitmap bitmap) { if (bitmap != null) { return new RoundedDrawable(bitmap); } else { return null; } } public static Drawable fromDrawable(Drawable drawable) { if (drawable != null) { if (drawable instanceof RoundedDrawable) { // just return if it's already a RoundedDrawable return drawable; } else if (drawable instanceof LayerDrawable) { LayerDrawable ld = (LayerDrawable) drawable; int num = ld.getNumberOfLayers(); // loop through layers to and change to RoundedDrawables if possible for (int i = 0; i < num; i++) { Drawable d = ld.getDrawable(i); ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d)); } return ld; } // try to get a bitmap from the drawable and Bitmap bm = drawableToBitmap(drawable); if (bm != null) { return new RoundedDrawable(bm); } } return drawable; } public static Bitmap drawableToBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } Bitmap bitmap; int width = Math.max(drawable.getIntrinsicWidth(), 2); int height = Math.max(drawable.getIntrinsicHeight(), 2); try { bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); } catch (Exception e) { e.printStackTrace(); Log.w(TAG, "Failed to create bitmap from drawable!"); bitmap = null; } return bitmap; } public Bitmap getSourceBitmap() { return mBitmap; } @Override public boolean isStateful() { return mBorderColor.isStateful(); } @Override protected boolean onStateChange(int[] state) { int newColor = mBorderColor.getColorForState(state, 0); if (mBorderPaint.getColor() != newColor) { mBorderPaint.setColor(newColor); return true; } else { return super.onStateChange(state); } } private void updateShaderMatrix() { float scale; float dx; float dy; switch (mScaleType) { case CENTER: mBorderRect.set(mBounds); mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2); mShaderMatrix.reset(); mShaderMatrix.setTranslate((int) ((mBorderRect.width() - mBitmapWidth) * 0.5f + 0.5f), (int) ((mBorderRect.height() - mBitmapHeight) * 0.5f + 0.5f)); break; case CENTER_CROP: mBorderRect.set(mBounds); mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2); mShaderMatrix.reset(); dx = 0; dy = 0; if (mBitmapWidth * mBorderRect.height() > mBorderRect.width() * mBitmapHeight) { scale = mBorderRect.height() / (float) mBitmapHeight; dx = (mBorderRect.width() - mBitmapWidth * scale) * 0.5f; } else { scale = mBorderRect.width() / (float) mBitmapWidth; dy = (mBorderRect.height() - mBitmapHeight * scale) * 0.5f; } mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth / 2, (int) (dy + 0.5f) + mBorderWidth / 2); break; case CENTER_INSIDE: mShaderMatrix.reset(); if (mBitmapWidth <= mBounds.width() && mBitmapHeight <= mBounds.height()) { scale = 1.0f; } else { scale = Math.min(mBounds.width() / (float) mBitmapWidth, mBounds.height() / (float) mBitmapHeight); } dx = (int) ((mBounds.width() - mBitmapWidth * scale) * 0.5f + 0.5f); dy = (int) ((mBounds.height() - mBitmapHeight * scale) * 0.5f + 0.5f); mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate(dx, dy); mBorderRect.set(mBitmapRect); mShaderMatrix.mapRect(mBorderRect); mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2); mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL); break; default: case FIT_CENTER: mBorderRect.set(mBitmapRect); mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.CENTER); mShaderMatrix.mapRect(mBorderRect); mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2); mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL); break; case FIT_END: mBorderRect.set(mBitmapRect); mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.END); mShaderMatrix.mapRect(mBorderRect); mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2); mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL); break; case FIT_START: mBorderRect.set(mBitmapRect); mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.START); mShaderMatrix.mapRect(mBorderRect); mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2); mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL); break; case FIT_XY: mBorderRect.set(mBounds); mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2); mShaderMatrix.reset(); mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL); break; } mDrawableRect.set(mBorderRect); } @Override protected void onBoundsChange(@NonNull Rect bounds) { super.onBoundsChange(bounds); mBounds.set(bounds); updateShaderMatrix(); } @Override public void draw(@NonNull Canvas canvas) { if (mRebuildShader) { BitmapShader bitmapShader = new BitmapShader(mBitmap, mTileModeX, mTileModeY); if (mTileModeX == Shader.TileMode.CLAMP && mTileModeY == Shader.TileMode.CLAMP) { bitmapShader.setLocalMatrix(mShaderMatrix); } mBitmapPaint.setShader(bitmapShader); mRebuildShader = false; } if (mOval) { if (mBorderWidth > 0) { canvas.drawOval(mDrawableRect, mBitmapPaint); canvas.drawOval(mBorderRect, mBorderPaint); } else { canvas.drawOval(mDrawableRect, mBitmapPaint); } } else { if (any(mCornersRounded)) { float radius = mCornerRadius; if (mBorderWidth > 0) { canvas.drawRoundRect(mDrawableRect, radius, radius, mBitmapPaint); canvas.drawRoundRect(mBorderRect, radius, radius, mBorderPaint); redrawBitmapForSquareCorners(canvas); redrawBorderForSquareCorners(canvas); } else { canvas.drawRoundRect(mDrawableRect, radius, radius, mBitmapPaint); redrawBitmapForSquareCorners(canvas); } } else { canvas.drawRect(mDrawableRect, mBitmapPaint); if (mBorderWidth > 0) { canvas.drawRect(mBorderRect, mBorderPaint); } } } } private void redrawBitmapForSquareCorners(Canvas canvas) { if (all(mCornersRounded)) { // no square corners return; } if (mCornerRadius == 0) { return; // no round corners } float left = mDrawableRect.left; float top = mDrawableRect.top; float right = left + mDrawableRect.width(); float bottom = top + mDrawableRect.height(); float radius = mCornerRadius; if (!mCornersRounded[Corner.TOP_LEFT]) { mSquareCornersRect.set(left, top, left + radius, top + radius); canvas.drawRect(mSquareCornersRect, mBitmapPaint); } if (!mCornersRounded[Corner.TOP_RIGHT]) { mSquareCornersRect.set(right - radius, top, right, radius); canvas.drawRect(mSquareCornersRect, mBitmapPaint); } if (!mCornersRounded[Corner.BOTTOM_RIGHT]) { mSquareCornersRect.set(right - radius, bottom - radius, right, bottom); canvas.drawRect(mSquareCornersRect, mBitmapPaint); } if (!mCornersRounded[Corner.BOTTOM_LEFT]) { mSquareCornersRect.set(left, bottom - radius, left + radius, bottom); canvas.drawRect(mSquareCornersRect, mBitmapPaint); } } private void redrawBorderForSquareCorners(Canvas canvas) { if (all(mCornersRounded)) { // no square corners return; } if (mCornerRadius == 0) { return; // no round corners } float left = mDrawableRect.left; float top = mDrawableRect.top; float right = left + mDrawableRect.width(); float bottom = top + mDrawableRect.height(); float radius = mCornerRadius; float offset = mBorderWidth / 2; if (!mCornersRounded[Corner.TOP_LEFT]) { canvas.drawLine(left - offset, top, left + radius, top, mBorderPaint); canvas.drawLine(left, top - offset, left, top + radius, mBorderPaint); } if (!mCornersRounded[Corner.TOP_RIGHT]) { canvas.drawLine(right - radius - offset, top, right, top, mBorderPaint); canvas.drawLine(right, top - offset, right, top + radius, mBorderPaint); } if (!mCornersRounded[Corner.BOTTOM_RIGHT]) { canvas.drawLine(right - radius - offset, bottom, right + offset, bottom, mBorderPaint); canvas.drawLine(right, bottom - radius, right, bottom, mBorderPaint); } if (!mCornersRounded[Corner.BOTTOM_LEFT]) { canvas.drawLine(left - offset, bottom, left + radius, bottom, mBorderPaint); canvas.drawLine(left, bottom - radius, left, bottom, mBorderPaint); } } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } @Override public int getAlpha() { return mBitmapPaint.getAlpha(); } @Override public void setAlpha(int alpha) { mBitmapPaint.setAlpha(alpha); invalidateSelf(); } @Override public ColorFilter getColorFilter() { return mBitmapPaint.getColorFilter(); } @Override public void setColorFilter(ColorFilter cf) { mBitmapPaint.setColorFilter(cf); invalidateSelf(); } @Override public void setDither(boolean dither) { mBitmapPaint.setDither(dither); invalidateSelf(); } @Override public void setFilterBitmap(boolean filter) { mBitmapPaint.setFilterBitmap(filter); invalidateSelf(); } @Override public int getIntrinsicWidth() { return mBitmapWidth; } @Override public int getIntrinsicHeight() { return mBitmapHeight; } /** * @return the corner radius. */ public float getCornerRadius() { return mCornerRadius; } /** * @param corner the specific corner to get radius of. * @return the corner radius of the specified corner. */ public float getCornerRadius(@Corner int corner) { return mCornersRounded[corner] ? mCornerRadius : 0f; } /** * Sets all corners to the specified radius. * * @param radius the radius. * @return the {@link RoundedDrawable} for chaining. */ public RoundedDrawable setCornerRadius(float radius) { setCornerRadius(radius, radius, radius, radius); return this; } /** * Sets the corner radius of one specific corner. * * @param corner the corner. * @param radius the radius. * @return the {@link RoundedDrawable} for chaining. */ public RoundedDrawable setCornerRadius(@Corner int corner, float radius) { if (radius != 0 && mCornerRadius != 0 && mCornerRadius != radius) { throw new IllegalArgumentException("Multiple nonzero corner radii not yet supported."); } if (radius == 0) { if (only(corner, mCornersRounded)) { mCornerRadius = 0; } mCornersRounded[corner] = false; } else { if (mCornerRadius == 0) { mCornerRadius = radius; } mCornersRounded[corner] = true; } return this; } /** * Sets the corner radii of all the corners. * * @param topLeft top left corner radius. * @param topRight top right corner radius * @param bottomRight bototm right corner radius. * @param bottomLeft bottom left corner radius. * @return the {@link RoundedDrawable} for chaining. */ public RoundedDrawable setCornerRadius(float topLeft, float topRight, float bottomRight, float bottomLeft) { Set<Float> radiusSet = new HashSet<>(4); radiusSet.add(topLeft); radiusSet.add(topRight); radiusSet.add(bottomRight); radiusSet.add(bottomLeft); radiusSet.remove(0f); if (radiusSet.size() > 1) { throw new IllegalArgumentException("Multiple nonzero corner radii not yet supported."); } if (!radiusSet.isEmpty()) { float radius = radiusSet.iterator().next(); if (Float.isInfinite(radius) || Float.isNaN(radius) || radius < 0) { throw new IllegalArgumentException("Invalid radius value: " + radius); } mCornerRadius = radius; } else { mCornerRadius = 0f; } mCornersRounded[Corner.TOP_LEFT] = topLeft > 0; mCornersRounded[Corner.TOP_RIGHT] = topRight > 0; mCornersRounded[Corner.BOTTOM_RIGHT] = bottomRight > 0; mCornersRounded[Corner.BOTTOM_LEFT] = bottomLeft > 0; return this; } public float getBorderWidth() { return mBorderWidth; } public RoundedDrawable setBorderWidth(float width) { mBorderWidth = width; mBorderPaint.setStrokeWidth(mBorderWidth); return this; } public int getBorderColor() { return mBorderColor.getDefaultColor(); } public RoundedDrawable setBorderColor(@ColorInt int color) { return setBorderColor(ColorStateList.valueOf(color)); } public ColorStateList getBorderColors() { return mBorderColor; } public RoundedDrawable setBorderColor(ColorStateList colors) { mBorderColor = colors != null ? colors : ColorStateList.valueOf(0); mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR)); return this; } public boolean isOval() { return mOval; } public RoundedDrawable setOval(boolean oval) { mOval = oval; return this; } public ScaleType getScaleType() { return mScaleType; } public RoundedDrawable setScaleType(ScaleType scaleType) { if (scaleType == null) { scaleType = ScaleType.FIT_CENTER; } if (mScaleType != scaleType) { mScaleType = scaleType; updateShaderMatrix(); } return this; } public Shader.TileMode getTileModeX() { return mTileModeX; } public RoundedDrawable setTileModeX(Shader.TileMode tileModeX) { if (mTileModeX != tileModeX) { mTileModeX = tileModeX; mRebuildShader = true; invalidateSelf(); } return this; } public Shader.TileMode getTileModeY() { return mTileModeY; } public RoundedDrawable setTileModeY(Shader.TileMode tileModeY) { if (mTileModeY != tileModeY) { mTileModeY = tileModeY; mRebuildShader = true; invalidateSelf(); } return this; } private static boolean only(int index, boolean[] booleans) { for (int i = 0, len = booleans.length; i < len; i++) { if (booleans[i] != (i == index)) { return false; } } return true; } private static boolean any(boolean[] booleans) { for (boolean b : booleans) { if (b) { return true; } } return false; } private static boolean all(boolean[] booleans) { for (boolean b : booleans) { if (b) { return false; } } return true; } public Bitmap toBitmap() { return drawableToBitmap(this); }}
package com.mirrorflower.idolfans.view;import android.content.Context;import android.content.res.ColorStateList;import android.content.res.Resources;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.ColorFilter;import android.graphics.Shader;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.graphics.drawable.LayerDrawable;import android.net.Uri;import android.support.annotation.ColorInt;import android.support.annotation.DimenRes;import android.support.annotation.DrawableRes;import android.util.AttributeSet;import android.util.Log;import android.widget.ImageView;import com.mirrorflower.meituan.R;@SuppressWarnings("UnusedDeclaration")public class CircleImageView extends ImageView { // Constants for tile mode attributes private static final int TILE_MODE_UNDEFINED = -2; private static final int TILE_MODE_CLAMP = 0; private static final int TILE_MODE_REPEAT = 1; private static final int TILE_MODE_MIRROR = 2; public static final String TAG = "RoundedImageView"; public static final float DEFAULT_RADIUS = 0f; public static final float DEFAULT_BORDER_WIDTH = 0f; public static final Shader.TileMode DEFAULT_TILE_MODE = Shader.TileMode.CLAMP; private static final ScaleType[] SCALE_TYPES = { ScaleType.MATRIX, ScaleType.FIT_XY, ScaleType.FIT_START, ScaleType.FIT_CENTER, ScaleType.FIT_END, ScaleType.CENTER, ScaleType.CENTER_CROP, ScaleType.CENTER_INSIDE }; private final float[] mCornerRadii = new float[] { DEFAULT_RADIUS, DEFAULT_RADIUS, DEFAULT_RADIUS, DEFAULT_RADIUS }; private Drawable mBackgroundDrawable; private ColorStateList mBorderColor = ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR); private float mBorderWidth = DEFAULT_BORDER_WIDTH; private ColorFilter mColorFilter = null; private boolean mColorMod = false; private Drawable mDrawable; private boolean mHasColorFilter = false; private boolean mIsOval = false; private boolean mMutateBackground = false; private int mResource; private int mBackgroundResource; private ScaleType mScaleType = ScaleType.FIT_CENTER; private Shader.TileMode mTileModeX = DEFAULT_TILE_MODE; private Shader.TileMode mTileModeY = DEFAULT_TILE_MODE; public CircleImageView(Context context) { super(context); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); int index = a.getInt(0, -1); if (index >= 0) { setScaleType(SCALE_TYPES[index]); } else { // default scaletype to FIT_CENTER setScaleType(ScaleType.FIT_CENTER); } float cornerRadiusOverride = a.getDimensionPixelSize(R.styleable.CircleImageView_riv_corner_radius, -1); mCornerRadii[Corner.TOP_LEFT] = a.getDimensionPixelSize(R.styleable.CircleImageView_riv_corner_radius_top_left, -1); mCornerRadii[Corner.TOP_RIGHT] = a.getDimensionPixelSize(R.styleable.CircleImageView_riv_corner_radius_top_right, -1); mCornerRadii[Corner.BOTTOM_RIGHT] = a.getDimensionPixelSize(R.styleable.CircleImageView_riv_corner_radius_bottom_right, -1); mCornerRadii[Corner.BOTTOM_LEFT] = a.getDimensionPixelSize(R.styleable.CircleImageView_riv_corner_radius_bottom_left, -1); boolean any = false; for (int i = 0, len = mCornerRadii.length; i < len; i++) { if (mCornerRadii[i] < 0) { mCornerRadii[i] = 0f; } else { any = true; } } if (!any) { if (cornerRadiusOverride < 0) { cornerRadiusOverride = DEFAULT_RADIUS; } for (int i = 0, len = mCornerRadii.length; i < len; i++) { mCornerRadii[i] = cornerRadiusOverride; } } mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_riv_border_width, -1); if (mBorderWidth < 0) { mBorderWidth = DEFAULT_BORDER_WIDTH; } mBorderColor = a.getColorStateList(R.styleable.CircleImageView_riv_border_color); if (mBorderColor == null) { mBorderColor = ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR); } mMutateBackground = a.getBoolean(R.styleable.CircleImageView_riv_mutate_background, false); mIsOval = a.getBoolean(R.styleable.CircleImageView_riv_oval, false); final int tileMode = a.getInt(R.styleable.CircleImageView_riv_tile_mode, TILE_MODE_UNDEFINED); if (tileMode != TILE_MODE_UNDEFINED) { setTileModeX(parseTileMode(tileMode)); setTileModeY(parseTileMode(tileMode)); } final int tileModeX = a.getInt(R.styleable.CircleImageView_riv_tile_mode_x, TILE_MODE_UNDEFINED); if (tileModeX != TILE_MODE_UNDEFINED) { setTileModeX(parseTileMode(tileModeX)); } final int tileModeY = a.getInt(R.styleable.CircleImageView_riv_tile_mode_y, TILE_MODE_UNDEFINED); if (tileModeY != TILE_MODE_UNDEFINED) { setTileModeY(parseTileMode(tileModeY)); } updateDrawableAttrs(); updateBackgroundDrawableAttrs(true); if (mMutateBackground) { // when setBackground() is called by View constructor, mMutateBackground is not loaded from the attribute, // so it's false by default, what doesn't allow to create the RoundedDrawable. At this point, after load // mMutateBackground and updated BackgroundDrawable to RoundedDrawable, the View's background drawable needs to // be changed to this new drawable. //noinspection deprecation super.setBackgroundDrawable(mBackgroundDrawable); } a.recycle(); } private static Shader.TileMode parseTileMode(int tileMode) { switch (tileMode) { case TILE_MODE_CLAMP: return Shader.TileMode.CLAMP; case TILE_MODE_REPEAT: return Shader.TileMode.REPEAT; case TILE_MODE_MIRROR: return Shader.TileMode.MIRROR; default: return null; } } @Override protected void drawableStateChanged() { super.drawableStateChanged(); invalidate(); } @Override public ScaleType getScaleType() { return mScaleType; } @Override public void setScaleType(ScaleType scaleType) { assert scaleType != null; if (mScaleType != scaleType) { mScaleType = scaleType; switch (scaleType) { case CENTER: case CENTER_CROP: case CENTER_INSIDE: case FIT_CENTER: case FIT_START: case FIT_END: case FIT_XY: super.setScaleType(ScaleType.FIT_XY); break; default: super.setScaleType(scaleType); break; } updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); invalidate(); } } @Override public void setImageDrawable(Drawable drawable) { mResource = 0; mDrawable = RoundedDrawable.fromDrawable(drawable); updateDrawableAttrs(); super.setImageDrawable(mDrawable); } @Override public void setImageBitmap(Bitmap bm) { mResource = 0; mDrawable = RoundedDrawable.fromBitmap(bm); updateDrawableAttrs(); super.setImageDrawable(mDrawable); } @Override public void setImageResource(@DrawableRes int resId) { if (mResource != resId) { mResource = resId; mDrawable = resolveResource(); updateDrawableAttrs(); super.setImageDrawable(mDrawable); } } @Override public void setImageURI(Uri uri) { super.setImageURI(uri); setImageDrawable(getDrawable()); } private Drawable resolveResource() { Resources rsrc = getResources(); if (rsrc == null) { return null; } Drawable d = null; if (mResource != 0) { try { d = rsrc.getDrawable(mResource); } catch (Exception e) { Log.w(TAG, "Unable to find resource: " + mResource, e); // Don't try again. mResource = 0; } } return RoundedDrawable.fromDrawable(d); } @Override public void setBackground(Drawable background) { setBackgroundDrawable(background); } @Override public void setBackgroundResource(@DrawableRes int resId) { if (mBackgroundResource != resId) { mBackgroundResource = resId; mBackgroundDrawable = resolveBackgroundResource(); setBackgroundDrawable(mBackgroundDrawable); } } @Override public void setBackgroundColor(int color) { mBackgroundDrawable = new ColorDrawable(color); setBackgroundDrawable(mBackgroundDrawable); } private Drawable resolveBackgroundResource() { Resources rsrc = getResources(); if (rsrc == null) { return null; } Drawable d = null; if (mBackgroundResource != 0) { try { d = rsrc.getDrawable(mBackgroundResource); } catch (Exception e) { Log.w(TAG, "Unable to find resource: " + mBackgroundResource, e); // Don't try again. mBackgroundResource = 0; } } return RoundedDrawable.fromDrawable(d); } private void updateDrawableAttrs() { updateAttrs(mDrawable, mScaleType); } private void updateBackgroundDrawableAttrs(boolean convert) { if (mMutateBackground) { if (convert) { mBackgroundDrawable = RoundedDrawable.fromDrawable(mBackgroundDrawable); } updateAttrs(mBackgroundDrawable, ScaleType.FIT_XY); } } @Override public void setColorFilter(ColorFilter cf) { if (mColorFilter != cf) { mColorFilter = cf; mHasColorFilter = true; mColorMod = true; applyColorMod(); invalidate(); } } private void applyColorMod() { // Only mutate and apply when modifications have occurred. This should // not reset the mColorMod flag, since these filters need to be // re-applied if the Drawable is changed. if (mDrawable != null && mColorMod) { mDrawable = mDrawable.mutate(); if (mHasColorFilter) { mDrawable.setColorFilter(mColorFilter); } // TODO: support, eventually... //mDrawable.setXfermode(mXfermode); //mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8); } } private void updateAttrs(Drawable drawable, ScaleType scaleType) { if (drawable == null) { return; } if (drawable instanceof RoundedDrawable) { ((RoundedDrawable) drawable) .setScaleType(scaleType) .setBorderWidth(mBorderWidth) .setBorderColor(mBorderColor) .setOval(mIsOval) .setTileModeX(mTileModeX) .setTileModeY(mTileModeY); if (mCornerRadii != null) { ((RoundedDrawable) drawable).setCornerRadius( mCornerRadii[Corner.TOP_LEFT], mCornerRadii[Corner.TOP_RIGHT], mCornerRadii[Corner.BOTTOM_RIGHT], mCornerRadii[Corner.BOTTOM_LEFT]); } applyColorMod(); } else if (drawable instanceof LayerDrawable) { // loop through layers to and set drawable attrs LayerDrawable ld = ((LayerDrawable) drawable); for (int i = 0, layers = ld.getNumberOfLayers(); i < layers; i++) { updateAttrs(ld.getDrawable(i), scaleType); } } } @Override @Deprecated public void setBackgroundDrawable(Drawable background) { mBackgroundDrawable = background; updateBackgroundDrawableAttrs(true); //noinspection deprecation super.setBackgroundDrawable(mBackgroundDrawable); } /** * @return the largest corner radius. */ public float getCornerRadius() { return getMaxCornerRadius(); } /** * @return the largest corner radius. */ public float getMaxCornerRadius() { float maxRadius = 0; for (float r : mCornerRadii) { maxRadius = Math.max(r, maxRadius); } return maxRadius; } /** * Get the corner radius of a specified corner. * * @param corner the corner. * @return the radius. */ public float getCornerRadius(@Corner int corner) { return mCornerRadii[corner]; } /** * Set all the corner radii from a dimension resource id. * * @param resId dimension resource id of radii. */ public void setCornerRadiusDimen(@DimenRes int resId) { float radius = getResources().getDimension(resId); setCornerRadius(radius, radius, radius, radius); } /** * Set the corner radius of a specific corner from a dimension resource id. * * @param corner the corner to set. * @param resId the dimension resource id of the corner radius. */ public void setCornerRadiusDimen(@Corner int corner, @DimenRes int resId) { setCornerRadius(corner, getResources().getDimensionPixelSize(resId)); } /** * Set the corner radii of all corners in px. * * @param radius the radius to set. */ public void setCornerRadius(float radius) { setCornerRadius(radius, radius, radius, radius); } /** * Set the corner radius of a specific corner in px. * * @param corner the corner to set. * @param radius the corner radius to set in px. */ public void setCornerRadius(@Corner int corner, float radius) { if (mCornerRadii[corner] == radius) { return; } mCornerRadii[corner] = radius; updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); invalidate(); } /** * Set the corner radii of each corner individually. Currently only one unique nonzero value is * supported. * * @param topLeft radius of the top left corner in px. * @param topRight radius of the top right corner in px. * @param bottomRight radius of the bottom right corner in px. * @param bottomLeft radius of the bottom left corner in px. */ public void setCornerRadius(float topLeft, float topRight, float bottomLeft, float bottomRight) { if (mCornerRadii[Corner.TOP_LEFT] == topLeft && mCornerRadii[Corner.TOP_RIGHT] == topRight && mCornerRadii[Corner.BOTTOM_RIGHT] == bottomRight && mCornerRadii[Corner.BOTTOM_LEFT] == bottomLeft) { return; } mCornerRadii[Corner.TOP_LEFT] = topLeft; mCornerRadii[Corner.TOP_RIGHT] = topRight; mCornerRadii[Corner.BOTTOM_LEFT] = bottomLeft; mCornerRadii[Corner.BOTTOM_RIGHT] = bottomRight; updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); invalidate(); } public float getBorderWidth() { return mBorderWidth; } public void setBorderWidth(@DimenRes int resId) { setBorderWidth(getResources().getDimension(resId)); } public void setBorderWidth(float width) { if (mBorderWidth == width) { return; } mBorderWidth = width; updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); invalidate(); } @ColorInt public int getBorderColor() { return mBorderColor.getDefaultColor(); } public void setBorderColor(@ColorInt int color) { setBorderColor(ColorStateList.valueOf(color)); } public ColorStateList getBorderColors() { return mBorderColor; } public void setBorderColor(ColorStateList colors) { if (mBorderColor.equals(colors)) { return; } mBorderColor = (colors != null) ? colors : ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR); updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); if (mBorderWidth > 0) { invalidate(); } } public boolean isOval() { return mIsOval; } public void setOval(boolean oval) { mIsOval = oval; updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); invalidate(); } public Shader.TileMode getTileModeX() { return mTileModeX; } public void setTileModeX(Shader.TileMode tileModeX) { if (this.mTileModeX == tileModeX) { return; } this.mTileModeX = tileModeX; updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); invalidate(); } public Shader.TileMode getTileModeY() { return mTileModeY; } public void setTileModeY(Shader.TileMode tileModeY) { if (this.mTileModeY == tileModeY) { return; } this.mTileModeY = tileModeY; updateDrawableAttrs(); updateBackgroundDrawableAttrs(false); invalidate(); } public boolean mutatesBackground() { return mMutateBackground; } public void mutateBackground(boolean mutate) { if (mMutateBackground == mutate) { return; } mMutateBackground = mutate; updateBackgroundDrawableAttrs(true); invalidate(); }}
xml中使用:
<com.mirrorflower.idolfans.view.CircleImageView android:id="@+id/head_portrait_icon" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_marginRight="14dp" app:riv_oval="true" android:src="@drawable/food" />
OK了!自定义属性还是蛮多的!不过功能很齐全有木有,可以设置圆形,可以单独设置某个角的弧度大小,还可以设置border边界线。
0 0
- 上传头像设置sessionid
- 上传设置头像
- Android设置头像上传功能实现
- 上传头像
- 上传头像
- 上传头像
- 上传头像
- 头像上传
- 上传头像
- 头像上传
- 头像上传
- 头像上传
- 上传头像
- 上传头像
- 头像上传
- 头像上传
- 上传头像
- 头像上传
- 不想丑陋之动态加载模块初级篇
- 用OpenCV实现Photoshop算法(九): 高反差保留
- NIO学习笔记
- MyEclipse的注册码计算
- 【Leetcode】399. Evaluate Division
- 上传设置头像
- Linux运维笔记----Bash Scripts基础II
- 二叉树中和为某一值的路径
- IDEA / WebStorm / PhpStorm 添加jQuery自动提示,自动补全,提示文档
- 51单片机最小系统的绘制
- HDU1231-最大连续子序列(线性dp)
- dex分包变形记
- HDU1059&&POJ1014-Dividing
- Java 引用传递