Android 心形图片心形ImageView、带边框的的心形图片和圆形图片

2024-08-21 02:32

本文主要是介绍Android 心形图片心形ImageView、带边框的的心形图片和圆形图片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

源码地址:心形图片、心形ImageView、圆形图片、圆形ImageView

实际效果如下:

示例图

一、思路

1、图片尺寸:加载的图片尺寸不会完全统一,可以是正方形,长方形等,这里不需要考虑正方形,因为一般的头像是正方形,需要考虑的是长方形,需要取长方形中边长的最大的居中的正方形,否则会拉伸,不好看。

2、心形边框:可以通过画笔或者一个心形的图片

3、细节:心形边框覆盖在图片上,并且只显示心形里面的部分图片,心形以外的图片不显示

二、实现

        结合思路中第二点和第三点,心形边框部分不可以使用心形边框图片遮盖图片。因为这样限制性太大,不同背景颜色的页面需要做对应颜色的心形边框图片。这样太费劲了,不能这么做。我们很懒!!!

        那么,我们需要自定义view用画笔 paint 来绘制一个心形边框,并且需要满足“心形边框覆盖在图片上,并且只显示心形里面的部分图片,心形以外的图片不显示”这样的需求。

 

涉及技术关键词:

贝赛尔曲线 : 参考 安卓自定义View进阶-Path之贝塞尔曲线  学习贝塞尔曲线的基础用法和适用场景

Paint Xfermode :参考 Android Paint Xfermode 学习paint.setXfermode的用途

 

三、代码

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="heartimageview"><attr name="border_size" format="dimension" /><attr name="in_border_color" format="color" /><attr name="out_border_color" format="color"/><attr name="shape_type" format="string"/></declare-styleable><declare-styleable name="CircleImageView"><attr name="civ_border_width" format="dimension" /><attr name="civ_border_color" format="color" /><attr name="civ_border_overlay" format="boolean" /><attr name="civ_circle_background_color" format="color" /></declare-styleable>
</resources>

HeartImageView.java

