attributeset
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于attributeset内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在attributeset相关知识领域提供全面立体的资料补充。同时还包含 android、a href、abap 的知识内容,欢迎查阅!
attributeset相关知识
-
直播间搭建Android自定义view,跟随手指滑动public class FollowConstraintLayout extends ConstraintLayout { //移动 private GestureDetector gestureDetector; private OnClickListener l; public FollowConstraintLayout(Context context) { super(context); } public FollowConstraintLayout(Context context, AttributeSet attrs) { super(context, attrs); } public FollowConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
-
android 开发:绘制简单折线图表Android 简单的折线图表绘制类: public class BaseFundChartView extends View { Paint linePaint; Paint textPaint; Paint xyChartPaint; Paint chartLinePaint; public BaseFundChartView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public BaseFundChartView(Context context) { this(context, null); } public BaseFundChartView(Context context, AttributeSet attrs) { this(
-
TextView跑马灯效果实现总结要实现TextView的跑马灯效果比把大象装冰箱还容易,只需要两步。 第一步:自定义一个类继承TextView public class MarqueeTextView extends TextView { public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MarqueeTextView(Context context, AttributeSet attrs) { super(context, attrs); } public MarqueeTextView(Context context) { super(context); } public boolean isFocuse
-
仿照ios回弹公司需要需求上面跟这篇俩都是,适合刚学自定义同学,/*** zhao*/public class MyScrollView extends ScrollView {//要操作Viewprivate View mInnerView;private float y;private Rect normal = new Rect();private boolean animationFlag = true;public MyScrollView(Context context) {super(context);}public MyScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public MyScrollView(Context context, AttributeSet attrs,&nb
attributeset相关课程
attributeset相关教程
- 5. @JvmOverloads @JvmOverloads 的作用指导 Kotlin 编译器为带默认参数值的函数(包括构造函数)生成多个重载函数。源码定义//作用对象是函数和构造函数@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR)@MustBeDocumented@OptionalExpectationpublic expect annotation class JvmOverloads()注解使用该注解使用最多就是用于带默认值函数的重载,在 Android 中我们在自定义 View 的时候一般会重载多个构造器,需要加入该注解,如果不加默认只定义一个构造器,那么当你直接在 XML 使用这个自定义 View 的时候会抛出异常。class ScrollerView @JvmOverloads constructor( context: Context, attr: AttributeSet? = null, defStyle: Int = 0) : View(context, attr, defStyle) { //...}反编译后的 Java 代码public final class ScrollerView extends View { @JvmOverloads public ScrollerView(@NotNull Context context, @Nullable AttributeSet attr, int defStyle) { Intrinsics.checkParameterIsNotNull(context, "context"); super(context, attr, defStyle); } // $FF: synthetic method @JvmOverloads public ScrollerView(Context var1, AttributeSet var2, int var3, int var4, DefaultConstructorMarker var5) { if ((var4 & 2) != 0) { var2 = (AttributeSet)null; } if ((var4 & 4) != 0) { var3 = 0; } this(var1, var2, var3); } @JvmOverloads public ScrollerView(@NotNull Context context, @Nullable AttributeSet attr) { this(context, attr, 0, 4, (DefaultConstructorMarker)null); } @JvmOverloads public ScrollerView(@NotNull Context context) { this(context, (AttributeSet)null, 0, 6, (DefaultConstructorMarker)null); } //...}
- 4. 类的构造器函数 在 Kotlin 中构造器函数是存在 “主从” 关系,这点是 Java 中不存在的,也就是常说的主构造器函数和从构造器函数。比如在上述 Bird 类中需要新增一个带类型 (type) 属性的构造器,就可以定义从构造器,从构造器是利用 constructor 关键字声明。class Bird(val color: String = "green", val age: Int = 3) { //主构造器 constructor( color: String = "green", age: Int = 3, type: String ) : this(color, age) {//使用constructor声明从构造器,:this(color, age)从构造器直接委托调用主构造器函数 //do logical } fun fly() { println("I can fly!") }}fun main() { val smallBird = Bird(color = "blue", age = 8, type = "small")}需要注意的是,在 Kotlin 中默认类都会存在一个无参主构造器函数,除非我们手动指定。此外如果一个存在主构造器,那么从构造器函数就会直接或间接委托调用主构造器,直接委托给主构造器就类似上述例子中的 : this(color, age) ,当然可以通过从构造器 A 委托从构造器 B,然后从构造器 B 委托给主构造器,从而达到间接委托作用。class CustomView : View { constructor(context: Context) : this(context, null)//从构造器A委托调用从构造器B constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)//从构造器B委托调用从构造器C constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {//从构造器C委托调用主构造器 }}
- 3.1 涵盖有关 Kotlin 的知识 Kotlin 中基本语法知识;Kotlin 中自定义属性访问器;Kotlin 中默认值参数实现构造器函数重载以及 @JvmOverloads 注解的使用;Kotlin 标准库中常见的apply,run,with函数的使用(后面语法会有介绍);Kotlin 中默认值参数函数的使用(后面语法会有介绍)。3.2 具体实现代码import android.content.Contextimport android.graphics.*import android.graphics.drawable.BitmapDrawableimport android.graphics.drawable.Drawableimport android.os.Bundleimport android.os.Parcelableimport android.util.AttributeSetimport android.util.TypedValueimport android.widget.ImageViewclass RoundImageView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null, defAttrStyle: Int = 0) : ImageView(context, attributeSet, defAttrStyle) { enum class ShapeType { SHAPE_CIRCLE, SHAPE_ROUND } //defAttr var private var mShapeType: ShapeType = ShapeType.SHAPE_CIRCLE set(value) { field = value invalidate() } private var mBorderWidth: Float = 20f set(value) { field = value invalidate() } private var mBorderColor: Int = Color.parseColor("#ff9900") set(value) { field = value invalidate() } private var mLeftTopRadiusX: Float = 0f set(value) { field = value invalidate() } private var mLeftTopRadiusY: Float = 0f set(value) { field = value invalidate() } private var mRightTopRadiusX: Float = 0f set(value) { field = value invalidate() } private var mRightTopRadiusY: Float = 0f set(value) { field = value invalidate() } private var mLeftBottomRadiusX: Float = 0f set(value) { field = value invalidate() } private var mLeftBottomRadiusY: Float = 0f set(value) { field = value invalidate() } private var mRightBottomRadiusX: Float = 0f set(value) { field = value invalidate() } private var mRightBottomRadiusY: Float = 0f set(value) { field = value invalidate() } private var mShowBorder: Boolean = true set(value) { field = value invalidate() } private var mShowCircleDot: Boolean = false set(value) { field = value invalidate() } private var mCircleDotColor: Int = Color.RED set(value) { field = value invalidate() } private var mCircleDotRadius: Float = 20f set(value) { field = value invalidate() } //drawTools var private lateinit var mShapePath: Path private lateinit var mBorderPath: Path private lateinit var mBitmapPaint: Paint private lateinit var mBorderPaint: Paint private lateinit var mCircleDotPaint: Paint private lateinit var mMatrix: Matrix //temp var private var mWidth: Int = 200//View的宽度 private var mHeight: Int = 200//View的高度 private var mRadius: Float = 100f//圆的半径 init { initAttrs(context, attributeSet, defAttrStyle)//获取自定义属性的值 initDrawTools()//初始化绘制工具 } private fun initAttrs(context: Context, attributeSet: AttributeSet?, defAttrStyle: Int) { val array = context.obtainStyledAttributes(attributeSet, R.styleable.PrettyImageView, defAttrStyle, 0) (0..array.indexCount) .asSequence() .map { array.getIndex(it) } .forEach { when (it) { R.styleable.RoundImageView_shape_type -> mShapeType = when { array.getInt(it, 0) == 0 -> ShapeType.SHAPE_CIRCLE array.getInt(it, 0) == 1 -> ShapeType.SHAPE_ROUND else -> ShapeType.SHAPE_CIRCLE } R.styleable.RoundImageView_border_width -> mBorderWidth = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4f, resources.displayMetrics)) R.styleable.RoundImageView_border_color -> mBorderColor = array.getColor(it, Color.parseColor("#ff0000")) R.styleable.RoundImageView_left_top_radiusX -> mLeftTopRadiusX = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_left_top_radiusY -> mLeftTopRadiusY = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_left_bottom_radiusX -> mLeftBottomRadiusX = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_left_bottom_radiusY -> mLeftBottomRadiusY = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_right_bottom_radiusX -> mRightBottomRadiusX = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_right_bottom_radiusY -> mRightBottomRadiusY = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_right_top_radiusX -> mRightTopRadiusX = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_right_top_radiusY -> mRightTopRadiusY = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0f, resources.displayMetrics)) R.styleable.RoundImageView_show_border -> mShowBorder = array.getBoolean(it, false) R.styleable.RoundImageView_show_circle_dot -> mShowCircleDot = array.getBoolean(it, false) R.styleable.RoundImageView_circle_dot_color -> mCircleDotColor = array.getColor(it, Color.parseColor("#ff0000")) R.styleable.RoundImageView_circle_dot_radius -> mCircleDotRadius = array.getDimension(it, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5f, resources.displayMetrics)) } } array.recycle() } private fun initDrawTools() { mBitmapPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { //最终绘制图片的画笔,需要设置BitmapShader着色器,从而实现把图片绘制在不同形状图形上 style = Paint.Style.FILL } mBorderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { //绘制边框画笔 style = Paint.Style.STROKE color = mBorderColor strokeCap = Paint.Cap.ROUND strokeWidth = mBorderWidth } mCircleDotPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { //绘制右上角圆点画笔 style = Paint.Style.FILL color = mCircleDotColor } mShapePath = Path()//描述形状轮廓的path路径 mBorderPath = Path()//描述图片边框轮廓的path路径 mMatrix = Matrix()//用于缩放图片的矩阵 scaleType = ScaleType.CENTER_CROP } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {//View的测量 super.onMeasure(widthMeasureSpec, heightMeasureSpec) if (mShapeType == ShapeType.SHAPE_CIRCLE) { mWidth = Math.min(measuredWidth, measuredHeight) mRadius = mWidth / 2.0f setMeasuredDimension(mWidth, mWidth) } else { mWidth = measuredWidth mHeight = measuredHeight setMeasuredDimension(mWidth, mHeight) } } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {//确定了最终View的尺寸 super.onSizeChanged(w, h, oldw, oldh) mBorderPath.reset() mShapePath.reset() when (mShapeType) { ShapeType.SHAPE_ROUND -> { mWidth = w mHeight = h buildRoundPath() } ShapeType.SHAPE_CIRCLE -> { buildCirclePath() } } } private fun buildCirclePath() {//构建圆形类型的Path路径 if (!mShowBorder) {//绘制不带边框的圆形实际上只需要把一个圆形扔进path即可 mShapePath.addCircle(mRadius, mRadius, mRadius, Path.Direction.CW) } else {//绘制带边框的圆形需要把内部圆形和外部圆形边框都要扔进path mShapePath.addCircle(mRadius, mRadius, mRadius - mBorderWidth, Path.Direction.CW) mBorderPath.addCircle(mRadius, mRadius, mRadius - mBorderWidth / 2.0f, Path.Direction.CW) } } private fun buildRoundPath() {//构建圆角类型的Path路径 if (!mShowBorder) {//绘制不带边框的圆角实际上只需要把一个圆角矩形扔进path即可 floatArrayOf(mLeftTopRadiusX, mLeftTopRadiusY, mRightTopRadiusX, mRightTopRadiusY, mRightBottomRadiusX, mRightBottomRadiusY, mLeftBottomRadiusX, mLeftBottomRadiusY).run { mShapePath.addRoundRect(RectF(0f, 0f, mWidth.toFloat(), mHeight.toFloat()), this, Path.Direction.CW) } } else {//绘制带边框的圆角实际上只需要把一个圆角矩形和一个圆角矩形的变量都扔进path即可 floatArrayOf(mLeftTopRadiusX - mBorderWidth / 2.0f, mLeftTopRadiusY - mBorderWidth / 2.0f, mRightTopRadiusX - mBorderWidth / 2.0f, mRightTopRadiusY - mBorderWidth / 2.0f, mRightBottomRadiusX - mBorderWidth / 2.0f, mRightBottomRadiusY - mBorderWidth / 2.0f, mLeftBottomRadiusX - mBorderWidth / 2.0f, mLeftBottomRadiusY - mBorderWidth / 2.0f).run { mBorderPath.addRoundRect(RectF(mBorderWidth / 2.0f, mBorderWidth / 2.0f, mWidth.toFloat() - mBorderWidth / 2.0f, mHeight.toFloat() - mBorderWidth / 2.0f), this, Path.Direction.CW) } floatArrayOf(mLeftTopRadiusX - mBorderWidth, mLeftTopRadiusY - mBorderWidth, mRightTopRadiusX - mBorderWidth, mRightTopRadiusY - mBorderWidth, mRightBottomRadiusX - mBorderWidth, mRightBottomRadiusY - mBorderWidth, mLeftBottomRadiusX - mBorderWidth, mLeftBottomRadiusY - mBorderWidth).run { mShapePath.addRoundRect(RectF(mBorderWidth, mBorderWidth, mWidth.toFloat() - mBorderWidth, mHeight.toFloat() - mBorderWidth), this, Path.Direction.CW) } } } override fun onDraw(canvas: Canvas?) {//由于经过以上根据不同逻辑构建了boderPath和shapePath,path中已经储存相应的形状,现在只需要把相应shapePath中形状用带BitmapShader画笔绘制出来,boderPath用普通画笔绘制出来即可 drawable ?: return mBitmapPaint.shader = getBitmapShader()//获得相应的BitmapShader着色器对象 when (mShapeType) { ShapeType.SHAPE_CIRCLE -> { if (mShowBorder) { canvas?.drawPath(mBorderPath, mBorderPaint)//绘制圆形图片边框path } canvas?.drawPath(mShapePath, mBitmapPaint)//绘制圆形图片形状path if (mShowCircleDot) { drawCircleDot(canvas)//绘制圆形图片右上角圆点 } } ShapeType.SHAPE_ROUND -> { if (mShowBorder) { canvas?.drawPath(mBorderPath, mBorderPaint)//绘制圆角图片边框path } canvas?.drawPath(mShapePath, mBitmapPaint)//绘制圆角图片形状path } } } private fun drawCircleDot(canvas: Canvas?) { canvas?.run { drawCircle((mRadius + mRadius * (Math.sqrt(2.0) / 2.0f)).toFloat(), (mRadius - mRadius * (Math.sqrt(2.0) / 2.0f)).toFloat(), mCircleDotRadius, mCircleDotPaint) } } private fun getBitmapShader(): BitmapShader { val bitmap = drawableToBitmap(drawable) return BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP).apply { var scale = 1.0f if (mShapeType == ShapeType.SHAPE_CIRCLE) { scale = (mWidth * 1.0f / Math.min(bitmap.width, bitmap.height)) } else if (mShapeType == ShapeType.SHAPE_ROUND) { // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; if (!(width == bitmap.width && width == bitmap.height)) { scale = Math.max(width * 1.0f / bitmap.width, height * 1.0f / bitmap.height) } } // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.setScale(scale, scale) setLocalMatrix(mMatrix) } } private fun drawableToBitmap(drawable: Drawable): Bitmap { if (drawable is BitmapDrawable) { return drawable.bitmap } return Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888).apply { drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight) drawable.draw(Canvas(this@apply)) } } companion object { private const val STATE_INSTANCE = "state_instance" private const val STATE_INSTANCE_SHAPE_TYPE = "state_shape_type" private const val STATE_INSTANCE_BORDER_WIDTH = "state_border_width" private const val STATE_INSTANCE_BORDER_COLOR = "state_border_color" private const val STATE_INSTANCE_RADIUS_LEFT_TOP_X = "state_radius_left_top_x" private const val STATE_INSTANCE_RADIUS_LEFT_TOP_Y = "state_radius_left_top_y" private const val STATE_INSTANCE_RADIUS_LEFT_BOTTOM_X = "state_radius_left_bottom_x" private const val STATE_INSTANCE_RADIUS_LEFT_BOTTOM_Y = "state_radius_left_bottom_y" private const val STATE_INSTANCE_RADIUS_RIGHT_TOP_X = "state_radius_right_top_x" private const val STATE_INSTANCE_RADIUS_RIGHT_TOP_Y = "state_radius_right_top_y" private const val STATE_INSTANCE_RADIUS_RIGHT_BOTTOM_X = "state_radius_right_bottom_x" private const val STATE_INSTANCE_RADIUS_RIGHT_BOTTOM_Y = "state_radius_right_bottom_y" private const val STATE_INSTANCE_RADIUS = "state_radius" private const val STATE_INSTANCE_SHOW_BORDER = "state_radius_show_border" } //View State Save override fun onSaveInstanceState(): Parcelable = Bundle().apply { putParcelable(STATE_INSTANCE, super.onSaveInstanceState()) putInt(STATE_INSTANCE_SHAPE_TYPE, when (mShapeType) { ShapeType.SHAPE_CIRCLE -> 0 ShapeType.SHAPE_ROUND -> 1 }) putFloat(STATE_INSTANCE_BORDER_WIDTH, mBorderWidth) putInt(STATE_INSTANCE_BORDER_COLOR, mBorderColor) putFloat(STATE_INSTANCE_RADIUS_LEFT_TOP_X, mLeftTopRadiusX) putFloat(STATE_INSTANCE_RADIUS_LEFT_TOP_Y, mLeftTopRadiusY) putFloat(STATE_INSTANCE_RADIUS_LEFT_BOTTOM_X, mLeftBottomRadiusX) putFloat(STATE_INSTANCE_RADIUS_LEFT_BOTTOM_Y, mLeftBottomRadiusY) putFloat(STATE_INSTANCE_RADIUS_RIGHT_TOP_X, mRightTopRadiusX) putFloat(STATE_INSTANCE_RADIUS_RIGHT_TOP_Y, mRightTopRadiusY) putFloat(STATE_INSTANCE_RADIUS_RIGHT_BOTTOM_X, mRightBottomRadiusX) putFloat(STATE_INSTANCE_RADIUS_RIGHT_BOTTOM_Y, mRightBottomRadiusY) putFloat(STATE_INSTANCE_RADIUS, mRadius) putBoolean(STATE_INSTANCE_SHOW_BORDER, mShowBorder) } //View State Restore override fun onRestoreInstanceState(state: Parcelable?) { if (state !is Bundle) { super.onRestoreInstanceState(state) return } with(state) { super.onRestoreInstanceState(getParcelable(STATE_INSTANCE)) mShapeType = when { getInt(STATE_INSTANCE_SHAPE_TYPE) == 0 -> ShapeType.SHAPE_CIRCLE getInt(STATE_INSTANCE_SHAPE_TYPE) == 1 -> ShapeType.SHAPE_ROUND else -> ShapeType.SHAPE_CIRCLE } mBorderWidth = getFloat(STATE_INSTANCE_BORDER_WIDTH) mBorderColor = getInt(STATE_INSTANCE_BORDER_COLOR) mLeftTopRadiusX = getFloat(STATE_INSTANCE_RADIUS_LEFT_TOP_X) mLeftTopRadiusY = getFloat(STATE_INSTANCE_RADIUS_LEFT_TOP_Y) mLeftBottomRadiusX = getFloat(STATE_INSTANCE_RADIUS_LEFT_BOTTOM_X) mLeftBottomRadiusY = getFloat(STATE_INSTANCE_RADIUS_LEFT_BOTTOM_Y) mRightTopRadiusX = getFloat(STATE_INSTANCE_RADIUS_RIGHT_TOP_X) mRightTopRadiusY = getFloat(STATE_INSTANCE_RADIUS_RIGHT_TOP_Y) mRightBottomRadiusX = getFloat(STATE_INSTANCE_RADIUS_RIGHT_BOTTOM_X) mRightBottomRadiusY = getFloat(STATE_INSTANCE_RADIUS_RIGHT_BOTTOM_Y) mRadius = getFloat(STATE_INSTANCE_RADIUS) mShowBorder = getBoolean(STATE_INSTANCE_SHOW_BORDER) } }}
- 4-2 查询角色分页数据(后端) 企业级在线办公系统
- 雪碧图和雪碧之间有什么关系? 零基础学习性能优化及帧动画必学技能
- ES6+ Object.keys() 零基础深入浅出讲解 ES6+ 的语法及使用
attributeset相关搜索
-
ajax
android
a href
abap
abap开发
abort
absolutelayout
abstractmethoderror
abstracttablemodel
accept
access
access教程
accordion
accumulate
acess
action
actionform
actionlistener
activity
addeventlistener