基础弹框实现XPopupShowmaker
import android.view.View;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
public interface ILayout {
int HIDE_RADIUS_SIDE_NONE = 0;
int HIDE_RADIUS_SIDE_TOP = 1;
int HIDE_RADIUS_SIDE_RIGHT = 2;
int HIDE_RADIUS_SIDE_BOTTOM = 3;
int HIDE_RADIUS_SIDE_LEFT = 4;
@IntDef(value = {
HIDE_RADIUS_SIDE_NONE,
HIDE_RADIUS_SIDE_TOP,
HIDE_RADIUS_SIDE_RIGHT,
HIDE_RADIUS_SIDE_BOTTOM,
HIDE_RADIUS_SIDE_LEFT})
@Retention(RetentionPolicy.SOURCE)
@interface HideRadiusSide {
}
boolean setWidthLimit(int widthLimit);
boolean setHeightLimit(int heightLimit);
void setUseThemeGeneralShadowElevation();
void setOutlineExcludePadding(boolean outlineExcludePadding);
void setShadowElevation(int elevation);
int getShadowElevation();
void setShadowAlpha(float shadowAlpha);
float getShadowAlpha();
void setShadowColor(int shadowColor);
int getShadowColor();
void setRadius(int radius);
void setRadius(int radius, int hideRadiusSide);
int getRadius();
void setOutlineInset(int left, int top, int right, int bottom);
void setShowBorderonlyBeforeL(boolean showBorderOnlyBeforeL);
void setHideRadiusSide(@HideRadiusSide int hideRadiusSide);
int getHideRadiusSide();
void setRadiusAndShadow(int radius, int shadowElevation, float shadowAlpha);
void setRadiusAndShadow(int radius, @HideRadiusSide int hideRadiusSide, int shadowElevation, float shadowAlpha);
void setRadiusAndShadow(int radius, @HideRadiusSide int hideRadiusSide, int shadowElevation, int shadowColor, float shadowAlpha);
void setBorderColor(@ColorInt int borderColor);
void setBorderWidth(int borderWidth);
void updateTopDivider(int topInsetLeft, int topInsetRight, int topDividerHeight, int topDividerColor);
void updateBottomDivider(int bottomInsetLeft, int bottomInsetRight, int bottomDividerHeight, int bottomDividerColor);
void updateLeftDivider(int leftInsetTop, int leftInsetBottom, int leftDividerWidth, int leftDividerColor);
void updateRightDivider(int rightInsetTop, int rightInsetBottom, int rightDividerWidth, int rightDividerColor);
void onlyShowTopDivider(int topInsetLeft, int topInsetRight, int topDividerHeight, int topDividerColor);
void onlyShowBottomDivider(int bottomInsetLeft, int bottomInsetRight, int bottomDividerHeight, int bottomDividerColor);
void onlyShowLeftDivider(int leftInsetTop, int leftInsetBottom, int leftDividerWidth, int leftDividerColor);
void onlyShowRightDivider(int rightInsetTop, int rightInsetBottom, int rightDividerWidth, int rightDividerColor);
void setTopDividerAlpha(int dividerAlpha);
void setBottomDividerAlpha(int dividerAlpha);
void setLeftDividerAlpha(int dividerAlpha);
void setRightDividerAlpha(int dividerAlpha);
void setOuterNormalColor(int color);
void updateLeftSeparatorColor(int color);
void updateRightSeparatorColor(int color);
void updateTopSeparatorColor(int color);
void updateBottomSeparatorColor(int color);
boolean hasTopSeparator();
boolean hasRightSeparator();
boolean hasLeftSeparator();
boolean hasBottomSeparator();
boolean hasBorder();
}
package com.example.theachermanagersystem.popup;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.PopupWindow;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import java.lang.ref.WeakReference;
public abstract class XbasePopup {
public static final float DIM_AMOUNT_NOT_EXIST = -1f;
public static final int NOT_SET = -1;
protected final PopupWindow mWindow;
protected WindowManager mWindowManager;
protected Context mContext;
protected WeakReference mAttachedViewRf;
private float mDimAmount = DIM_AMOUNT_NOT_EXIST;
private int mDimAmountAttr = 0;
private PopupWindow.onDismissListener mDismissListener;
private View.onAttachStateChangeListener monAttachStateChangeListener = new View.onAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
}
@Override
public void onViewDetachedFromWindow(View v) {
dismiss();
}
};
private View.onTouchListener mOutsideTouchDismissListener = new View.onTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mWindow.dismiss();
return true;
}
return false;
}
};
public XbasePopup(Context context) {
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mWindow = new PopupWindow(context);
mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mWindow.setFocusable(true);
mWindow.setTouchable(true);
mWindow.setonDismissListener(new PopupWindow.onDismissListener() {
@Override
public void onDismiss() {
removeOldAttachStateChangeListener();
mAttachedViewRf = null;
XbasePopup.this.onDismiss();
if (mDismissListener != null) {
mDismissListener.onDismiss();
}
}
});
dismissIfOutsideTouch(true);
}
protected void onSkinChange(int oldSkin, int newSkin){
}
public T dimAmount(float dimAmount) {
mDimAmount = dimAmount;
return (T) this;
}
public T dimAmountAttr(int dimAmountAttr) {
mDimAmountAttr = dimAmountAttr;
return (T) this;
}
public T setTouchable(boolean touchable){
mWindow.setTouchable(true);
return (T) this;
}
public T setFocusable(boolean focusable){
mWindow.setFocusable(focusable);
return (T) this;
}
public T dismissIfOutsideTouch(boolean dismissIfOutsideTouch) {
mWindow.setOutsideTouchable(dismissIfOutsideTouch);
if (dismissIfOutsideTouch) {
mWindow.setTouchInterceptor(mOutsideTouchDismissListener);
} else {
mWindow.setTouchInterceptor(null);
}
return (T) this;
}
public T onDismiss(PopupWindow.onDismissListener listener) {
mDismissListener = listener;
return (T) this;
}
private void removeOldAttachStateChangeListener() {
if (mAttachedViewRf != null) {
View oldAttachedView = mAttachedViewRf.get();
if (oldAttachedView != null) {
oldAttachedView.removeonAttachStateChangeListener(mOnAttachStateChangeListener);
}
}
}
public View getDecorView() {
View decorView = null;
try {
if (mWindow.getBackground() == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
decorView = (View) mWindow.getContentView().getParent();
} else {
decorView = mWindow.getContentView();
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
decorView = (View) mWindow.getContentView().getParent().getParent();
} else {
decorView = (View) mWindow.getContentView().getParent();
}
}
} catch (Exception ignore) {
}
return decorView;
}
protected void showAtLocation(@NonNull View parent, int x, int y) {
if (!ViewCompat.isAttachedToWindow(parent)) {
return;
}
removeOldAttachStateChangeListener();
parent.addonAttachStateChangeListener(mOnAttachStateChangeListener);
mAttachedViewRf = new WeakReference<>(parent);
mWindow.showAtLocation(parent, Gravity.NO_GRAVITY, x, y);
if (mDimAmount != DIM_AMOUNT_NOT_EXIST) {
updateDimAmount(mDimAmount);
}
}
private void updateDimAmount(float dimAmount) {
View decorView = getDecorView();
if (decorView != null) {
WindowManager.LayoutParams p = (WindowManager.LayoutParams) decorView.getLayoutParams();
p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = dimAmount;
modifyWindowLayoutParams(p);
mWindowManager.updateViewLayout(decorView, p);
}
}
protected void modifyWindowLayoutParams(WindowManager.LayoutParams lp) {
}
protected void onDismiss() {
}
public final void dismiss() {
mWindow.dismiss();
}
}
package com.example.theachermanagersystem.popup;
import android.content.Context;
import android.graphics.Canvas;
import androidx.annotation.ColorInt;
import android.util.AttributeSet;
import android.widget.frameLayout;
public class XframeLayout extends frameLayout implements ILayout {
private XLayoutHelper mLayoutHelper;
public XframeLayout(Context context) {
super(context);
init(context, null, 0);
}
public XframeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public XframeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
mLayoutHelper = new XLayoutHelper(context, attrs, defStyleAttr, this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
widthMeasureSpec = mLayoutHelper.getMeasuredWidthSpec(widthMeasureSpec);
heightMeasureSpec = mLayoutHelper.getMeasuredHeightSpec(heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int minW = mLayoutHelper.handleMiniWidth(widthMeasureSpec, getMeasuredWidth());
int minH = mLayoutHelper.handleMiniHeight(heightMeasureSpec, getMeasuredHeight());
if (widthMeasureSpec != minW || heightMeasureSpec != minH) {
super.onMeasure(minW, minH);
}
}
@Override
public void updateTopDivider(int topInsetLeft, int topInsetRight, int topDividerHeight, int topDividerColor) {
mLayoutHelper.updateTopDivider(topInsetLeft, topInsetRight, topDividerHeight, topDividerColor);
invalidate();
}
@Override
public void updateBottomDivider(int bottomInsetLeft, int bottomInsetRight, int bottomDividerHeight, int bottomDividerColor) {
mLayoutHelper.updateBottomDivider(bottomInsetLeft, bottomInsetRight, bottomDividerHeight, bottomDividerColor);
invalidate();
}
@Override
public void updateLeftDivider(int leftInsetTop, int leftInsetBottom, int leftDividerWidth, int leftDividerColor) {
mLayoutHelper.updateLeftDivider(leftInsetTop, leftInsetBottom, leftDividerWidth, leftDividerColor);
invalidate();
}
@Override
public void updateRightDivider(int rightInsetTop, int rightInsetBottom, int rightDividerWidth, int rightDividerColor) {
mLayoutHelper.updateRightDivider(rightInsetTop, rightInsetBottom, rightDividerWidth, rightDividerColor);
invalidate();
}
@Override
public void onlyShowTopDivider(int topInsetLeft, int topInsetRight,
int topDividerHeight, int topDividerColor) {
mLayoutHelper.onlyShowTopDivider(topInsetLeft, topInsetRight, topDividerHeight, topDividerColor);
invalidate();
}
@Override
public void onlyShowBottomDivider(int bottomInsetLeft, int bottomInsetRight,
int bottomDividerHeight, int bottomDividerColor) {
mLayoutHelper.onlyShowBottomDivider(bottomInsetLeft, bottomInsetRight, bottomDividerHeight, bottomDividerColor);
invalidate();
}
@Override
public void onlyShowLeftDivider(int leftInsetTop, int leftInsetBottom, int leftDividerWidth, int leftDividerColor) {
mLayoutHelper.onlyShowLeftDivider(leftInsetTop, leftInsetBottom, leftDividerWidth, leftDividerColor);
invalidate();
}
@Override
public void onlyShowRightDivider(int rightInsetTop, int rightInsetBottom, int rightDividerWidth, int rightDividerColor) {
mLayoutHelper.onlyShowRightDivider(rightInsetTop, rightInsetBottom, rightDividerWidth, rightDividerColor);
invalidate();
}
@Override
public void setTopDividerAlpha(int dividerAlpha) {
mLayoutHelper.setTopDividerAlpha(dividerAlpha);
invalidate();
}
@Override
public void setBottomDividerAlpha(int dividerAlpha) {
mLayoutHelper.setBottomDividerAlpha(dividerAlpha);
invalidate();
}
@Override
public void setLeftDividerAlpha(int dividerAlpha) {
mLayoutHelper.setLeftDividerAlpha(dividerAlpha);
invalidate();
}
@Override
public void setRightDividerAlpha(int dividerAlpha) {
mLayoutHelper.setRightDividerAlpha(dividerAlpha);
invalidate();
}
@Override
public void setRadiusAndShadow(int radius, int shadowElevation, final float shadowAlpha) {
mLayoutHelper.setRadiusAndShadow(radius, shadowElevation, shadowAlpha);
}
@Override
public void setRadiusAndShadow(int radius, @XLayoutHelper.HideRadiusSide int hideRadiusSide, int shadowElevation, final float shadowAlpha) {
mLayoutHelper.setRadiusAndShadow(radius, hideRadiusSide, shadowElevation, shadowAlpha);
}
@Override
public void setRadiusAndShadow(int radius, int hideRadiusSide, int shadowElevation, int shadowColor, float shadowAlpha) {
mLayoutHelper.setRadiusAndShadow(radius, hideRadiusSide, shadowElevation, shadowColor, shadowAlpha);
}
@Override
public void setRadius(int radius) {
mLayoutHelper.setRadius(radius);
}
@Override
public void setRadius(int radius, @XLayoutHelper.HideRadiusSide int hideRadiusSide) {
mLayoutHelper.setRadius(radius, hideRadiusSide);
}
@Override
public int getRadius() {
return mLayoutHelper.getRadius();
}
@Override
public void setOutlineInset(int left, int top, int right, int bottom) {
mLayoutHelper.setOutlineInset(left, top, right, bottom);
}
@Override
public void setHideRadiusSide(int hideRadiusSide) {
mLayoutHelper.setHideRadiusSide(hideRadiusSide);
}
@Override
public int getHideRadiusSide() {
return mLayoutHelper.getHideRadiusSide();
}
@Override
public void setBorderColor(@ColorInt int borderColor) {
mLayoutHelper.setBorderColor(borderColor);
invalidate();
}
@Override
public void setBorderWidth(int borderWidth) {
mLayoutHelper.setBorderWidth(borderWidth);
invalidate();
}
@Override
public void setShowBorderonlyBeforeL(boolean showBorderOnlyBeforeL) {
mLayoutHelper.setShowBorderonlyBeforeL(showBorderOnlyBeforeL);
invalidate();
}
@Override
public boolean setWidthLimit(int widthLimit) {
if (mLayoutHelper.setWidthLimit(widthLimit)) {
requestLayout();
invalidate();
}
return true;
}
@Override
public boolean setHeightLimit(int heightLimit) {
if (mLayoutHelper.setHeightLimit(heightLimit)) {
requestLayout();
invalidate();
}
return true;
}
@Override
public void setUseThemeGeneralShadowElevation() {
mLayoutHelper.setUseThemeGeneralShadowElevation();
}
@Override
public void setOutlineExcludePadding(boolean outlineExcludePadding) {
mLayoutHelper.setOutlineExcludePadding(outlineExcludePadding);
}
@Override
public void setShadowElevation(int elevation) {
mLayoutHelper.setShadowElevation(elevation);
}
@Override
public int getShadowElevation() {
return mLayoutHelper.getShadowElevation();
}
@Override
public void setShadowAlpha(float shadowAlpha) {
mLayoutHelper.setShadowAlpha(shadowAlpha);
}
@Override
public float getShadowAlpha() {
return mLayoutHelper.getShadowAlpha();
}
@Override
public void setShadowColor(int shadowColor) {
mLayoutHelper.setShadowColor(shadowColor);
}
@Override
public int getShadowColor() {
return mLayoutHelper.getShadowColor();
}
@Override
public void setOuterNormalColor(int color) {
mLayoutHelper.setOuterNormalColor(color);
}
@Override
public void updateBottomSeparatorColor(int color) {
mLayoutHelper.updateBottomSeparatorColor(color);
}
@Override
public void updateLeftSeparatorColor(int color) {
mLayoutHelper.updateLeftSeparatorColor(color);
}
@Override
public void updateRightSeparatorColor(int color) {
mLayoutHelper.updateRightSeparatorColor(color);
}
@Override
public void updateTopSeparatorColor(int color) {
mLayoutHelper.updateTopSeparatorColor(color);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
mLayoutHelper.drawDividers(canvas, getWidth(), getHeight());
mLayoutHelper.dispatchRoundBorderDraw(canvas);
}
@Override
public boolean hasBorder() {
return mLayoutHelper.hasBorder();
}
@Override
public boolean hasLeftSeparator() {
return mLayoutHelper.hasLeftSeparator();
}
@Override
public boolean hasTopSeparator() {
return mLayoutHelper.hasTopSeparator();
}
@Override
public boolean hasRightSeparator() {
return mLayoutHelper.hasRightSeparator();
}
@Override
public boolean hasBottomSeparator() {
return mLayoutHelper.hasBottomSeparator();
}
}
package com.example.theachermanagersystem.popup;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
import java.lang.ref.WeakReference;
import androidx.annotation.ColorInt;
import androidx.core.content.ContextCompat;
import com.example.theachermanagersystem.R;
public class XLayoutHelper implements ILayout {
public static final int RADIUS_OF_HALF_VIEW_HEIGHT = -1;
public static final int RADIUS_OF_HALF_VIEW_WIDTH = -2;
private Context mContext;
// size
private int mWidthLimit = 0;
private int mHeightLimit = 0;
private int mWidthMini = 0;
private int mHeightMini = 0;
// divider
private int mTopDividerHeight = 0;
private int mTopDividerInsetLeft = 0;
private int mTopDividerInsetRight = 0;
private int mTopDividerColor;
private int mTopDividerAlpha = 255;
private int mBottomDividerHeight = 0;
private int mBottomDividerInsetLeft = 0;
private int mBottomDividerInsetRight = 0;
private int mBottomDividerColor;
private int mBottomDividerAlpha = 255;
private int mLeftDividerWidth = 0;
private int mLeftDividerInsetTop = 0;
private int mLeftDividerInsetBottom = 0;
private int mLeftDividerColor;
private int mLeftDividerAlpha = 255;
private int mRightDividerWidth = 0;
private int mRightDividerInsetTop = 0;
private int mRightDividerInsetBottom = 0;
private int mRightDividerColor;
private int mRightDividerAlpha = 255;
private Paint mDividerPaint;
// round
private Paint mClipPaint;
private PorterDuffXfermode mMode;
private int mRadius = 20;
private @ILayout.HideRadiusSide int mHideRadiusSide = HIDE_RADIUS_SIDE_NONE;
private float[] mRadiusArray;
private boolean mShouldUseRadiusArray;
private RectF mBorderRect;
private int mBorderColor = Color.RED;
private int mBorderWidth = 1;
private int mOuterNormalColor = 0;
private WeakReference mOwner;
private boolean mIsOutlineExcludePadding = false;
private Path mPath = new Path();
// shadow
private boolean mIsShowBorderonlyBeforeL = true;
private int mShadowElevation = 0;
private float mShadowAlpha;
private int mShadowColor = Color.BLACK;
// outline inset
private int mOutlineInsetLeft = 0;
private int mOutlineInsetRight = 0;
private int mOutlineInsetTop = 0;
private int mOutlineInsetBottom = 0;
public XLayoutHelper(Context context, AttributeSet attrs, int defAttr, View owner) {
this(context, attrs, defAttr, 0, owner);
}
public XLayoutHelper(Context context, AttributeSet attrs, int defAttr, int defStyleRes, View owner) {
mContext = context;
mOwner = new WeakReference<>(owner);
mBottomDividerColor = mTopDividerColor =
ContextCompat.getColor(context, R.color.qmui_config_color_separator);
mMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
mClipPaint = new Paint();
mClipPaint.setAntiAlias(true);
mShadowAlpha = 0.25f;
mBorderRect = new RectF();
int radius = 0, shadow = 0;
boolean useThemeGeneralShadowElevation = false;
if (null != attrs || defAttr != 0 || defStyleRes != 0) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.QMUILayout, defAttr, defStyleRes);
int count = ta.getIndexCount();
for (int i = 0; i < count; ++i) {
int index = ta.getIndex(i);
if (index == R.styleable.QMUILayout_android_maxWidth) {
mWidthLimit = ta.getDimensionPixelSize(index, mWidthLimit);
} else if (index == R.styleable.QMUILayout_android_maxHeight) {
mHeightLimit = ta.getDimensionPixelSize(index, mHeightLimit);
} else if (index == R.styleable.QMUILayout_android_minWidth) {
mWidthMini = ta.getDimensionPixelSize(index, mWidthMini);
} else if (index == R.styleable.QMUILayout_android_minHeight) {
mHeightMini = ta.getDimensionPixelSize(index, mHeightMini);
} else if (index == R.styleable.QMUILayout_qmui_topDividerColor) {
mTopDividerColor = ta.getColor(index, mTopDividerColor);
} else if (index == R.styleable.QMUILayout_qmui_topDividerHeight) {
mTopDividerHeight = ta.getDimensionPixelSize(index, mTopDividerHeight);
} else if (index == R.styleable.QMUILayout_qmui_topDividerInsetLeft) {
mTopDividerInsetLeft = ta.getDimensionPixelSize(index, mTopDividerInsetLeft);
} else if (index == R.styleable.QMUILayout_qmui_topDividerInsetRight) {
mTopDividerInsetRight = ta.getDimensionPixelSize(index, mTopDividerInsetRight);
} else if (index == R.styleable.QMUILayout_qmui_bottomDividerColor) {
mBottomDividerColor = ta.getColor(index, mBottomDividerColor);
} else if (index == R.styleable.QMUILayout_qmui_bottomDividerHeight) {
mBottomDividerHeight = ta.getDimensionPixelSize(index, mBottomDividerHeight);
} else if (index == R.styleable.QMUILayout_qmui_bottomDividerInsetLeft) {
mBottomDividerInsetLeft = ta.getDimensionPixelSize(index, mBottomDividerInsetLeft);
} else if (index == R.styleable.QMUILayout_qmui_bottomDividerInsetRight) {
mBottomDividerInsetRight = ta.getDimensionPixelSize(index, mBottomDividerInsetRight);
} else if (index == R.styleable.QMUILayout_qmui_leftDividerColor) {
mLeftDividerColor = ta.getColor(index, mLeftDividerColor);
} else if (index == R.styleable.QMUILayout_qmui_leftDividerWidth) {
mLeftDividerWidth = ta.getDimensionPixelSize(index, mLeftDividerWidth);
} else if (index == R.styleable.QMUILayout_qmui_leftDividerInsetTop) {
mLeftDividerInsetTop = ta.getDimensionPixelSize(index, mLeftDividerInsetTop);
} else if (index == R.styleable.QMUILayout_qmui_leftDividerInsetBottom) {
mLeftDividerInsetBottom = ta.getDimensionPixelSize(index, mLeftDividerInsetBottom);
} else if (index == R.styleable.QMUILayout_qmui_rightDividerColor) {
mRightDividerColor = ta.getColor(index, mRightDividerColor);
} else if (index == R.styleable.QMUILayout_qmui_rightDividerWidth) {
mRightDividerWidth = ta.getDimensionPixelSize(index, mRightDividerWidth);
} else if (index == R.styleable.QMUILayout_qmui_rightDividerInsetTop) {
mRightDividerInsetTop = ta.getDimensionPixelSize(index, mRightDividerInsetTop);
} else if (index == R.styleable.QMUILayout_qmui_rightDividerInsetBottom) {
mRightDividerInsetBottom = ta.getDimensionPixelSize(index, mRightDividerInsetBottom);
} else if (index == R.styleable.QMUILayout_qmui_outerNormalColor) {
mOuterNormalColor = ta.getColor(index, mOuterNormalColor);
} else if (index == R.styleable.QMUILayout_qmui_hideRadiusSide) {
mHideRadiusSide = ta.getInt(index, mHideRadiusSide);
} else if (index == R.styleable.QMUILayout_qmui_showBorderOnlyBeforeL) {
mIsShowBorderonlyBeforeL = ta.getBoolean(index, mIsShowBorderOnlyBeforeL);
} else if (index == R.styleable.QMUILayout_qmui_shadowElevation) {
shadow = ta.getDimensionPixelSize(index, shadow);
} else if (index == R.styleable.QMUILayout_qmui_shadowAlpha) {
mShadowAlpha = ta.getFloat(index, mShadowAlpha);
} else if (index == R.styleable.QMUILayout_qmui_useThemeGeneralShadowElevation) {
useThemeGeneralShadowElevation = ta.getBoolean(index, false);
} else if (index == R.styleable.QMUILayout_qmui_outlineInsetLeft) {
mOutlineInsetLeft = ta.getDimensionPixelSize(index, 0);
} else if (index == R.styleable.QMUILayout_qmui_outlineInsetRight) {
mOutlineInsetRight = ta.getDimensionPixelSize(index, 0);
} else if (index == R.styleable.QMUILayout_qmui_outlineInsetTop) {
mOutlineInsetTop = ta.getDimensionPixelSize(index, 0);
} else if (index == R.styleable.QMUILayout_qmui_outlineInsetBottom) {
mOutlineInsetBottom = ta.getDimensionPixelSize(index, 0);
} else if (index == R.styleable.QMUILayout_qmui_outlineExcludePadding) {
mIsOutlineExcludePadding = ta.getBoolean(index, false);
}
}
ta.recycle();
}
if (shadow == 0 && useThemeGeneralShadowElevation) {
shadow = 10;
}
setRadiusAndShadow(radius, mHideRadiusSide, shadow, mShadowAlpha);
}
@Override
public void setUseThemeGeneralShadowElevation() {
mShadowElevation = 20;
setRadiusAndShadow(mRadius, mHideRadiusSide, mShadowElevation, mShadowAlpha);
}
@Override
public void setOutlineExcludePadding(boolean outlineExcludePadding) {
if (useFeature()) {
View owner = mOwner.get();
if (owner == null) {
return;
}
mIsOutlineExcludePadding = outlineExcludePadding;
owner.invalidateOutline();
}
}
@Override
public boolean setWidthLimit(int widthLimit) {
if (mWidthLimit != widthLimit) {
mWidthLimit = widthLimit;
return true;
}
return false;
}
@Override
public boolean setHeightLimit(int heightLimit) {
if (mHeightLimit != heightLimit) {
mHeightLimit = heightLimit;
return true;
}
return false;
}
@Override
public void updateLeftSeparatorColor(int color) {
if (mLeftDividerColor != color) {
mLeftDividerColor = color;
invalidate();
}
}
@Override
public void updateBottomSeparatorColor(int color) {
if (mBottomDividerColor != color) {
mBottomDividerColor = color;
invalidate();
}
}
@Override
public void updateTopSeparatorColor(int color) {
if (mTopDividerColor != color) {
mTopDividerColor = color;
invalidate();
}
}
@Override
public void updateRightSeparatorColor(int color) {
if (mRightDividerColor != color) {
mRightDividerColor = color;
invalidate();
}
}
@Override
public int getShadowElevation() {
return mShadowElevation;
}
@Override
public float getShadowAlpha() {
return mShadowAlpha;
}
@Override
public int getShadowColor() {
return mShadowColor;
}
@Override
public void setOutlineInset(int left, int top, int right, int bottom) {
if (useFeature()) {
View owner = mOwner.get();
if (owner == null) {
return;
}
mOutlineInsetLeft = left;
mOutlineInsetRight = right;
mOutlineInsetTop = top;
mOutlineInsetBottom = bottom;
owner.invalidateOutline();
}
}
@Override
public void setShowBorderonlyBeforeL(boolean showBorderOnlyBeforeL) {
mIsShowBorderonlyBeforeL = showBorderOnlyBeforeL;
invalidate();
}
@Override
public void setShadowElevation(int elevation) {
if (mShadowElevation == elevation) {
return;
}
mShadowElevation = elevation;
invalidateOutline();
}
@Override
public void setShadowAlpha(float shadowAlpha) {
if (mShadowAlpha == shadowAlpha) {
return;
}
mShadowAlpha = shadowAlpha;
invalidateOutline();
}
@Override
public void setShadowColor(int shadowColor) {
if (mShadowColor == shadowColor) {
return;
}
mShadowColor = shadowColor;
setShadowColorInner(mShadowColor);
}
private void setShadowColorInner(int shadowColor) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
View owner = mOwner.get();
if (owner == null) {
return;
}
owner.setOutlineAmbientShadowColor(shadowColor);
owner.setOutlineSpotShadowColor(shadowColor);
}
}
private void invalidateOutline() {
if (useFeature()) {
View owner = mOwner.get();
if (owner == null) {
return;
}
if (mShadowElevation == 0) {
owner.setElevation(0);
} else {
owner.setElevation(mShadowElevation);
}
owner.invalidateOutline();
}
}
private void invalidate() {
View owner = mOwner.get();
if (owner == null) {
return;
}
owner.invalidate();
}
@Override
public void setHideRadiusSide(@HideRadiusSide int hideRadiusSide) {
if (mHideRadiusSide == hideRadiusSide) {
return;
}
setRadiusAndShadow(mRadius, hideRadiusSide, mShadowElevation, mShadowAlpha);
}
@Override
public int getHideRadiusSide() {
return mHideRadiusSide;
}
@Override
public void setRadius(int radius) {
if (mRadius != radius) {
setRadiusAndShadow(radius, mShadowElevation, mShadowAlpha);
}
}
@Override
public void setRadius(int radius, @ILayout.HideRadiusSide int hideRadiusSide) {
if (mRadius == radius && hideRadiusSide == mHideRadiusSide) {
return;
}
setRadiusAndShadow(radius, hideRadiusSide, mShadowElevation, mShadowAlpha);
}
@Override
public int getRadius() {
return mRadius;
}
@Override
public void setRadiusAndShadow(int radius, int shadowElevation, float shadowAlpha) {
setRadiusAndShadow(radius, mHideRadiusSide, shadowElevation, shadowAlpha);
}
@Override
public void setRadiusAndShadow(int radius, @ILayout.HideRadiusSide int hideRadiusSide, int shadowElevation, float shadowAlpha) {
setRadiusAndShadow(radius, hideRadiusSide, shadowElevation, mShadowColor, shadowAlpha);
}
@Override
public void setRadiusAndShadow(int radius, int hideRadiusSide, int shadowElevation, int shadowColor, float shadowAlpha) {
final View owner = mOwner.get();
if (owner == null) {
return;
}
mRadius = radius;
mHideRadiusSide = hideRadiusSide;
mShouldUseRadiusArray = isRadiusWithSideHidden();
mShadowElevation = shadowElevation;
mShadowAlpha = shadowAlpha;
mShadowColor = shadowColor;
if (useFeature()) {
if (mShadowElevation == 0 || mShouldUseRadiusArray) {
owner.setElevation(0);
} else {
owner.setElevation(mShadowElevation);
}
setShadowColorInner(mShadowColor);
owner.setOutlineProvider(new ViewOutlineProvider() {
@Override
@TargetApi(21)
public void getOutline(View view, Outline outline) {
int w = view.getWidth(), h = view.getHeight();
if (w == 0 || h == 0) {
return;
}
float radius = getRealRadius();
int min = Math.min(w, h);
if (radius * 2 > min) {
// 解决 onePlus 3T 8.0 上显示变形
radius = min / 2F;
}
if (mShouldUseRadiusArray) {
int left = 0, top = 0, right = w, bottom = h;
if (mHideRadiusSide == HIDE_RADIUS_SIDE_LEFT) {
left -= radius;
} else if (mHideRadiusSide == HIDE_RADIUS_SIDE_TOP) {
top -= radius;
} else if (mHideRadiusSide == HIDE_RADIUS_SIDE_RIGHT) {
right += radius;
} else if (mHideRadiusSide == HIDE_RADIUS_SIDE_BOTTOM) {
bottom += radius;
}
outline.setRoundRect(left, top,
right, bottom, radius);
return;
}
int top = mOutlineInsetTop, bottom = Math.max(top + 1, h - mOutlineInsetBottom),
left = mOutlineInsetLeft, right = w - mOutlineInsetRight;
if (mIsOutlineExcludePadding) {
left += view.getPaddingLeft();
top += view.getPaddingTop();
right = Math.max(left + 1, right - view.getPaddingRight());
bottom = Math.max(top + 1, bottom - view.getPaddingBottom());
}
float shadowAlpha = mShadowAlpha;
if (mShadowElevation == 0) {
// outline.setAlpha will work even if shadowElevation == 0
shadowAlpha = 1f;
}
outline.setAlpha(shadowAlpha);
if (radius <= 0) {
outline.setRect(left, top,
right, bottom);
} else {
outline.setRoundRect(left, top,
right, bottom, radius);
}
}
});
owner.setClipToOutline(mRadius == RADIUS_OF_HALF_VIEW_WIDTH || mRadius == RADIUS_OF_HALF_VIEW_HEIGHT || mRadius > 0);
}
owner.invalidate();
}
public boolean isRadiusWithSideHidden() {
return (mRadius == RADIUS_OF_HALF_VIEW_HEIGHT ||
mRadius == RADIUS_OF_HALF_VIEW_WIDTH ||
mRadius > 0) && mHideRadiusSide != HIDE_RADIUS_SIDE_NONE;
}
@Override
public void updateTopDivider(int topInsetLeft, int topInsetRight, int topDividerHeight, int topDividerColor) {
mTopDividerInsetLeft = topInsetLeft;
mTopDividerInsetRight = topInsetRight;
mTopDividerHeight = topDividerHeight;
mTopDividerColor = topDividerColor;
}
@Override
public void updateBottomDivider(int bottomInsetLeft, int bottomInsetRight, int bottomDividerHeight, int bottomDividerColor) {
mBottomDividerInsetLeft = bottomInsetLeft;
mBottomDividerInsetRight = bottomInsetRight;
mBottomDividerColor = bottomDividerColor;
mBottomDividerHeight = bottomDividerHeight;
}
@Override
public void updateLeftDivider(int leftInsetTop, int leftInsetBottom, int leftDividerWidth, int leftDividerColor) {
mLeftDividerInsetTop = leftInsetTop;
mLeftDividerInsetBottom = leftInsetBottom;
mLeftDividerWidth = leftDividerWidth;
mLeftDividerColor = leftDividerColor;
}
@Override
public void updateRightDivider(int rightInsetTop, int rightInsetBottom, int rightDividerWidth, int rightDividerColor) {
mRightDividerInsetTop = rightInsetTop;
mRightDividerInsetBottom = rightInsetBottom;
mRightDividerWidth = rightDividerWidth;
mRightDividerColor = rightDividerColor;
}
@Override
public void onlyShowTopDivider(int topInsetLeft, int topInsetRight,
int topDividerHeight, int topDividerColor) {
updateTopDivider(topInsetLeft, topInsetRight, topDividerHeight, topDividerColor);
mLeftDividerWidth = 0;
mRightDividerWidth = 0;
mBottomDividerHeight = 0;
}
@Override
public void onlyShowBottomDivider(int bottomInsetLeft, int bottomInsetRight,
int bottomDividerHeight, int bottomDividerColor) {
updateBottomDivider(bottomInsetLeft, bottomInsetRight, bottomDividerHeight, bottomDividerColor);
mLeftDividerWidth = 0;
mRightDividerWidth = 0;
mTopDividerHeight = 0;
}
@Override
public void onlyShowLeftDivider(int leftInsetTop, int leftInsetBottom, int leftDividerWidth, int leftDividerColor) {
updateLeftDivider(leftInsetTop, leftInsetBottom, leftDividerWidth, leftDividerColor);
mRightDividerWidth = 0;
mTopDividerHeight = 0;
mBottomDividerHeight = 0;
}
@Override
public void onlyShowRightDivider(int rightInsetTop, int rightInsetBottom, int rightDividerWidth, int rightDividerColor) {
updateRightDivider(rightInsetTop, rightInsetBottom, rightDividerWidth, rightDividerColor);
mLeftDividerWidth = 0;
mTopDividerHeight = 0;
mBottomDividerHeight = 0;
}
@Override
public void setTopDividerAlpha(int dividerAlpha) {
mTopDividerAlpha = dividerAlpha;
}
@Override
public void setBottomDividerAlpha(int dividerAlpha) {
mBottomDividerAlpha = dividerAlpha;
}
@Override
public void setLeftDividerAlpha(int dividerAlpha) {
mLeftDividerAlpha = dividerAlpha;
}
@Override
public void setRightDividerAlpha(int dividerAlpha) {
mRightDividerAlpha = dividerAlpha;
}
public int handleMiniWidth(int widthMeasureSpec, int measuredWidth) {
if (View.MeasureSpec.getMode(widthMeasureSpec) != View.MeasureSpec.EXACTLY
&& measuredWidth < mWidthMini) {
return View.MeasureSpec.makeMeasureSpec(mWidthMini, View.MeasureSpec.EXACTLY);
}
return widthMeasureSpec;
}
public int handleMiniHeight(int heightMeasureSpec, int measuredHeight) {
if (View.MeasureSpec.getMode(heightMeasureSpec) != View.MeasureSpec.EXACTLY
&& measuredHeight < mHeightMini) {
return View.MeasureSpec.makeMeasureSpec(mHeightMini, View.MeasureSpec.EXACTLY);
}
return heightMeasureSpec;
}
public int getMeasuredWidthSpec(int widthMeasureSpec) {
if (mWidthLimit > 0) {
int size = View.MeasureSpec.getSize(widthMeasureSpec);
if (size > mWidthLimit) {
int mode = View.MeasureSpec.getMode(widthMeasureSpec);
if (mode == View.MeasureSpec.AT_MOST) {
widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(mWidthLimit, View.MeasureSpec.AT_MOST);
} else {
widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(mWidthLimit, View.MeasureSpec.EXACTLY);
}
}
}
return widthMeasureSpec;
}
public int getMeasuredHeightSpec(int heightMeasureSpec) {
if (mHeightLimit > 0) {
int size = View.MeasureSpec.getSize(heightMeasureSpec);
if (size > mHeightLimit) {
int mode = View.MeasureSpec.getMode(heightMeasureSpec);
if (mode == View.MeasureSpec.AT_MOST) {
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(mWidthLimit, View.MeasureSpec.AT_MOST);
} else {
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(mWidthLimit, View.MeasureSpec.EXACTLY);
}
}
}
return heightMeasureSpec;
}
@Override
public void setBorderColor(@ColorInt int borderColor) {
mBorderColor = borderColor;
}
@Override
public void setBorderWidth(int borderWidth) {
mBorderWidth = borderWidth;
}
@Override
public void setOuterNormalColor(int color) {
mOuterNormalColor = color;
View owner = mOwner.get();
if (owner != null) {
owner.invalidate();
}
}
@Override
public boolean hasTopSeparator() {
return mTopDividerHeight > 0;
}
@Override
public boolean hasRightSeparator() {
return mRightDividerWidth > 0;
}
@Override
public boolean hasBottomSeparator() {
return mBottomDividerHeight > 0;
}
@Override
public boolean hasLeftSeparator() {
return mLeftDividerWidth > 0;
}
@Override
public boolean hasBorder() {
return mBorderWidth > 0;
}
public void drawDividers(Canvas canvas, int w, int h) {
View owner = mOwner.get();
if(owner == null){
return;
}
if (mDividerPaint == null &&
(mTopDividerHeight > 0 || mBottomDividerHeight > 0 || mLeftDividerWidth > 0 || mRightDividerWidth > 0)) {
mDividerPaint = new Paint();
}
canvas.save();
canvas.translate(owner.getScrollX(), owner.getScrollY());
if (mTopDividerHeight > 0) {
mDividerPaint.setStrokeWidth(mTopDividerHeight);
mDividerPaint.setColor(mTopDividerColor);
if (mTopDividerAlpha < 255) {
mDividerPaint.setAlpha(mTopDividerAlpha);
}
float y = mTopDividerHeight / 2f;
canvas.drawLine(mTopDividerInsetLeft, y, w - mTopDividerInsetRight, y, mDividerPaint);
}
if (mBottomDividerHeight > 0) {
mDividerPaint.setStrokeWidth(mBottomDividerHeight);
mDividerPaint.setColor(mBottomDividerColor);
if (mBottomDividerAlpha < 255) {
mDividerPaint.setAlpha(mBottomDividerAlpha);
}
float y = (float) Math.floor(h - mBottomDividerHeight / 2f);
canvas.drawLine(mBottomDividerInsetLeft, y, w - mBottomDividerInsetRight, y, mDividerPaint);
}
if (mLeftDividerWidth > 0) {
mDividerPaint.setStrokeWidth(mLeftDividerWidth);
mDividerPaint.setColor(mLeftDividerColor);
if (mLeftDividerAlpha < 255) {
mDividerPaint.setAlpha(mLeftDividerAlpha);
}
float x = mLeftDividerWidth / 2f;
canvas.drawLine(x, mLeftDividerInsetTop, x, h - mLeftDividerInsetBottom, mDividerPaint);
}
if (mRightDividerWidth > 0) {
mDividerPaint.setStrokeWidth(mRightDividerWidth);
mDividerPaint.setColor(mRightDividerColor);
if (mRightDividerAlpha < 255) {
mDividerPaint.setAlpha(mRightDividerAlpha);
}
float x = (float) Math.floor(w - mRightDividerWidth / 2f);
canvas.drawLine(x, mRightDividerInsetTop, x, h - mRightDividerInsetBottom, mDividerPaint);
}
canvas.restore();
}
private int getRealRadius(){
View owner = mOwner.get();
if (owner == null) {
return mRadius;
}
int radius;
if(mRadius == RADIUS_OF_HALF_VIEW_HEIGHT){
radius = owner.getHeight() /2;
}else if(mRadius == RADIUS_OF_HALF_VIEW_WIDTH){
radius = owner.getWidth() / 2;
}else{
radius = mRadius;
}
return radius;
}
public void dispatchRoundBorderDraw(Canvas canvas) {
View owner = mOwner.get();
if (owner == null) {
return;
}
int radius = getRealRadius();
boolean needCheckFakeOuterNormalDraw = radius > 0 && !useFeature() && mOuterNormalColor != 0;
boolean needDrawBorder = mBorderWidth > 0 && mBorderColor != 0;
if (!needCheckFakeOuterNormalDraw && !needDrawBorder) {
return;
}
if (mIsShowBorderonlyBeforeL && useFeature() && mShadowElevation != 0) {
return;
}
int width = canvas.getWidth(), height = canvas.getHeight();
canvas.save();
canvas.translate(owner.getScrollX(), owner.getScrollY());
// react
float halfBorderWith = mBorderWidth / 2f;
if (mIsOutlineExcludePadding) {
mBorderRect.set(
owner.getPaddingLeft() + halfBorderWith,
owner.getPaddingTop() + halfBorderWith,
width - owner.getPaddingRight() - halfBorderWith,
height - owner.getPaddingBottom() - halfBorderWith);
} else {
mBorderRect.set(halfBorderWith, halfBorderWith,
width- halfBorderWith, height - halfBorderWith);
}
if(mShouldUseRadiusArray){
if(mRadiusArray == null){
mRadiusArray = new float[8];
}
if (mHideRadiusSide == HIDE_RADIUS_SIDE_TOP) {
mRadiusArray[4] = radius;
mRadiusArray[5] = radius;
mRadiusArray[6] = radius;
mRadiusArray[7] = radius;
} else if (mHideRadiusSide == HIDE_RADIUS_SIDE_RIGHT) {
mRadiusArray[0] = radius;
mRadiusArray[1] = radius;
mRadiusArray[6] = radius;
mRadiusArray[7] = radius;
} else if (mHideRadiusSide == HIDE_RADIUS_SIDE_BOTTOM) {
mRadiusArray[0] = radius;
mRadiusArray[1] = radius;
mRadiusArray[2] = radius;
mRadiusArray[3] = radius;
} else if (mHideRadiusSide == HIDE_RADIUS_SIDE_LEFT) {
mRadiusArray[2] = radius;
mRadiusArray[3] = radius;
mRadiusArray[4] = radius;
mRadiusArray[5] = radius;
}
}
if (needCheckFakeOuterNormalDraw) {
int layerId = canvas.saveLayer(0, 0, width, height, null, Canvas.ALL_SAVE_FLAG);
canvas.drawColor(mOuterNormalColor);
mClipPaint.setColor(mOuterNormalColor);
mClipPaint.setStyle(Paint.Style.FILL);
mClipPaint.setXfermode(mMode);
if (!mShouldUseRadiusArray) {
canvas.drawRoundRect(mBorderRect, radius, radius, mClipPaint);
} else {
drawRoundRect(canvas, mBorderRect, mRadiusArray, mClipPaint);
}
mClipPaint.setXfermode(null);
canvas.restoreToCount(layerId);
}
if (needDrawBorder) {
mClipPaint.setColor(mBorderColor);
mClipPaint.setStrokeWidth(mBorderWidth);
mClipPaint.setStyle(Paint.Style.STROKE);
if (mShouldUseRadiusArray) {
drawRoundRect(canvas, mBorderRect, mRadiusArray, mClipPaint);
} else if (radius <= 0) {
canvas.drawRect(mBorderRect, mClipPaint);
} else {
canvas.drawRoundRect(mBorderRect, radius, radius, mClipPaint);
}
}
canvas.restore();
}
private void drawRoundRect(Canvas canvas, RectF rect, float[] radiusArray, Paint paint) {
mPath.reset();
mPath.addRoundRect(rect, radiusArray, Path.Direction.CW);
canvas.drawPath(mPath, paint);
}
public static boolean useFeature() {
return Build.VERSION.SDK_INT >= 21;
}
}
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.frameLayout;
import androidx.annotation.AnimRes;
import androidx.annotation.IntDef;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import com.example.theachermanagersystem.R;
import com.example.theachermanagersystem.app.XApplication;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class XNormalPopup extends XbasePopup {
public static final int ANIM_AUTO = 0;
public static final int ANIM_GROW_FROM_LEFT = 1;
public static final int ANIM_GROW_FROM_RIGHT = 2;
public static final int ANIM_GROW_FROM_CENTER = 3;
public static final int ANIM_SPEC = 4;
@IntDef(value = {ANIM_AUTO, ANIM_GROW_FROM_LEFT, ANIM_GROW_FROM_RIGHT, ANIM_GROW_FROM_CENTER, ANIM_SPEC})
@interface AnimStyle {
}
public static final int DIRECTION_TOP = 0;
public static final int DIRECTION_BOTTOM = 1;
public static final int DIRECTION_CENTER_IN_SCREEN = 2;
@IntDef({DIRECTION_CENTER_IN_SCREEN, DIRECTION_TOP, DIRECTION_BOTTOM})
@Retention(RetentionPolicy.SOURCE)
public @interface Direction {
}
protected @AnimStyle int mAnimStyle;
protected int mSpecAnimStyle;
private int mEdgeProtectionTop;
private int mEdgeProtectionLeft;
private int mEdgeProtectionRight;
private int mEdgeProtectionBottom;
private boolean mShowArrow = true;
private boolean mAddShadow = false;
private int mRadius = NOT_SET;
private int mBorderColor = Color.TRANSPARENT;
private int mBorderUsedColor = Color.TRANSPARENT;
private boolean mIsBorderColorSet = false;
private int mBorderWidth = NOT_SET;
private int mShadowElevation = NOT_SET;
private float mShadowAlpha = 0f;
private int mShadowInset = NOT_SET;
private int mBgColor = Color.TRANSPARENT;
private boolean mIsBgColorSet= false;
private int mBgUsedColor = Color.TRANSPARENT;
private int mOffsetX = 0;
private int mOffsetYIfTop = 0;
private int mOffsetYIfBottom = 0;
private @Direction int mPreferredDirection = DIRECTION_BOTTOM;
protected final int mInitWidth;
protected final int mInitHeight;
private int mArrowWidth = NOT_SET;
private int mArrowHeight = NOT_SET;
private boolean mRemoveBorderWhenShadow = false;
private View mContentView;
public XNormalPopup(Context context, int width, int height) {
super(context);
mInitWidth = width;
mInitHeight = height;
}
public T arrow(boolean showArrow) {
mShowArrow = showArrow;
return (T) this;
}
public T arrowSize(int width, int height) {
mArrowWidth = width;
mArrowHeight = height;
return (T) this;
}
public T shadow(boolean addShadow) {
mAddShadow = addShadow;
return (T) this;
}
public T removeBorderWhenShadow(boolean removeBorderWhenShadow) {
mRemoveBorderWhenShadow = removeBorderWhenShadow;
return (T) this;
}
public T animStyle(@AnimStyle int animStyle) {
mAnimStyle = animStyle;
return (T) this;
}
public T customAnimStyle(@AnimRes int animStyle) {
mAnimStyle = ANIM_SPEC;
mSpecAnimStyle = animStyle;
return (T) this;
}
public T radius(int radius) {
mRadius = radius;
return (T) this;
}
public T shadowElevation(int shadowElevation, float shadowAlpha) {
mShadowAlpha = shadowAlpha;
mShadowElevation = shadowElevation;
return (T) this;
}
public T shadowInset(int shadowInset) {
mShadowInset = shadowInset;
return (T) this;
}
public T edgeProtection(int distance) {
mEdgeProtectionLeft = distance;
mEdgeProtectionRight = distance;
mEdgeProtectionTop = distance;
mEdgeProtectionBottom = distance;
return (T) this;
}
public T edgeProtection(int left, int top, int right, int bottom) {
mEdgeProtectionLeft = left;
mEdgeProtectionTop = top;
mEdgeProtectionRight = right;
mEdgeProtectionBottom = bottom;
return (T) this;
}
public T offsetX(int offsetX) {
mOffsetX = offsetX;
return (T) this;
}
public T offsetYIfTop(int y) {
mOffsetYIfTop = y;
return (T) this;
}
public T offsetYIfBottom(int y) {
mOffsetYIfBottom = y;
return (T) this;
}
public T preferredDirection(@Direction int preferredDirection) {
mPreferredDirection = preferredDirection;
return (T) this;
}
public T view(View contentView) {
mContentView = contentView;
return (T) this;
}
public T view(@LayoutRes int contentViewResId) {
return view(LayoutInflater.from(mContext).inflate(contentViewResId, null));
}
public T borderWidth(int borderWidth) {
mBorderWidth = borderWidth;
return (T) this;
}
public T borderColor(int borderColor) {
mBorderColor = borderColor;
mIsBorderColorSet = true;
return (T) this;
}
public int getBgColor() {
return mBgColor;
}
public int getBorderColor() {
return mBorderColor;
}
public T bgColor(int bgColor) {
mBgColor = bgColor;
mIsBgColorSet = true;
return (T) this;
}
class ShowInfo {
private int[] anchorRootLocation = new int[2];
private Rect anchorframe = new Rect();
Rect visibleWindowframe = new Rect();
int width;
int height;
int x;
int y;
int anchorHeight;
int anchorCenter;
int direction = mPreferredDirection;
int contentWidthMeasureSpec;
int contentHeightMeasureSpec;
int decorationLeft = 0;
int decorationRight = 0;
int decorationTop = 0;
int decorationBottom = 0;
ShowInfo(View anchor, int anchorAreaLeft, int anchorAreaTop, int anchorAreaRight, int anchorAreaBottom) {
this.anchorHeight = anchorAreaBottom - anchorAreaTop;
// for muti window
anchor.getRootView().getLocationOnScreen(anchorRootLocation);
int[] anchorLocation = new int[2];
anchor.getLocationOnScreen(anchorLocation);
this.anchorCenter = anchorLocation[0] + (anchorAreaLeft + anchorAreaRight) / 2;
anchor.getWindowVisibleDisplayframe(visibleWindowframe);
anchorframe.left = anchorLocation [0] + anchorAreaLeft;
anchorframe.top = anchorLocation[1] + anchorAreaTop;
anchorframe.right = anchorLocation [0] + anchorAreaRight;
anchorframe.bottom = anchorLocation [1] + anchorAreaBottom;
}
ShowInfo(View anchor){
this(anchor, 0, 0, anchor.getWidth(), anchor.getHeight());
}
float anchorProportion() {
return (anchorCenter - x) / (float) width;
}
int windowWidth() {
return decorationLeft + width + decorationRight;
}
int windowHeight() {
return decorationTop + height + decorationBottom;
}
int getVisibleWidth() {
return visibleWindowframe.width();
}
int getVisibleHeight() {
return visibleWindowframe.height();
}
int getWindowX() {
return x - anchorRootLocation[0];
}
int getWindowY() {
return y - anchorRootLocation[1];
}
}
private boolean shouldShowShadow() {
return mAddShadow;
}
public T show(@NonNull View anchor) {
return show(anchor, 0, 0, anchor.getWidth(), anchor.getHeight());
}
public T show(@NonNull View anchor, int anchorAreaLeft, int anchorAreaTop, int anchorAreaRight, int anchorAreaBottom){
if (mContentView == null) {
throw new RuntimeException("you should call view() to set your content view");
}
ShowInfo showInfo = new ShowInfo(anchor, anchorAreaLeft, anchorAreaTop, anchorAreaRight, anchorAreaBottom);
calculateWindowSize(showInfo);
calculateXY(showInfo);
adjustShowInfo(showInfo);
decorateContentView(showInfo);
setAnimationStyle(showInfo.anchorProportion(), showInfo.direction);
mWindow.setWidth(showInfo.windowWidth());
mWindow.setHeight(showInfo.windowHeight());
showAtLocation(anchor, showInfo.getWindowX(), showInfo.getWindowY());
return (T) this;
}
private void decorateContentView(ShowInfo showInfo) {
if (mIsBorderColorSet) {
mBorderUsedColor = mBorderColor;
} else {
// 设置边框颜色默认为透明色
mBorderUsedColor = Color.TRANSPARENT;
}
if (mIsBgColorSet) {
mBgUsedColor = mBgColor;
} else {
// 设置背景颜色默认值
mBgUsedColor = Color.WHITE;
}
if (mBorderWidth == NOT_SET) {
// 设置边框默认宽度值
mBorderWidth = dp2px(0);
}
ContentView contentView = ContentView.wrap(mContentView, mInitWidth, mInitHeight);
contentView.setBackgroundColor(mBgUsedColor);
contentView.setBorderColor(mBorderUsedColor);
contentView.setBorderWidth(mBorderWidth);
contentView.setShowBorderonlyBeforeL(mRemoveBorderWhenShadow);
if (mRadius == NOT_SET) {
// 设置圆角默认值
mRadius = dp2px(15);
}
if (shouldShowShadow()) {
contentView.setRadiusAndShadow(mRadius, mShadowElevation, mShadowAlpha);
} else {
contentView.setRadius(mRadius);
}
DecorRootView decorRootView = new DecorRootView(mContext, showInfo);
decorRootView.setContentView(contentView);
mWindow.setContentView(decorRootView);
}
private void adjustShowInfo(ShowInfo showInfo) {
if (shouldShowShadow()) {
if (mShadowElevation == NOT_SET) {
mShadowElevation = XResHelper.getAttrDimen(mContext, R.attr.qmui_popup_shadow_elevation);
mShadowAlpha = XResHelper.getAttrFloatValue(mContext, R.attr.qmui_popup_shadow_alpha);
}
if (mShadowInset == NOT_SET) {
mShadowInset = XResHelper.getAttrDimen(mContext, R.attr.qmui_popup_shadow_inset);
}
int originX = showInfo.x, originY = showInfo.y;
if (originX - mShadowInset > showInfo.visibleWindowframe.left) {
showInfo.x -= mShadowInset;
showInfo.decorationLeft = mShadowInset;
} else {
showInfo.decorationLeft = originX - showInfo.visibleWindowframe.left;
showInfo.x = showInfo.visibleWindowframe.left;
}
if (originX + showInfo.width + mShadowInset < showInfo.visibleWindowframe.right) {
showInfo.decorationRight = mShadowInset;
} else {
showInfo.decorationRight = showInfo.visibleWindowframe.right - originX - showInfo.width;
}
if (originY - mShadowInset > showInfo.visibleWindowframe.top) {
showInfo.y -= mShadowInset;
showInfo.decorationTop = mShadowInset;
} else {
showInfo.decorationTop = originY - showInfo.visibleWindowframe.top;
showInfo.y = showInfo.visibleWindowframe.top;
}
if (originY + showInfo.height + mShadowInset < showInfo.visibleWindowframe.bottom) {
showInfo.decorationBottom = mShadowInset;
} else {
showInfo.decorationBottom = showInfo.visibleWindowframe.bottom - originY - showInfo.height;
}
}
if (mShowArrow && showInfo.direction != DIRECTION_CENTER_IN_SCREEN) {
if (mArrowWidth == NOT_SET) {
mArrowWidth = dp2px(18);
}
if (mArrowHeight == NOT_SET) {
mArrowHeight = dp2px(10);
}
if (showInfo.direction == DIRECTION_BOTTOM) {
if (shouldShowShadow()) {
showInfo.y += mArrowHeight;
}
showInfo.decorationTop = Math.max(showInfo.decorationTop, mArrowHeight);
} else if (showInfo.direction == DIRECTION_TOP) {
showInfo.decorationBottom = Math.max(showInfo.decorationBottom, mArrowHeight);
showInfo.y -= mArrowHeight;
}
}
}
private void calculateXY(ShowInfo showInfo) {
if (showInfo.anchorCenter < showInfo.visibleWindowframe.left + showInfo.getVisibleWidth() / 2) { // anchor point on the left
showInfo.x = Math.max(mEdgeProtectionLeft + showInfo.visibleWindowframe.left, showInfo.anchorCenter - showInfo.width / 2 + mOffsetX);
} else { // anchor point on the left
showInfo.x = Math.min(
showInfo.visibleWindowframe.right - mEdgeProtectionRight - showInfo.width,
showInfo.anchorCenter - showInfo.width / 2 + mOffsetX);
}
int nextDirection = DIRECTION_CENTER_IN_SCREEN;
if (mPreferredDirection == DIRECTION_BOTTOM) {
nextDirection = DIRECTION_TOP;
} else if (mPreferredDirection == DIRECTION_TOP) {
nextDirection = DIRECTION_BOTTOM;
}
handleDirection(showInfo, mPreferredDirection, nextDirection);
}
private void handleDirection(ShowInfo showInfo, int currentDirection, int nextDirection) {
if (currentDirection == DIRECTION_CENTER_IN_SCREEN) {
showInfo.x = showInfo.visibleWindowframe.left + (showInfo.getVisibleWidth() - showInfo.width) / 2;
showInfo.y = showInfo.visibleWindowframe.top + (showInfo.getVisibleHeight() - showInfo.height) / 2;
showInfo.direction = DIRECTION_CENTER_IN_SCREEN;
} else if (currentDirection == DIRECTION_TOP) {
showInfo.y = showInfo.anchorframe.top - showInfo.height - mOffsetYIfTop;
if (showInfo.y < mEdgeProtectionTop + showInfo.visibleWindowframe.top) {
handleDirection(showInfo, nextDirection, DIRECTION_CENTER_IN_SCREEN);
} else {
showInfo.direction = DIRECTION_TOP;
}
} else if (currentDirection == DIRECTION_BOTTOM) {
showInfo.y = showInfo.anchorframe.top + showInfo.anchorHeight + mOffsetYIfBottom;
if (showInfo.y > showInfo.visibleWindowframe.bottom - mEdgeProtectionBottom - showInfo.height) {
handleDirection(showInfo, nextDirection, DIRECTION_CENTER_IN_SCREEN);
} else {
showInfo.direction = DIRECTION_BOTTOM;
}
}
}
protected int proxyWidth(int width) {
return width;
}
protected int proxyHeight(int height) {
return height;
}
private void calculateWindowSize(ShowInfo showInfo) {
boolean needMeasureForWidth = false, needMeasureForHeight = false;
if (mInitWidth > 0) {
showInfo.width = proxyWidth(mInitWidth);
showInfo.contentWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
showInfo.width, View.MeasureSpec.EXACTLY);
} else {
int maxWidth = showInfo.getVisibleWidth() - mEdgeProtectionLeft - mEdgeProtectionRight;
if (mInitWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
showInfo.width = proxyWidth(maxWidth);
showInfo.contentWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
showInfo.width, View.MeasureSpec.EXACTLY);
} else {
needMeasureForWidth = true;
showInfo.contentWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
proxyWidth(maxWidth), View.MeasureSpec.AT_MOST);
}
}
if (mInitHeight > 0) {
showInfo.height = proxyHeight(mInitHeight);
showInfo.contentHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
showInfo.height, View.MeasureSpec.EXACTLY);
} else {
int maxHeight = showInfo.getVisibleHeight() - mEdgeProtectionTop - mEdgeProtectionBottom;
if (mInitHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
showInfo.height = proxyHeight(maxHeight);
showInfo.contentHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
showInfo.height, View.MeasureSpec.EXACTLY);
} else {
needMeasureForHeight = true;
showInfo.contentHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
proxyHeight(maxHeight), View.MeasureSpec.AT_MOST);
}
}
if (needMeasureForWidth || needMeasureForHeight) {
mContentView.measure(
showInfo.contentWidthMeasureSpec, showInfo.contentHeightMeasureSpec);
if (needMeasureForWidth) {
showInfo.width = proxyWidth(mContentView.getMeasuredWidth());
}
if (needMeasureForHeight) {
showInfo.height = proxyHeight(mContentView.getMeasuredHeight());
}
}
}
private void setAnimationStyle(float anchorProportion, @Direction int direction) {
boolean onTop = direction == DIRECTION_TOP;
switch (mAnimStyle) {
case ANIM_GROW_FROM_LEFT:
mWindow.setAnimationStyle(onTop ? R.style.QMUI_Animation_PopUpMenu_Left : R.style.QMUI_Animation_PopDownMenu_Left);
break;
case ANIM_GROW_FROM_RIGHT:
mWindow.setAnimationStyle(onTop ? R.style.QMUI_Animation_PopUpMenu_Right : R.style.QMUI_Animation_PopDownMenu_Right);
break;
case ANIM_GROW_FROM_CENTER:
mWindow.setAnimationStyle(onTop ? R.style.QMUI_Animation_PopUpMenu_Center : R.style.QMUI_Animation_PopDownMenu_Center);
break;
case ANIM_AUTO:
if (anchorProportion <= 0.25f) {
mWindow.setAnimationStyle(onTop ? R.style.QMUI_Animation_PopUpMenu_Left : R.style.QMUI_Animation_PopDownMenu_Left);
} else if (anchorProportion > 0.25f && anchorProportion < 0.75f) {
mWindow.setAnimationStyle(onTop ? R.style.QMUI_Animation_PopUpMenu_Center : R.style.QMUI_Animation_PopDownMenu_Center);
} else {
mWindow.setAnimationStyle(onTop ? R.style.QMUI_Animation_PopUpMenu_Right : R.style.QMUI_Animation_PopDownMenu_Right);
}
break;
case ANIM_SPEC:
mWindow.setAnimationStyle(mSpecAnimStyle);
break;
}
}
static class ContentView extends XframeLayout {
private ContentView(Context context) {
super(context);
}
static ContentView wrap(View businessView, int width, int height) {
ContentView contentView = new ContentView(businessView.getContext());
if (businessView.getParent() != null) {
((ViewGroup) businessView.getParent()).removeView(businessView);
}
contentView.addView(businessView, new frameLayout.LayoutParams(width, height));
return contentView;
}
}
class DecorRootView extends frameLayout {
private ShowInfo mShowInfo;
private View mContentView;
private Paint mArrowPaint;
private Path mArrowPath;
private RectF mArrowSaveRect = new RectF();
private PorterDuffXfermode mArrowAlignMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
private int mPendingWidth;
private int mPendingHeight;
private Runnable mUpdateWindowAction = new Runnable() {
@Override
public void run() {
mShowInfo.width = mPendingWidth;
mShowInfo.height = mPendingHeight;
calculateXY(mShowInfo);
adjustShowInfo(mShowInfo);
mWindow.update(mShowInfo.getWindowX(), mShowInfo.getWindowY(), mShowInfo.windowWidth(), mShowInfo.windowHeight());
}
};
private DecorRootView(Context context, ShowInfo showInfo) {
super(context);
mShowInfo = showInfo;
mArrowPaint = new Paint();
mArrowPaint.setAntiAlias(true);
mArrowPath = new Path();
}
public void setContentView(View contentView) {
if (mContentView != null) {
removeView(mContentView);
}
if (contentView.getParent() != null) {
((ViewGroup) contentView.getParent()).removeView(contentView);
}
mContentView = contentView;
addView(contentView);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
removeCallbacks(mUpdateWindowAction);
if (mContentView != null) {
mContentView.measure(mShowInfo.contentWidthMeasureSpec, mShowInfo.contentHeightMeasureSpec);
int measuredWidth = mContentView.getMeasuredWidth();
int measuredHeight = mContentView.getMeasuredHeight();
if (mShowInfo.width != measuredWidth || mShowInfo.height != measuredHeight) {
mPendingWidth = measuredWidth;
mPendingHeight = measuredHeight;
post(mUpdateWindowAction);
}
}
setMeasuredDimension(mShowInfo.windowWidth(), mShowInfo.windowHeight());
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (mContentView != null) {
mContentView.layout(mShowInfo.decorationLeft, mShowInfo.decorationTop,
mShowInfo.width + mShowInfo.decorationLeft,
mShowInfo.height + mShowInfo.decorationTop);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
removeCallbacks(mUpdateWindowAction);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mShowArrow) {
if (mShowInfo.direction == DIRECTION_TOP) {
canvas.save();
mArrowSaveRect.set(0f, 0f, mShowInfo.width, mShowInfo.height);
mArrowPaint.setStyle(Paint.Style.FILL);
mArrowPaint.setColor(mBgUsedColor);
mArrowPaint.setXfermode(null);
int l = mShowInfo.anchorCenter - mShowInfo.x - mArrowWidth / 2;
l = Math.min(Math.max(l, mShowInfo.decorationLeft),
getWidth() - mShowInfo.decorationRight - mArrowWidth);
int t = mShowInfo.decorationTop + mShowInfo.height - mBorderWidth;
canvas.translate(l, t);
mArrowPath.reset();
mArrowPath.setLastPoint(-mArrowWidth / 2f, -mArrowHeight);
mArrowPath.lineTo(mArrowWidth / 2f, mArrowHeight);
mArrowPath.lineTo(mArrowWidth * 3 /2f, -mArrowHeight);
mArrowPath.close();
canvas.drawPath(mArrowPath, mArrowPaint);
if (!mRemoveBorderWhenShadow || !shouldShowShadow()) {
mArrowSaveRect.set(0f, -mBorderWidth, mArrowWidth, mArrowHeight + mBorderWidth);
int saveLayer = canvas.saveLayer(mArrowSaveRect, mArrowPaint, Canvas.ALL_SAVE_FLAG);
mArrowPaint.setStrokeWidth(mBorderWidth);
mArrowPaint.setColor(mBorderUsedColor);
mArrowPaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(mArrowPath, mArrowPaint);
mArrowPaint.setXfermode(mArrowAlignMode);
mArrowPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(0f, -mBorderWidth, mArrowWidth, 0, mArrowPaint);
canvas.restoreToCount(saveLayer);
}
canvas.restore();
} else if (mShowInfo.direction == DIRECTION_BOTTOM) {
canvas.save();
mArrowPaint.setStyle(Paint.Style.FILL);
mArrowPaint.setXfermode(null);
mArrowPaint.setColor(mBgUsedColor);
int l = mShowInfo.anchorCenter - mShowInfo.x - mArrowWidth / 2;
l = Math.min(Math.max(l, mShowInfo.decorationLeft),
getWidth() - mShowInfo.decorationRight - mArrowWidth);
int t = mShowInfo.decorationTop + mBorderWidth;
canvas.translate(l, t);
mArrowPath.reset();
mArrowPath.setLastPoint(-mArrowWidth / 2f, mArrowHeight);
mArrowPath.lineTo(mArrowWidth / 2f, -mArrowHeight);
mArrowPath.lineTo(mArrowWidth * 3 / 2f, mArrowHeight);
mArrowPath.close();
canvas.drawPath(mArrowPath, mArrowPaint);
if (!mRemoveBorderWhenShadow || !shouldShowShadow()) {
mArrowSaveRect.set(0, -mArrowHeight - mBorderWidth, mArrowWidth, mBorderWidth);
int saveLayer = canvas.saveLayer(mArrowSaveRect, mArrowPaint, Canvas.ALL_SAVE_FLAG);
mArrowPaint.setStrokeWidth(mBorderWidth);
mArrowPaint.setStyle(Paint.Style.STROKE);
mArrowPaint.setColor(mBorderUsedColor);
canvas.drawPath(mArrowPath, mArrowPaint);
mArrowPaint.setXfermode(mArrowAlignMode);
mArrowPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(0, 0, mArrowWidth, mBorderWidth, mArrowPaint);
canvas.restoreToCount(saveLayer);
}
canvas.restore();
}
}
}
}
public int dp2px(int dp) {
return (int) (XApplication.getContext().getResources().getDisplayMetrics().density * dp + 0.5);
}
}
package com.example.theachermanagersystem.popup;
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
public class XPopup extends XNormalPopup {
public XPopup(Context context, int width, int height) {
super(context, width, height);
}
@Override
public XPopup show(@NonNull View anchor) {
return super.show(anchor);
}
@Override
public XPopup show(@NonNull View anchor, int anchorAreaLeft, int anchorAreaTop, int anchorAreaRight, int anchorAreaBottom) {
return super.show(anchor, anchorAreaLeft, anchorAreaTop, anchorAreaRight, anchorAreaBottom);
}
}
package com.example.theachermanagersystem.popup;
import android.content.Context;
import android.view.ViewGroup;
public class XPopupShowmaker {
public static XPopup popup(Context context) {
return new XPopup(context,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
public static XPopup popup(Context context, int width) {
return new XPopup(context,
width,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
public static XPopup popup(Context context, int width, int height) {
return new XPopup(context, width, height);
}
}
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
public class XResHelper {
private static TypedValue sTmpValue;
public static float getAttrFloatValue(Context context, int attr) {
return getAttrFloatValue(context.getTheme(), attr);
}
public static float getAttrFloatValue(Resources.Theme theme, int attr) {
if (sTmpValue == null) {
sTmpValue = new TypedValue();
}
if (!theme.resolveAttribute(attr, sTmpValue, true)) {
return 0;
}
return sTmpValue.getFloat();
}
public static int getAttrColor(Context context, int attrRes) {
return getAttrColor(context.getTheme(), attrRes);
}
public static int getAttrColor(Resources.Theme theme, int attr) {
if (sTmpValue == null) {
sTmpValue = new TypedValue();
}
if (!theme.resolveAttribute(attr, sTmpValue, true)) {
return 0;
}
if (sTmpValue.type == TypedValue.TYPE_ATTRIBUTE) {
return getAttrColor(theme, sTmpValue.data);
}
return sTmpValue.data;
}
@Nullable
public static ColorStateList getAttrColorStateList(Context context, int attrRes) {
return getAttrColorStateList(context, context.getTheme(), attrRes);
}
@Nullable
public static ColorStateList getAttrColorStateList(Context context, Resources.Theme theme, int attr) {
if (attr == 0) {
return null;
}
if (sTmpValue == null) {
sTmpValue = new TypedValue();
}
if (!theme.resolveAttribute(attr, sTmpValue, true)) {
return null;
}
if (sTmpValue.type >= TypedValue.TYPE_FIRST_COLOR_INT
&& sTmpValue.type <= TypedValue.TYPE_LAST_COLOR_INT) {
return ColorStateList.valueOf(sTmpValue.data);
}
if (sTmpValue.type == TypedValue.TYPE_ATTRIBUTE) {
return getAttrColorStateList(context, theme, sTmpValue.data);
}
if (sTmpValue.resourceId == 0) {
return null;
}
return ContextCompat.getColorStateList(context, sTmpValue.resourceId);
}
public static int getAttrDimen(Context context, int attrRes) {
if (sTmpValue == null) {
sTmpValue = new TypedValue();
}
if (!context.getTheme().resolveAttribute(attrRes, sTmpValue, true)) {
return 0;
}
return TypedValue.complexToDimensionPixelSize(sTmpValue.data, getDisplayMetrics(context));
}
public static DisplayMetrics getDisplayMetrics(Context context) {
return context.getResources().getDisplayMetrics();
}
@Nullable
public static String getAttrString(Context context, int attrRes) {
if (sTmpValue == null) {
sTmpValue = new TypedValue();
}
if (!context.getTheme().resolveAttribute(attrRes, sTmpValue, true)) {
return null;
}
CharSequence str = sTmpValue.string;
return str == null ? null : str.toString();
}
public static int getAttrInt(Context context, int attrRes) {
if (sTmpValue == null) {
sTmpValue = new TypedValue();
}
context.getTheme().resolveAttribute(attrRes, sTmpValue, true);
return sTmpValue.data;
}
}