/*** 心形ImageView 可以设置边框* @author DerekYan*/
public class HeartImageView extends ImageView {private Context mContext;private int border_size = 0;// 边框厚度private int in_border_color = 0;// 内圆边框颜色private int out_border_color = 0;// 外圆边框颜色private int defColor = 0xFFFFFFFF;// 默认颜色private int width = 0;// 控件的宽度private int height = 0;// 控件的高度private String shape_type;// 形状的类型public HeartImageView(Context context) {super(context);// TODO Auto-generated constructor stubthis.mContext = context;}public HeartImageView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubthis.mContext = context;setAttributes(attrs);}public HeartImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stubthis.mContext = context;setAttributes(attrs);}/*** 获得自定义属性** @param attrs*/private void setAttributes(AttributeSet attrs) {// TODO Auto-generated method stubTypedArray mArray = mContext.obtainStyledAttributes(attrs,R.styleable.heartimageview);// 得到边框厚度,否则返回0border_size = mArray.getDimensionPixelSize(R.styleable.heartimageview_border_size, 0);// 得到内边框颜色,否则返回默认颜色in_border_color = mArray.getColor(R.styleable.heartimageview_in_border_color, defColor);// 得到外边框颜色,否则返回默认颜色out_border_color = mArray.getColor(R.styleable.heartimageview_out_border_color, defColor);// 得到形状的类型shape_type = mArray.getString(R.styleable.heartimageview_shape_type);mArray.recycle();// 回收mArray}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stub// super.onDraw(canvas); 必须去掉该行或注释掉,否则会出现两张图片// 得到传入的图片Drawable drawable = getDrawable();if (drawable == null) {return;}if (getWidth() == 0 || getHeight() == 0) {return;}this.measure(0, 0);if (drawable.getClass() == NinePatchDrawable.class) {// 如果该传入图片是.9格式的图片return;}// 将图片转为位图Bitmap mBitmap = ((BitmapDrawable) drawable).getBitmap();Bitmap cpBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true);// 得到画布宽高width = getWidth();height = getHeight();
//int radius = 0;//radius = (width < height ? width : height) / 2;
//Bitmap shapeBitmap = drawShapeBitmap(cpBitmap, radius);canvas.drawBitmap(shapeBitmap, width / 2 - radius, height / 2 - radius,null);}/*** 画出指定形状的图片** @param radius* @return*/private Bitmap drawShapeBitmap(Bitmap bmp, int radius) {// TODO Auto-generated method stubBitmap squareBitmap;// 根据传入的位图截取合适的正方形位图Bitmap scaledBitmap;// 根据diameter对截取的正方形位图进行缩放Log.i("HeartImageView", "radius:" + radius);int diameter = radius * 2;// 位图的宽高int w = bmp.getWidth();int h = bmp.getHeight();// 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图片squareBitmap = bmp;// 对squareBitmap进行缩放为diameter边长的正方形位图if (w != diameter|| h != diameter) {if (w < diameter || h < diameter) {//位图宽高没有ImageView的宽高大 需要放大float scale; //缩放倍数scale = 1f * diameter / (Math.min(w, h));Matrix matrix = new Matrix();matrix.postScale(scale,scale);squareBitmap =  Bitmap.createBitmap(squareBitmap,0,0,w,h,matrix,false);if (w != h) {//从矩形图中截取正中间的正方形部分。scaledBitmap = centerSquareScaleBitmap(squareBitmap, diameter);} else {scaledBitmap = squareBitmap;}} else {//从矩形图中截取正中间的正方形部分。scaledBitmap = centerSquareScaleBitmap(squareBitmap, diameter);}} else {scaledBitmap = squareBitmap;}Bitmap outputbmp = Bitmap.createBitmap(scaledBitmap.getWidth(),scaledBitmap.getHeight(), Config.ARGB_8888);Canvas canvas = new Canvas(outputbmp);// 创建一个相同大小的画布Paint paint = new Paint();// 定义画笔paint.setAntiAlias(true);// 设置抗锯齿paint.setFilterBitmap(true);paint.setDither(true);canvas.drawARGB(0, 0, 0, 0);//设置边框Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);borderPaint.setColor(out_border_color);borderPaint.setStyle(Paint.Style.STROKE);borderPaint.setStrokeWidth(border_size);Path path = new Path();//右心形path.moveTo(diameter / 2f, diameter / 7f);path.cubicTo((diameter /6f) * 5  , 0 - ( diameter / 5f), (diameter / 5f) * 7  , (diameter / 5f) * 2  , diameter / 2f, diameter- border_size );//左心形path.moveTo(diameter / 2f, diameter / 7f);path.cubicTo(diameter / 6f , 0 - ( diameter / 5f), 0 - (diameter / 5f) * 2, (diameter / 5f) * 2, diameter / 2f, diameter - border_size );canvas.drawPath(path, paint);// 设置Xfermode的Modepaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));canvas.drawBitmap(scaledBitmap, 0, 0, paint);canvas.drawPath(path, borderPaint);bmp = null;squareBitmap = null;scaledBitmap = null;return outputbmp;}/*** @param bitmap      原图* @param edgeLength  希望得到的正方形部分的边长* @return  缩放截取正中部分后的位图。*/public static Bitmap centerSquareScaleBitmap(Bitmap bitmap, int edgeLength){if(null == bitmap || edgeLength <= 0){return  null;}Bitmap result = bitmap;int widthOrg = bitmap.getWidth();int heightOrg = bitmap.getHeight();if(widthOrg > edgeLength && heightOrg > edgeLength){//压缩到一个最小长度是edgeLength的bitmapint longerEdge = (int)(edgeLength * Math.max(widthOrg, heightOrg) / Math.min(widthOrg, heightOrg));int scaledWidth = widthOrg > heightOrg ? longerEdge : edgeLength;int scaledHeight = widthOrg > heightOrg ? edgeLength : longerEdge;Bitmap scaledBitmap;try{scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);}catch(Exception e){return null;}//从图中截取正中间的正方形部分。int xTopLeft = (scaledWidth - edgeLength) / 2;int yTopLeft = (scaledHeight - edgeLength) / 2;try{result = Bitmap.createBitmap(scaledBitmap, xTopLeft, yTopLeft, edgeLength, edgeLength);scaledBitmap.recycle();}catch(Exception e){return null;}}return result;}}

CircleImageView.java

public class CircleImageView extends ImageView {private static final ImageView.ScaleType SCALE_TYPE = ImageView.ScaleType.CENTER_CROP;private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;private static final int COLORDRAWABLE_DIMENSION = 2;private static final int DEFAULT_BORDER_WIDTH = 0;private static final int DEFAULT_BORDER_COLOR = Color.BLACK;private static final int DEFAULT_CIRCLE_BACKGROUND_COLOR = Color.TRANSPARENT;private static final int DEFAULT_IMAGE_ALPHA = 255;private static final boolean DEFAULT_BORDER_OVERLAY = false;private final RectF mDrawableRect = new RectF();private final RectF mBorderRect = new RectF();private final Matrix mShaderMatrix = new Matrix();private final Paint mBitmapPaint = new Paint();private final Paint mBorderPaint = new Paint();private final Paint mCircleBackgroundPaint = new Paint();private int mBorderColor = DEFAULT_BORDER_COLOR;private int mBorderWidth = DEFAULT_BORDER_WIDTH;private int mCircleBackgroundColor = DEFAULT_CIRCLE_BACKGROUND_COLOR;private int mImageAlpha = DEFAULT_IMAGE_ALPHA;private Bitmap mBitmap;private Canvas mBitmapCanvas;private float mDrawableRadius;private float mBorderRadius;private ColorFilter mColorFilter;private boolean mInitialized;private boolean mRebuildShader;private boolean mDrawableDirty;private boolean mBorderOverlay;private boolean mDisableCircularTransformation;public CircleImageView(Context context) {super(context);init();}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);mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);mCircleBackgroundColor = a.getColor(R.styleable.CircleImageView_civ_circle_background_color, DEFAULT_CIRCLE_BACKGROUND_COLOR);a.recycle();init();}private void init() {mInitialized = true;super.setScaleType(SCALE_TYPE);mBitmapPaint.setAntiAlias(true);mBitmapPaint.setDither(true);mBitmapPaint.setFilterBitmap(true);mBitmapPaint.setAlpha(mImageAlpha);mBitmapPaint.setColorFilter(mColorFilter);mBorderPaint.setStyle(Paint.Style.STROKE);mBorderPaint.setAntiAlias(true);mBorderPaint.setColor(mBorderColor);mBorderPaint.setStrokeWidth(mBorderWidth);mCircleBackgroundPaint.setStyle(Paint.Style.FILL);mCircleBackgroundPaint.setAntiAlias(true);mCircleBackgroundPaint.setColor(mCircleBackgroundColor);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {setOutlineProvider(new OutlineProvider());}}@Overridepublic void setScaleType(ImageView.ScaleType scaleType) {if (scaleType != SCALE_TYPE) {throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));}}@Overridepublic void setAdjustViewBounds(boolean adjustViewBounds) {if (adjustViewBounds) {throw new IllegalArgumentException("adjustViewBounds not supported.");}}@SuppressLint("CanvasSize")@Overrideprotected void onDraw(Canvas canvas) {if (mDisableCircularTransformation) {super.onDraw(canvas);return;}if (mCircleBackgroundColor != Color.TRANSPARENT) {canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mCircleBackgroundPaint);}if (mBitmap != null) {if (mDrawableDirty && mBitmapCanvas != null) {mDrawableDirty = false;Drawable drawable = getDrawable();drawable.setBounds(0, 0, mBitmapCanvas.getWidth(), mBitmapCanvas.getHeight());drawable.draw(mBitmapCanvas);}if (mRebuildShader) {mRebuildShader = false;BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);bitmapShader.setLocalMatrix(mShaderMatrix);mBitmapPaint.setShader(bitmapShader);}canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);}if (mBorderWidth > 0) {canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);}}@Overridepublic void invalidateDrawable(@NonNull Drawable dr) {mDrawableDirty = true;invalidate();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);updateDimensions();invalidate();}@Overridepublic void setPadding(int left, int top, int right, int bottom) {super.setPadding(left, top, right, bottom);updateDimensions();invalidate();}@Overridepublic void setPaddingRelative(int start, int top, int end, int bottom) {super.setPaddingRelative(start, top, end, bottom);updateDimensions();invalidate();}public int getBorderColor() {return mBorderColor;}public void setBorderColor(@ColorInt int borderColor) {if (borderColor == mBorderColor) {return;}mBorderColor = borderColor;mBorderPaint.setColor(borderColor);invalidate();}public int getCircleBackgroundColor() {return mCircleBackgroundColor;}public void setCircleBackgroundColor(@ColorInt int circleBackgroundColor) {if (circleBackgroundColor == mCircleBackgroundColor) {return;}mCircleBackgroundColor = circleBackgroundColor;mCircleBackgroundPaint.setColor(circleBackgroundColor);invalidate();}/*** @deprecated Use {@link #setCircleBackgroundColor(int)} instead*/@Deprecatedpublic void setCircleBackgroundColorResource(@ColorRes int circleBackgroundRes) {setCircleBackgroundColor(getContext().getResources().getColor(circleBackgroundRes));}public int getBorderWidth() {return mBorderWidth;}public void setBorderWidth(int borderWidth) {if (borderWidth == mBorderWidth) {return;}mBorderWidth = borderWidth;mBorderPaint.setStrokeWidth(borderWidth);updateDimensions();invalidate();}public boolean isBorderOverlay() {return mBorderOverlay;}public void setBorderOverlay(boolean borderOverlay) {if (borderOverlay == mBorderOverlay) {return;}mBorderOverlay = borderOverlay;updateDimensions();invalidate();}public boolean isDisableCircularTransformation() {return mDisableCircularTransformation;}public void setDisableCircularTransformation(boolean disableCircularTransformation) {if (disableCircularTransformation == mDisableCircularTransformation) {return;}mDisableCircularTransformation = disableCircularTransformation;if (disableCircularTransformation) {mBitmap = null;mBitmapCanvas = null;mBitmapPaint.setShader(null);} else {initializeBitmap();}invalidate();}@Overridepublic void setImageBitmap(Bitmap bm) {super.setImageBitmap(bm);initializeBitmap();invalidate();}@Overridepublic void setImageDrawable(Drawable drawable) {super.setImageDrawable(drawable);initializeBitmap();invalidate();}@Overridepublic void setImageResource(@DrawableRes int resId) {super.setImageResource(resId);initializeBitmap();invalidate();}@Overridepublic void setImageURI(Uri uri) {super.setImageURI(uri);initializeBitmap();invalidate();}@Overridepublic void setImageAlpha(int alpha) {alpha &= 0xFF;if (alpha == mImageAlpha) {return;}mImageAlpha = alpha;// This might be called during ImageView construction before// member initialization has finished on API level >= 16.if (mInitialized) {mBitmapPaint.setAlpha(alpha);invalidate();}}@Overridepublic int getImageAlpha() {return mImageAlpha;}@Overridepublic void setColorFilter(ColorFilter cf) {if (cf == mColorFilter) {return;}mColorFilter = cf;// This might be called during ImageView construction before// member initialization has finished on API level <= 19.if (mInitialized) {mBitmapPaint.setColorFilter(cf);invalidate();}}@Overridepublic ColorFilter getColorFilter() {return mColorFilter;}private Bitmap getBitmapFromDrawable(Drawable drawable) {if (drawable == null) {return null;}if (drawable instanceof BitmapDrawable) {return ((BitmapDrawable) drawable).getBitmap();}try {Bitmap bitmap;if (drawable instanceof ColorDrawable) {bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);} else {bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);}Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());drawable.draw(canvas);return bitmap;} catch (Exception e) {e.printStackTrace();return null;}}private void initializeBitmap() {mBitmap = getBitmapFromDrawable(getDrawable());if (mBitmap != null && mBitmap.isMutable()) {mBitmapCanvas = new Canvas(mBitmap);} else {mBitmapCanvas = null;}if (!mInitialized) {return;}if (mBitmap != null) {updateShaderMatrix();} else {mBitmapPaint.setShader(null);}}private void updateDimensions() {mBorderRect.set(calculateBounds());mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);mDrawableRect.set(mBorderRect);if (!mBorderOverlay && mBorderWidth > 0) {mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);}mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);updateShaderMatrix();}private RectF calculateBounds() {int availableWidth  = getWidth() - getPaddingLeft() - getPaddingRight();int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();int sideLength = Math.min(availableWidth, availableHeight);float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;float top = getPaddingTop() + (availableHeight - sideLength) / 2f;return new RectF(left, top, left + sideLength, top + sideLength);}private void updateShaderMatrix() {if (mBitmap == null) {return;}float scale;float dx = 0;float dy = 0;mShaderMatrix.set(null);int bitmapHeight = mBitmap.getHeight();int bitmapWidth = mBitmap.getWidth();if (bitmapWidth * mDrawableRect.height() > mDrawableRect.width() * bitmapHeight) {scale = mDrawableRect.height() / (float) bitmapHeight;dx = (mDrawableRect.width() - bitmapWidth * scale) * 0.5f;} else {scale = mDrawableRect.width() / (float) bitmapWidth;dy = (mDrawableRect.height() - bitmapHeight * scale) * 0.5f;}mShaderMatrix.setScale(scale, scale);mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);mRebuildShader = true;}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {if (mDisableCircularTransformation) {return super.onTouchEvent(event);}return inTouchableArea(event.getX(), event.getY()) && super.onTouchEvent(event);}private boolean inTouchableArea(float x, float y) {if (mBorderRect.isEmpty()) {return true;}return Math.pow(x - mBorderRect.centerX(), 2) + Math.pow(y - mBorderRect.centerY(), 2) <= Math.pow(mBorderRadius, 2);}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)private class OutlineProvider extends ViewOutlineProvider {@Overridepublic void getOutline(View view, Outline outline) {if (mDisableCircularTransformation) {ViewOutlineProvider.BACKGROUND.getOutline(view, outline);} else {Rect bounds = new Rect();mBorderRect.roundOut(bounds);outline.setRoundRect(bounds, bounds.width() / 2.0f);}}}}

 

源码地址:github 源码

这篇关于Android 心形图片心形ImageView、带边框的的心形图片和圆形图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1091862

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Spring MVC 图片上传

引入需要的包 <dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-

Prompt - 将图片的表格转换成Markdown

Prompt - 将图片的表格转换成Markdown 0. 引言1. 提示词2. 原始版本 0. 引言 最近尝试将图片中的表格转换成Markdown格式,需要不断条件和优化提示词。记录一下调整好的提示词,以后在继续优化迭代。 1. 提示词 英文版本: You are an AI assistant tasked with extracting the content of