parent
a0463171c0
commit
6f260e4f1d
@ -1,119 +0,0 @@ |
|||||||
package io.legado.app.ui.widget; |
|
||||||
|
|
||||||
import android.app.SearchableInfo; |
|
||||||
import android.content.Context; |
|
||||||
import android.graphics.Canvas; |
|
||||||
import android.graphics.Paint; |
|
||||||
import android.graphics.drawable.Drawable; |
|
||||||
import android.text.Spannable; |
|
||||||
import android.text.SpannableStringBuilder; |
|
||||||
import android.text.style.ImageSpan; |
|
||||||
import android.util.AttributeSet; |
|
||||||
import android.util.TypedValue; |
|
||||||
import android.view.Gravity; |
|
||||||
import android.widget.TextView; |
|
||||||
|
|
||||||
import androidx.annotation.NonNull; |
|
||||||
import androidx.annotation.Nullable; |
|
||||||
import io.legado.app.R; |
|
||||||
|
|
||||||
public class SearchView extends androidx.appcompat.widget.SearchView { |
|
||||||
private Drawable mSearchHintIcon = null; |
|
||||||
private TextView textView = null; |
|
||||||
|
|
||||||
public SearchView(Context context) { |
|
||||||
this(context, null); |
|
||||||
} |
|
||||||
|
|
||||||
public SearchView(Context context, AttributeSet attrs) { |
|
||||||
super(context, attrs); |
|
||||||
} |
|
||||||
|
|
||||||
public SearchView(Context context, AttributeSet attrs, int defStyleAttr) { |
|
||||||
super(context, attrs, defStyleAttr); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { |
|
||||||
super.onLayout(changed, left, top, right, bottom); |
|
||||||
try { |
|
||||||
if (textView == null) { |
|
||||||
textView = (TextView) this.findViewById(androidx.appcompat.R.id.search_src_text); |
|
||||||
mSearchHintIcon = this.getContext().getDrawable(R.drawable.ic_search_hint); |
|
||||||
updateQueryHint(); |
|
||||||
} |
|
||||||
// 改变字体
|
|
||||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); |
|
||||||
textView.setGravity(Gravity.CENTER_VERTICAL); |
|
||||||
} catch (Exception e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
private CharSequence getDecoratedHint(CharSequence hintText) { |
|
||||||
// If the field is always expanded or we don't have a search hint icon,
|
|
||||||
// then don't add the search icon to the hint.
|
|
||||||
if (mSearchHintIcon == null) { |
|
||||||
return hintText; |
|
||||||
} |
|
||||||
|
|
||||||
final int textSize = (int) (textView.getTextSize() * 0.8); |
|
||||||
mSearchHintIcon.setBounds(0, 0, textSize, textSize); |
|
||||||
|
|
||||||
final SpannableStringBuilder ssb = new SpannableStringBuilder(" "); |
|
||||||
ssb.setSpan(new CenteredImageSpan(mSearchHintIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); |
|
||||||
ssb.append(hintText); |
|
||||||
return ssb; |
|
||||||
} |
|
||||||
|
|
||||||
private void updateQueryHint() { |
|
||||||
if (textView != null) { |
|
||||||
final CharSequence hint = getQueryHint(); |
|
||||||
textView.setHint(getDecoratedHint(hint == null ? "" : hint)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setIconifiedByDefault(boolean iconified) { |
|
||||||
super.setIconifiedByDefault(iconified); |
|
||||||
updateQueryHint(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setSearchableInfo(SearchableInfo searchable) { |
|
||||||
super.setSearchableInfo(searchable); |
|
||||||
if (searchable != null) |
|
||||||
updateQueryHint(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void setQueryHint(@Nullable CharSequence hint) { |
|
||||||
super.setQueryHint(hint); |
|
||||||
updateQueryHint(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class CenteredImageSpan extends ImageSpan { |
|
||||||
|
|
||||||
public CenteredImageSpan(final Drawable drawable) { |
|
||||||
super(drawable); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void draw(@NonNull Canvas canvas, CharSequence text, |
|
||||||
int start, int end, float x, |
|
||||||
int top, int y, int bottom, @NonNull Paint paint) { |
|
||||||
// image to draw
|
|
||||||
Drawable b = getDrawable(); |
|
||||||
// font metrics of text to be replaced
|
|
||||||
Paint.FontMetricsInt fm = paint.getFontMetricsInt(); |
|
||||||
int transY = (y + fm.descent + y + fm.ascent) / 2 |
|
||||||
- b.getBounds().bottom / 2; |
|
||||||
|
|
||||||
canvas.save(); |
|
||||||
canvas.translate(x, transY); |
|
||||||
b.draw(canvas); |
|
||||||
canvas.restore(); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,113 @@ |
|||||||
|
package io.legado.app.ui.widget |
||||||
|
|
||||||
|
import android.app.SearchableInfo |
||||||
|
import android.content.Context |
||||||
|
import android.graphics.Canvas |
||||||
|
import android.graphics.Paint |
||||||
|
import android.graphics.drawable.Drawable |
||||||
|
import android.text.Spannable |
||||||
|
import android.text.SpannableStringBuilder |
||||||
|
import android.text.style.ImageSpan |
||||||
|
import android.util.AttributeSet |
||||||
|
import android.util.TypedValue |
||||||
|
import android.view.Gravity |
||||||
|
import android.view.View |
||||||
|
import android.widget.TextView |
||||||
|
import androidx.appcompat.widget.SearchView |
||||||
|
import io.legado.app.R |
||||||
|
|
||||||
|
class SearchView : SearchView { |
||||||
|
private var mSearchHintIcon: Drawable? = null |
||||||
|
private var textView: TextView? = null |
||||||
|
|
||||||
|
constructor( |
||||||
|
context: Context?, |
||||||
|
attrs: AttributeSet? = null |
||||||
|
) : super(context, attrs) |
||||||
|
|
||||||
|
constructor( |
||||||
|
context: Context?, |
||||||
|
attrs: AttributeSet?, |
||||||
|
defStyleAttr: Int |
||||||
|
) : super(context, attrs, defStyleAttr) |
||||||
|
|
||||||
|
override fun onLayout( |
||||||
|
changed: Boolean, |
||||||
|
left: Int, |
||||||
|
top: Int, |
||||||
|
right: Int, |
||||||
|
bottom: Int |
||||||
|
) { |
||||||
|
super.onLayout(changed, left, top, right, bottom) |
||||||
|
try { |
||||||
|
if (textView == null) { |
||||||
|
textView = |
||||||
|
findViewById<View>(androidx.appcompat.R.id.search_src_text) as TextView |
||||||
|
mSearchHintIcon = this.context.getDrawable(R.drawable.ic_search_hint) |
||||||
|
updateQueryHint() |
||||||
|
} |
||||||
|
// 改变字体 |
||||||
|
textView!!.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f) |
||||||
|
textView!!.gravity = Gravity.CENTER_VERTICAL |
||||||
|
} catch (e: Exception) { |
||||||
|
e.printStackTrace() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private fun getDecoratedHint(hintText: CharSequence): CharSequence { |
||||||
|
// If the field is always expanded or we don't have a search hint icon, |
||||||
|
// then don't add the search icon to the hint. |
||||||
|
if (mSearchHintIcon == null) { |
||||||
|
return hintText |
||||||
|
} |
||||||
|
val textSize = (textView!!.textSize * 0.8).toInt() |
||||||
|
mSearchHintIcon!!.setBounds(0, 0, textSize, textSize) |
||||||
|
val ssb = SpannableStringBuilder(" ") |
||||||
|
ssb.setSpan(CenteredImageSpan(mSearchHintIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) |
||||||
|
ssb.append(hintText) |
||||||
|
return ssb |
||||||
|
} |
||||||
|
|
||||||
|
private fun updateQueryHint() { |
||||||
|
if (textView != null) { |
||||||
|
val hint = queryHint |
||||||
|
textView!!.hint = getDecoratedHint(hint ?: "") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun setIconifiedByDefault(iconified: Boolean) { |
||||||
|
super.setIconifiedByDefault(iconified) |
||||||
|
updateQueryHint() |
||||||
|
} |
||||||
|
|
||||||
|
override fun setSearchableInfo(searchable: SearchableInfo?) { |
||||||
|
super.setSearchableInfo(searchable) |
||||||
|
searchable?.let { |
||||||
|
updateQueryHint() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun setQueryHint(hint: CharSequence?) { |
||||||
|
super.setQueryHint(hint) |
||||||
|
updateQueryHint() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal class CenteredImageSpan(drawable: Drawable?) : ImageSpan(drawable!!) { |
||||||
|
override fun draw( |
||||||
|
canvas: Canvas, text: CharSequence, |
||||||
|
start: Int, end: Int, x: Float, |
||||||
|
top: Int, y: Int, bottom: Int, paint: Paint |
||||||
|
) { |
||||||
|
// image to draw |
||||||
|
val b = drawable |
||||||
|
// font metrics of text to be replaced |
||||||
|
val fm = paint.fontMetricsInt |
||||||
|
val transY = ((y + fm.descent + y + fm.ascent) / 2 |
||||||
|
- b.bounds.bottom / 2) |
||||||
|
canvas.save() |
||||||
|
canvas.translate(x, transY.toFloat()) |
||||||
|
b.draw(canvas) |
||||||
|
canvas.restore() |
||||||
|
} |
||||||
|
} |
@ -1,195 +0,0 @@ |
|||||||
package io.legado.app.ui.widget; |
|
||||||
|
|
||||||
import android.content.Context; |
|
||||||
import android.content.res.TypedArray; |
|
||||||
import android.graphics.Canvas; |
|
||||||
import android.graphics.Color; |
|
||||||
import android.graphics.Paint; |
|
||||||
import android.graphics.RectF; |
|
||||||
import android.util.AttributeSet; |
|
||||||
import android.util.DisplayMetrics; |
|
||||||
import android.view.View; |
|
||||||
import android.widget.RelativeLayout; |
|
||||||
import io.legado.app.R; |
|
||||||
|
|
||||||
/** |
|
||||||
* ShadowLayout.java |
|
||||||
* <p> |
|
||||||
* Created by lijiankun on 17/8/11. |
|
||||||
*/ |
|
||||||
|
|
||||||
public class ShadowLayout extends RelativeLayout { |
|
||||||
|
|
||||||
public static final int ALL = 0x1111; |
|
||||||
|
|
||||||
public static final int LEFT = 0x0001; |
|
||||||
|
|
||||||
public static final int TOP = 0x0010; |
|
||||||
|
|
||||||
public static final int RIGHT = 0x0100; |
|
||||||
|
|
||||||
public static final int BOTTOM = 0x1000; |
|
||||||
|
|
||||||
public static final int SHAPE_RECTANGLE = 0x0001; |
|
||||||
|
|
||||||
public static final int SHAPE_OVAL = 0x0010; |
|
||||||
|
|
||||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); |
|
||||||
|
|
||||||
private RectF mRectF = new RectF(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 阴影的颜色 |
|
||||||
*/ |
|
||||||
private int mShadowColor = Color.TRANSPARENT; |
|
||||||
|
|
||||||
/** |
|
||||||
* 阴影的大小范围 |
|
||||||
*/ |
|
||||||
private float mShadowRadius = 0; |
|
||||||
|
|
||||||
/** |
|
||||||
* 阴影 x 轴的偏移量 |
|
||||||
*/ |
|
||||||
private float mShadowDx = 0; |
|
||||||
|
|
||||||
/** |
|
||||||
* 阴影 y 轴的偏移量 |
|
||||||
*/ |
|
||||||
private float mShadowDy = 0; |
|
||||||
|
|
||||||
/** |
|
||||||
* 阴影显示的边界 |
|
||||||
*/ |
|
||||||
private int mShadowSide = ALL; |
|
||||||
|
|
||||||
/** |
|
||||||
* 阴影的形状,圆形/矩形 |
|
||||||
*/ |
|
||||||
private int mShadowShape = SHAPE_RECTANGLE; |
|
||||||
|
|
||||||
public ShadowLayout(Context context) { |
|
||||||
this(context, null); |
|
||||||
} |
|
||||||
|
|
||||||
public ShadowLayout(Context context, AttributeSet attrs) { |
|
||||||
this(context, attrs, 0); |
|
||||||
} |
|
||||||
|
|
||||||
public ShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) { |
|
||||||
super(context, attrs, defStyleAttr); |
|
||||||
init(attrs); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
|
||||||
float effect = mShadowRadius + dip2px(5); |
|
||||||
float rectLeft = 0; |
|
||||||
float rectTop = 0; |
|
||||||
float rectRight = this.getMeasuredWidth(); |
|
||||||
float rectBottom = this.getMeasuredHeight(); |
|
||||||
int paddingLeft = 0; |
|
||||||
int paddingTop = 0; |
|
||||||
int paddingRight = 0; |
|
||||||
int paddingBottom = 0; |
|
||||||
this.getWidth(); |
|
||||||
if ((mShadowSide & LEFT) == LEFT) { |
|
||||||
rectLeft = effect; |
|
||||||
paddingLeft = (int) effect; |
|
||||||
} |
|
||||||
if ((mShadowSide & TOP) == TOP) { |
|
||||||
rectTop = effect; |
|
||||||
paddingTop = (int) effect; |
|
||||||
} |
|
||||||
if ((mShadowSide & RIGHT) == RIGHT) { |
|
||||||
rectRight = this.getMeasuredWidth() - effect; |
|
||||||
paddingRight = (int) effect; |
|
||||||
} |
|
||||||
if ((mShadowSide & BOTTOM) == BOTTOM) { |
|
||||||
rectBottom = this.getMeasuredHeight() - effect; |
|
||||||
paddingBottom = (int) effect; |
|
||||||
} |
|
||||||
if (mShadowDy != 0.0f) { |
|
||||||
rectBottom = rectBottom - mShadowDy; |
|
||||||
paddingBottom = paddingBottom + (int) mShadowDy; |
|
||||||
} |
|
||||||
if (mShadowDx != 0.0f) { |
|
||||||
rectRight = rectRight - mShadowDx; |
|
||||||
paddingRight = paddingRight + (int) mShadowDx; |
|
||||||
} |
|
||||||
mRectF.left = rectLeft; |
|
||||||
mRectF.top = rectTop; |
|
||||||
mRectF.right = rectRight; |
|
||||||
mRectF.bottom = rectBottom; |
|
||||||
this.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 真正绘制阴影的方法 |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected void onDraw(Canvas canvas) { |
|
||||||
super.onDraw(canvas); |
|
||||||
setUpShadowPaint(); |
|
||||||
if (mShadowShape == SHAPE_RECTANGLE) { |
|
||||||
canvas.drawRect(mRectF, mPaint); |
|
||||||
} else if (mShadowShape == SHAPE_OVAL) { |
|
||||||
canvas.drawCircle(mRectF.centerX(), mRectF.centerY(), Math.min(mRectF.width(), mRectF.height()) / 2, mPaint); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void setShadowColor(int shadowColor) { |
|
||||||
mShadowColor = shadowColor; |
|
||||||
requestLayout(); |
|
||||||
postInvalidate(); |
|
||||||
} |
|
||||||
|
|
||||||
public void setShadowRadius(float shadowRadius) { |
|
||||||
mShadowRadius = shadowRadius; |
|
||||||
requestLayout(); |
|
||||||
postInvalidate(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 读取设置的阴影的属性 |
|
||||||
* |
|
||||||
* @param attrs 从其中获取设置的值 |
|
||||||
*/ |
|
||||||
private void init(AttributeSet attrs) { |
|
||||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null); // 关闭硬件加速
|
|
||||||
this.setWillNotDraw(false); // 调用此方法后,才会执行 onDraw(Canvas) 方法
|
|
||||||
|
|
||||||
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ShadowLayout); |
|
||||||
if (typedArray != null) { |
|
||||||
mShadowColor = typedArray.getColor(R.styleable.ShadowLayout_shadowColor, |
|
||||||
getContext().getResources().getColor(android.R.color.black)); |
|
||||||
mShadowRadius = typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius, dip2px(0)); |
|
||||||
mShadowDx = typedArray.getDimension(R.styleable.ShadowLayout_shadowDx, dip2px(0)); |
|
||||||
mShadowDy = typedArray.getDimension(R.styleable.ShadowLayout_shadowDy, dip2px(0)); |
|
||||||
mShadowSide = typedArray.getInt(R.styleable.ShadowLayout_shadowSide, ALL); |
|
||||||
mShadowShape = typedArray.getInt(R.styleable.ShadowLayout_shadowShape, SHAPE_RECTANGLE); |
|
||||||
typedArray.recycle(); |
|
||||||
} |
|
||||||
setUpShadowPaint(); |
|
||||||
} |
|
||||||
|
|
||||||
private void setUpShadowPaint() { |
|
||||||
mPaint.reset(); |
|
||||||
mPaint.setAntiAlias(true); |
|
||||||
mPaint.setColor(Color.TRANSPARENT); |
|
||||||
mPaint.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* dip2px dp 值转 px 值 |
|
||||||
* |
|
||||||
* @param dpValue dp 值 |
|
||||||
* @return px 值 |
|
||||||
*/ |
|
||||||
private float dip2px(float dpValue) { |
|
||||||
DisplayMetrics dm = getContext().getResources().getDisplayMetrics(); |
|
||||||
float scale = dm.density; |
|
||||||
return (dpValue * scale + 0.5F); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,185 @@ |
|||||||
|
package io.legado.app.ui.widget |
||||||
|
|
||||||
|
import android.content.Context |
||||||
|
import android.graphics.Canvas |
||||||
|
import android.graphics.Color |
||||||
|
import android.graphics.Paint |
||||||
|
import android.graphics.RectF |
||||||
|
import android.util.AttributeSet |
||||||
|
import android.view.View |
||||||
|
import android.widget.RelativeLayout |
||||||
|
import io.legado.app.R |
||||||
|
import io.legado.app.utils.getCompatColor |
||||||
|
|
||||||
|
/** |
||||||
|
* ShadowLayout.java |
||||||
|
* |
||||||
|
* |
||||||
|
* Created by lijiankun on 17/8/11. |
||||||
|
*/ |
||||||
|
class ShadowLayout( |
||||||
|
context: Context, |
||||||
|
attrs: AttributeSet? = null |
||||||
|
) : RelativeLayout(context, attrs) { |
||||||
|
private val mPaint = |
||||||
|
Paint(Paint.ANTI_ALIAS_FLAG) |
||||||
|
private val mRectF = RectF() |
||||||
|
|
||||||
|
/** |
||||||
|
* 阴影的颜色 |
||||||
|
*/ |
||||||
|
private var mShadowColor = Color.TRANSPARENT |
||||||
|
|
||||||
|
/** |
||||||
|
* 阴影的大小范围 |
||||||
|
*/ |
||||||
|
private var mShadowRadius = 0f |
||||||
|
|
||||||
|
/** |
||||||
|
* 阴影 x 轴的偏移量 |
||||||
|
*/ |
||||||
|
private var mShadowDx = 0f |
||||||
|
|
||||||
|
/** |
||||||
|
* 阴影 y 轴的偏移量 |
||||||
|
*/ |
||||||
|
private var mShadowDy = 0f |
||||||
|
|
||||||
|
/** |
||||||
|
* 阴影显示的边界 |
||||||
|
*/ |
||||||
|
private var mShadowSide = ALL |
||||||
|
|
||||||
|
/** |
||||||
|
* 阴影的形状,圆形/矩形 |
||||||
|
*/ |
||||||
|
private var mShadowShape = SHAPE_RECTANGLE |
||||||
|
|
||||||
|
|
||||||
|
init { |
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null) // 关闭硬件加速 |
||||||
|
setWillNotDraw(false) // 调用此方法后,才会执行 onDraw(Canvas) 方法 |
||||||
|
val typedArray = |
||||||
|
context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout) |
||||||
|
mShadowColor = typedArray.getColor( |
||||||
|
R.styleable.ShadowLayout_shadowColor, |
||||||
|
context.getCompatColor(android.R.color.black) |
||||||
|
) |
||||||
|
mShadowRadius = |
||||||
|
typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius, dip2px(0f)) |
||||||
|
mShadowDx = typedArray.getDimension(R.styleable.ShadowLayout_shadowDx, dip2px(0f)) |
||||||
|
mShadowDy = typedArray.getDimension(R.styleable.ShadowLayout_shadowDy, dip2px(0f)) |
||||||
|
mShadowSide = |
||||||
|
typedArray.getInt(R.styleable.ShadowLayout_shadowSide, ALL) |
||||||
|
mShadowShape = typedArray.getInt( |
||||||
|
R.styleable.ShadowLayout_shadowShape, |
||||||
|
SHAPE_RECTANGLE |
||||||
|
) |
||||||
|
typedArray.recycle() |
||||||
|
|
||||||
|
setUpShadowPaint() |
||||||
|
} |
||||||
|
|
||||||
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { |
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec) |
||||||
|
val effect = mShadowRadius + dip2px(5f) |
||||||
|
var rectLeft = 0f |
||||||
|
var rectTop = 0f |
||||||
|
var rectRight = this.measuredWidth.toFloat() |
||||||
|
var rectBottom = this.measuredHeight.toFloat() |
||||||
|
var paddingLeft = 0 |
||||||
|
var paddingTop = 0 |
||||||
|
var paddingRight = 0 |
||||||
|
var paddingBottom = 0 |
||||||
|
this.width |
||||||
|
if (mShadowSide and LEFT == LEFT) { |
||||||
|
rectLeft = effect |
||||||
|
paddingLeft = effect.toInt() |
||||||
|
} |
||||||
|
if (mShadowSide and TOP == TOP) { |
||||||
|
rectTop = effect |
||||||
|
paddingTop = effect.toInt() |
||||||
|
} |
||||||
|
if (mShadowSide and RIGHT == RIGHT) { |
||||||
|
rectRight = this.measuredWidth - effect |
||||||
|
paddingRight = effect.toInt() |
||||||
|
} |
||||||
|
if (mShadowSide and BOTTOM == BOTTOM) { |
||||||
|
rectBottom = this.measuredHeight - effect |
||||||
|
paddingBottom = effect.toInt() |
||||||
|
} |
||||||
|
if (mShadowDy != 0.0f) { |
||||||
|
rectBottom -= mShadowDy |
||||||
|
paddingBottom += mShadowDy.toInt() |
||||||
|
} |
||||||
|
if (mShadowDx != 0.0f) { |
||||||
|
rectRight -= mShadowDx |
||||||
|
paddingRight += mShadowDx.toInt() |
||||||
|
} |
||||||
|
mRectF.left = rectLeft |
||||||
|
mRectF.top = rectTop |
||||||
|
mRectF.right = rectRight |
||||||
|
mRectF.bottom = rectBottom |
||||||
|
setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 真正绘制阴影的方法 |
||||||
|
*/ |
||||||
|
override fun onDraw(canvas: Canvas) { |
||||||
|
super.onDraw(canvas) |
||||||
|
setUpShadowPaint() |
||||||
|
if (mShadowShape == SHAPE_RECTANGLE) { |
||||||
|
canvas.drawRect(mRectF, mPaint) |
||||||
|
} else if (mShadowShape == SHAPE_OVAL) { |
||||||
|
canvas.drawCircle( |
||||||
|
mRectF.centerX(), |
||||||
|
mRectF.centerY(), |
||||||
|
mRectF.width().coerceAtMost(mRectF.height()) / 2, |
||||||
|
mPaint |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun setShadowColor(shadowColor: Int) { |
||||||
|
mShadowColor = shadowColor |
||||||
|
requestLayout() |
||||||
|
postInvalidate() |
||||||
|
} |
||||||
|
|
||||||
|
fun setShadowRadius(shadowRadius: Float) { |
||||||
|
mShadowRadius = shadowRadius |
||||||
|
requestLayout() |
||||||
|
postInvalidate() |
||||||
|
} |
||||||
|
|
||||||
|
private fun setUpShadowPaint() { |
||||||
|
mPaint.reset() |
||||||
|
mPaint.isAntiAlias = true |
||||||
|
mPaint.color = Color.TRANSPARENT |
||||||
|
mPaint.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* dip2px dp 值转 px 值 |
||||||
|
* |
||||||
|
* @param dpValue dp 值 |
||||||
|
* @return px 值 |
||||||
|
*/ |
||||||
|
private fun dip2px(dpValue: Float): Float { |
||||||
|
val dm = context.resources.displayMetrics |
||||||
|
val scale = dm.density |
||||||
|
return dpValue * scale + 0.5f |
||||||
|
} |
||||||
|
|
||||||
|
companion object { |
||||||
|
const val ALL = 0x1111 |
||||||
|
const val LEFT = 0x0001 |
||||||
|
const val TOP = 0x0010 |
||||||
|
const val RIGHT = 0x0100 |
||||||
|
const val BOTTOM = 0x1000 |
||||||
|
const val SHAPE_RECTANGLE = 0x0001 |
||||||
|
const val SHAPE_OVAL = 0x0010 |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue