首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带聊天类型边框的线性布局

带聊天类型边框的线性布局
EN

Stack Overflow用户
提问于 2019-09-13 23:54:08
回答 2查看 134关注 0票数 1

如何为Android中的线性布局提供附加类型的边框。我正在开发一个Xamarin Android应用程序。

我给出了以下代码,以实现圆角布局。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>

 <shape xmlns:android="http://schemas.android.com/apk/res/android" 
   android:shape="rectangle">
 <corners android:radius="10dp"/> 

 <padding android:left="10dp" 
  android:right="10dp" 
  android:top="10dp" 
  android:bottom="10dp"/>

 <stroke android:width="1dp" 
  android:color="#CCCCCC"/> </shape>
EN

回答 2

Stack Overflow用户

发布于 2019-09-14 15:32:27

您必须使用Android Nine Patch Image。九补丁图像是一种android特殊的图像格式,可以使背景图像正确缩放。

see this link

票数 1
EN

Stack Overflow用户

发布于 2019-09-16 11:24:31

正如赛义德·马苏德·卡德米所说,你可以使用九补丁图像轻松实现效果,当然你也可以使用自定义view.here来实现这一点,这是一个简单的示例:

创建自定义视图:

代码语言:javascript
复制
public  class BubbleLayout : FrameLayout
 {
    public static  int LEFT = 1;
    public static  int TOP = 2;
    public static  int RIGHT = 3;
    public static  int BOTTOM = 4;

    // radius size
    private int mRadius;


    //the center of the base of a triangle
    private Point mDatumPoint;

    //Triangle position offset (centered by default)
    private int mOffset;

    private Paint mBorderPaint;

    private Path mPath;

    private RectF mRect;

    //Direction of triangle
    private int mDirection;
    protected BubbleLayout(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {

    }

    public BubbleLayout(Context context) : base(context)
    {
        init(context,null);
    }

    private void init(Context context, IAttributeSet attrs)
    {
        TypedArray ta = context.ObtainStyledAttributes(attrs, Resource.Styleable.BubbleLayout);
        //back ground color
        var backGroundColor = ta.GetColor(Resource.Styleable.BubbleLayout_background_color, Color.White);
        //shadow color
        var shadowColor = ta.GetColor(Resource.Styleable.BubbleLayout_shadow_color,
                Color.ParseColor("#999999"));
        int defShadowSize = (int)TypedValue.ApplyDimension(ComplexUnitType.Px,
                4, Resources.DisplayMetrics);
        //shadow size
        int shadowSize = ta.GetDimensionPixelSize(Resource.Styleable.BubbleLayout_shadow_size, defShadowSize);
        mRadius = ta.GetDimensionPixelSize(Resource.Styleable.BubbleLayout_radius, 0);
        //Triangular direction
        mDirection = ta.GetInt(Resource.Styleable.BubbleLayout_direction, BOTTOM);
        mOffset = ta.GetDimensionPixelOffset(Resource.Styleable.BubbleLayout_offset, 0);
        ta.Recycle();

        mBorderPaint = new Paint();
        mBorderPaint.AntiAlias = true;
        mBorderPaint.Color = backGroundColor;
        mBorderPaint.SetShadowLayer(shadowSize, 0, 0, shadowColor);

        mPath = new Path();
        mRect = new RectF();
        mDatumPoint = new Point();

        SetWillNotDraw(false);
        //Turn off hardware acceleration
        SetLayerType(LayerType.Software, null);
    }

    public BubbleLayout(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        init(context, attrs); ;
    }

    public BubbleLayout(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
    {
        init(context, attrs);
    }

    private void drawLeftTriangle(Canvas canvas)
    {
        int triangularLength = PaddingLeft;
        if (triangularLength == 0)
        {
            return;
        }

        mPath.AddRoundRect(mRect, mRadius, mRadius, Path.Direction.Ccw);
        mPath.MoveTo(mDatumPoint.X, mDatumPoint.Y - triangularLength / 2);
        mPath.LineTo(mDatumPoint.X - triangularLength / 2, mDatumPoint.Y);
        mPath.LineTo(mDatumPoint.X, mDatumPoint.Y + triangularLength / 2);
        mPath.Close();
        canvas.DrawPath(mPath, mBorderPaint);
    }

    private void drawTopTriangle(Canvas canvas)
    {
        int triangularLength = PaddingTop;
        if (triangularLength == 0)
        {
            return;
        }

        mPath.AddRoundRect(mRect, mRadius, mRadius, Path.Direction.Ccw);
        mPath.MoveTo(mDatumPoint.X + triangularLength / 2, mDatumPoint.Y);
        mPath.LineTo(mDatumPoint.X, mDatumPoint.Y - triangularLength / 2);
        mPath.LineTo(mDatumPoint.X - triangularLength / 2, mDatumPoint.Y);
        mPath.Close();
        canvas.DrawPath(mPath, mBorderPaint);
    }

    private void drawRightTriangle(Canvas canvas)
    {
        int triangularLength = PaddingRight;
        if (triangularLength == 0)
        {
            return;
        }

        mPath.AddRoundRect(mRect, mRadius, mRadius, Path.Direction.Ccw);
        mPath.MoveTo(mDatumPoint.X, mDatumPoint.Y - triangularLength / 2);
        mPath.LineTo(mDatumPoint.X + triangularLength / 2, mDatumPoint.Y);
        mPath.LineTo(mDatumPoint.X, mDatumPoint.Y + triangularLength / 2);
        mPath.Close();
        canvas.DrawPath(mPath, mBorderPaint);
    }

    private void drawBottomTriangle(Canvas canvas)
    {
        int triangularLength = PaddingBottom;
        if (triangularLength == 0)
        {
            return;
        }

        mPath.AddRoundRect(mRect, mRadius, mRadius, Path.Direction.Ccw);
        mPath.MoveTo(mDatumPoint.X + triangularLength / 2, mDatumPoint.Y);
        mPath.LineTo(mDatumPoint.X, mDatumPoint.Y + triangularLength / 2);
        mPath.LineTo(mDatumPoint.X - triangularLength / 2, mDatumPoint.Y);
        mPath.Close();
        canvas.DrawPath(mPath, mBorderPaint);
    }

    protected override void OnDraw(Canvas canvas)
    {
        base.OnDraw(canvas);
        if (mDatumPoint.X > 0 && mDatumPoint.Y > 0)
            switch (mDirection)
            {
                case 1:
                    drawLeftTriangle(canvas);
                    break;
                case 2:
                    drawTopTriangle(canvas);
                    break;
                case 3:
                    drawRightTriangle(canvas);
                    break;
                case 4:
                    drawBottomTriangle(canvas);
                    break;
            }
    }

    protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
    {
        base.OnSizeChanged(w, h, oldw, oldh);
        mRect.Left = PaddingLeft;
        mRect.Top = PaddingTop;
        mRect.Right = w - PaddingRight;
        mRect.Bottom = h - PaddingBottom;

        switch (mDirection)
        {
            case 1:
                mDatumPoint.X = PaddingLeft;
                mDatumPoint.Y = h / 2;
                break;
            case 2:
                mDatumPoint.X = w / 2;
                mDatumPoint.Y = PaddingTop;
                break;
            case 3:
                mDatumPoint.X = w - PaddingRight;
                mDatumPoint.Y = h / 2;
                break;
            case 4:
                mDatumPoint.X = w / 2;
                mDatumPoint.Y = h - PaddingBottom;
                break;
        }

        if (mOffset != 0)
        {
            applyOffset();
        }
    }


    /**
     * Set the triangle offset position
     *
     * @param offset 
    */
    public void setTriangleOffset(int offset)
    {
        this.mOffset = offset;
        applyOffset();
        Invalidate();
    }
    private void applyOffset()
    {
        switch (mDirection)
        {
            case 1:
            case 2:
                mDatumPoint.Y += mOffset;
                break;
            case 3:
            case 4:
                mDatumPoint.X += mOffset;
                break;
        }
    }
}  

Resources/values中定义attrs.xml

代码语言:javascript
复制
<declare-styleable name="BubbleLayout">
  <attr name="background_color" format="color" />
  <attr name="shadow_color" format="color" />
  <attr name="shadow_size" format="dimension" />
  <attr name="radius" format="dimension" />
  <attr name="direction" format="enum">
    <enum name="left" value="1" />
    <enum name="top" value="2" />
    <enum name="right" value="3" />
    <enum name="bottom" value="4" />
</attr>
<attr name="offset" format="dimension" />

在您的layout.xaml中:

代码语言:javascript
复制
<namespace.BubbleLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="16dp"   //You must set enough padding to draw the triangle and shadow
    app:background_color="#FF4081"
    app:direction="bottom"
    app:offset="-20dp"
    app:radius="4dp"
    app:shadow_color="#999999"
    app:shadow_size="4dp">
    <TextView 
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="HelloWorld"
    />
</namespace.BubbleLayout>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57926838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档