<resources>
<declare-styleable name="ArrowRectangleView">
<attr name="arrow_width" format="dimension" />
<attr name="arrow_height" format="dimension" />
<attr name="arrow_offset" format="dimension" />
<attr name="radius" format="dimension" />
<attr name="background_color" format="color" />
<attr name="shadow_color" format="color" />
<attr name="shadow_thickness" format="dimension" />
</declare-styleable>
</resources>
public class ArrowRectangleView extends ViewGroup {
... ...
public ArrowRectangleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.ArrowRectangleView, defStyleAttr, 0);
for (int i = 0; i < a.getIndexCount(); i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.ArrowRectangleView_arrow_width:
mArrowWidth = a.getDimensionPixelSize(attr, mArrowWidth);
break;
case R.styleable.ArrowRectangleView_arrow_height:
mArrowHeight = a.getDimensionPixelSize(attr, mArrowHeight);
break;
case R.styleable.ArrowRectangleView_radius:
mRadius = a.getDimensionPixelSize(attr, mRadius);
break;
case R.styleable.ArrowRectangleView_background_color:
mBackgroundColor = a.getColor(attr, mBackgroundColor);
break;
case R.styleable.ArrowRectangleView_arrow_offset:
mArrowOffset = a.getDimensionPixelSize(attr, mArrowOffset);
break;
case R.styleable.ArrowRectangleView_shadow_color:
mShadowColor = a.getColor(attr, mShadowColor);
break;
case R.styleable.ArrowRectangleView_shadow_thickness:
mShadowThickness = a.getDimensionPixelSize(attr, mShadowThickness);
break;
}
}
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
int maxWidth = 0;
// reserve space for the arrow and round corners
int maxHeight = mArrowHeight + mRadius;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
maxWidth = Math.max(maxWidth, child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
maxHeight = maxHeight + child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
}
}
maxWidth = maxWidth + getPaddingLeft() + getPaddingRight() + mShadowThickness;
maxHeight = maxHeight + getPaddingTop() + getPaddingBottom() + mShadowThickness;
setMeasuredDimension(maxWidth, maxHeight);
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
int topOffset = t + mArrowHeight + mRadius/2;
int top = 0;
int bottom = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
top = topOffset + i * child.getMeasuredHeight();
bottom = top + child.getMeasuredHeight();
child.layout(l, top, r - mRadius/2 - mShadowThickness, bottom);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
// disable h/w acceleration for blur mask filter
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(mBackgroundColor);
paint.setStyle(Paint.Style.FILL);
// set Xfermode for source and shadow overlap
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
// draw round corner rectangle
paint.setColor(mBackgroundColor);
canvas.drawRoundRect(new RectF(0, mArrowHeight, getMeasuredWidth() - mShadowThickness, getMeasuredHeight() - mShadowThickness), mRadius, mRadius, paint);
// draw arrow
Path path = new Path();
int startPoint = getMeasuredWidth() - mArrowOffset;
path.moveTo(startPoint, mArrowHeight);
path.lineTo(startPoint + mArrowWidth, mArrowHeight);
path.lineTo(startPoint + mArrowWidth / 2, 0);
path.close();
canvas.drawPath(path, paint);
// draw shadow
if (mShadowThickness > 0) {
paint.setMaskFilter(new BlurMaskFilter(mShadowThickness, BlurMaskFilter.Blur.OUTER));
paint.setColor(mShadowColor);
canvas.drawRoundRect(new RectF(mShadowThickness, mArrowHeight + mShadowThickness, getMeasuredWidth() - mShadowThickness, getMeasuredHeight() - mShadowThickness), mRadius, mRadius, paint);
}
super.dispatchDraw(canvas);
}
<?xml version="1.0" encoding="utf-8"?>
<com.xinxin.arrowrectanglemenu.widget.ArrowRectangleView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@android:color/transparent"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:splitMotionEvents="false"
app:arrow_offset="31dp"
app:arrow_width="16dp"
app:arrow_height="8dp"
app:radius="5dp"
app:background_color="#ffb1df83"
app:shadow_color="#66000000"
app:shadow_thickness="5dp">
<LinearLayout
android:id="@+id/cmx_toolbar_menu_turn_off"
android:layout_width="wrap_content"
android:layout_height="42dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="16sp"
android:textColor="#FF393F4A"
android:paddingLeft="16dp"
android:paddingRight="32dp"
android:clickable="false"
android:text="Menu Item #1"/>
</LinearLayout>
<LinearLayout
android:id="@+id/cmx_toolbar_menu_feedback"
android:layout_width="wrap_content"
android:layout_height="42dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="16sp"
android:textColor="#FF393F4A"
android:paddingLeft="16dp"
android:paddingRight="32dp"
android:clickable="false"
android:text="Menu Item #2"/>
</LinearLayout>
</com.xinxin.arrowrectanglemenu.widget.ArrowRectangleView>
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有