Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 三角形按钮安卓点击/悬停_C#_Android_Xamarin - Fatal编程技术网

C# 三角形按钮安卓点击/悬停

C# 三角形按钮安卓点击/悬停,c#,android,xamarin,C#,Android,Xamarin,我在android中创建了一个三角形按钮。它工作得很好。 我只想在按钮悬停/按下时更改填充颜色/笔划颜色(如默认按钮) 我试图在hovered属性更改时使视图无效,并在OnDraw方法中更改颜色,但没有成功 这是我的代码: public enum TriangularButtonDirection { Up = 0, Down = 1 } class TriangularButton : Button { public TriangularButton(IntPtr j

我在android中创建了一个三角形按钮。它工作得很好。 我只想在按钮悬停/按下时更改填充颜色/笔划颜色(如默认按钮)

我试图在hovered属性更改时使视图无效,并在OnDraw方法中更改颜色,但没有成功

这是我的代码:

public enum TriangularButtonDirection
{
    Up = 0,
    Down = 1
}

class TriangularButton : Button
{
    public TriangularButton(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
        this.Initialize(null);
    }

    public TriangularButton(Context context) : base(context)
    {
        this.Initialize(null);
    }

    public TriangularButton(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        this.Initialize(attrs);
    }

    public TriangularButton(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
    {
        this.Initialize(attrs);
    }

    public TriangularButton(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
    {
        this.Initialize(attrs);
    }

    private TriangularButtonDirection _direction = TriangularButtonDirection.Down;

    private void Initialize(IAttributeSet attributeSet)
    {
        if (attributeSet != null)
        {
            TypedArray a = this.Context.ObtainStyledAttributes(attributeSet, Resource.Styleable.TriangularButton);

            int direction = a.GetInt(Resource.Styleable.TriangularButton_direction, -1);
            if (direction > -1)
                this._direction = (TriangularButtonDirection)direction;
            a.Recycle();
        }
    }

    public override bool OnTouchEvent(MotionEvent e)
    {
        float x = e.GetX();
        float y = e.GetY();
        int width = this.MeasuredWidth;
        PointF point1Draw;
        PointF point2Draw;
        PointF point3Draw;
        if (this._direction == TriangularButtonDirection.Up)
        {
            point1Draw = new PointF(0, 3f * width / 4);
            point2Draw = new PointF(width, 3f * width / 4);
            point3Draw = new PointF(width / 2f, 0);
        }
        else
        {
            point1Draw = new PointF(0, 0);
            point2Draw = new PointF(width, 0);
            point3Draw = new PointF(width / 2f, 3f * width / 4);
        }
        bool test = PointInTriangle(new PointF(x, y), point1Draw, point2Draw, point3Draw);
        if (test)
            base.OnTouchEvent(e);
        return (test);
    }

    public static bool PointInTriangle(PointF p, PointF p0, PointF p1, PointF p2)
    {
        float s = p0.Y * p2.X - p0.X * p2.Y + (p2.Y - p0.Y) * p.X + (p0.X - p2.X) * p.Y;
        float t = p0.X * p1.Y - p0.Y * p1.X + (p0.Y - p1.Y) * p.X + (p1.X - p0.X) * p.Y;
        if ((s < 0) != (t < 0))
            return false;
        float a = -p1.Y * p2.X + p0.Y * (p2.X - p1.X) + p0.X * (p1.Y - p2.Y) + p1.X * p2.Y;
        if (a < 0.0)
        {
            s = -s;
            t = -t;
            a = -a;
        }
        return s > 0 && t > 0 && (s + t) <= a;
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
        this.SetMeasuredDimension(this.MeasuredWidth, 3 * this.MeasuredWidth / 4);
    }

    public override void Draw(Canvas canvas)
    {
        int width = this.MeasuredWidth;

        Paint paintFill = new Paint(PaintFlags.AntiAlias);
        paintFill.StrokeWidth = 2; 
        paintFill.Color = this.Hovered ? Color.Red : new Color(242, 180, 54);
        paintFill.SetStyle(Android.Graphics.Paint.Style.Fill);
        paintFill.AntiAlias = true;

        Paint paintStroke = new Paint(PaintFlags.AntiAlias);
        paintStroke.StrokeWidth = 2;
        paintStroke.Color = Color.White;
        paintStroke.SetStyle(Android.Graphics.Paint.Style.Stroke);
        paintStroke.AntiAlias = true;

        PointF point1Draw;
        PointF point2Draw;
        PointF point3Draw;
        if (this._direction == TriangularButtonDirection.Up)
        {
            point1Draw = new PointF(0, 3f * width / 4);
            point2Draw = new PointF(width, 3f * width / 4);
            point3Draw = new PointF(width / 2f, 0);
        }
        else
        {
            point1Draw = new PointF(0, 0);
            point2Draw = new PointF(width, 0);
            point3Draw = new PointF(width / 2f, 3f * width / 4);
        }

        Path path = new Path();
        path.SetFillType(Path.FillType.EvenOdd);
        path.MoveTo(point1Draw.X, point1Draw.Y);
        path.LineTo(point2Draw.X, point2Draw.Y);
        path.LineTo(point3Draw.X, point3Draw.Y);
        path.LineTo(point1Draw.X, point1Draw.Y);
        path.Close();

        canvas.DrawPath(path, paintFill);
        canvas.DrawPath(path, paintStroke);
    }
}
public enum TriangularButtonDirection
{
Up=0,
向下=1
}
类三角形按钮:按钮
{
公共三角按钮(IntPtr javaReference,JniHandleOwnership transfer):base(javaReference,transfer)
{
初始化(null);
}
公共三角形按钮(上下文):基础(上下文)
{
初始化(null);
}
公共三角形按钮(上下文,IAttributeSet属性):基本(上下文,属性)
{
初始化(attrs);
}
公共三角形按钮(上下文,IAttributeSet属性,int defStyleAttr):基(上下文,属性,defStyleAttr)
{
初始化(attrs);
}
公共三角形按钮(上下文上下文、IAttributeSet属性、int-defstylettr、int-defStyleRes):基本(上下文、属性、defStyleAttr、defStyleRes)
{
初始化(attrs);
}
private TriangularButtonDirection _direction=TriangularButtonDirection.Down;
私有void初始化(IAttributeSet attributeSet)
{
if(attributeSet!=null)
{
TypedArray a=this.Context.ActainStyledAttributes(attributeSet,Resource.Styleable.TriangularButton);
int direction=a.GetInt(Resource.Styleable.TriangularButton_direction,-1);
如果(方向>-1)
此._方向=(三角形按钮方向)方向;
a、 回收();
}
}
公共覆盖bool ONTOUCHENT(运动事件e)
{
float x=e.GetX();
float y=e.GetY();
int-width=此.MeasuredWidth;
PointF point1Draw;
点f点2draw;
PointF point3Draw;
if(this._direction==TriangularButtonDirection.Up)
{
point1Draw=新的PointF(0,3f*宽度/4);
point2Draw=新的PointF(宽度,3f*宽度/4);
point3Draw=新的PointF(宽度/2f,0);
}
其他的
{
point1Draw=新的PointF(0,0);
point2Draw=新的PointF(宽度,0);
point3Draw=新的PointF(宽度/2f,3f*宽度/4);
}
布尔测试=点三角形(新点F(x,y)、点1Draw、点2Draw、点3Draw);
如果(测试)
基孔(e);
返回(测试);
}
公共静态布尔点三角形(点F p、点F p0、点F p1、点F p2)
{
浮点s=p0.Y*p2.X-p0.X*p2.Y+(p2.Y-p0.Y)*p.X+(p0.X-p2.X)*p.Y;
浮动t=p0.X*p1.Y-p0.Y*p1.X+(p0.Y-p1.Y)*p.X+(p1.X-p0.X)*p.Y;
如果((s<0)!=(t<0))
返回false;
浮点a=-p1.Y*p2.X+p0.Y*(p2.X-p1.X)+p0.X*(p1.Y-p2.Y)+p1.X*p2.Y;
如果(a<0.0)
{
s=-s;
t=-t;
a=-a;
}
返回s>0&&t>0&&t(s+t)-1)
此._方向=(三角形按钮方向)方向;
a、 回收();
}
此._paintFillNormal=新油漆(PaintFlags.antialas);
这._paintFillNormal.StrokeWidth=2;
这._paintFillNormal.Color=新颜色(242、180、54);
这个.u paintFillNormal.SetStyle(Android.Graphics.Paint.Style.Fill);
这是._paintFillNormal.antialas=true;
此._paintFillPressed=新油漆(PaintFlags.antialas);
这._paintFillPressed.StrokeWidth=2;
此._paintFillPressed.Color=新颜色(255、255、255、51);
这个.u paintFillPressed.SetStyle(Android.Graphics.Paint.Style.Fill);
这是._paintFillPressed.antialas=true;
此._paintStrokeNormal=新油漆(PaintFlags.antialas);
这一点。_paintStrokeNormal.StrokeWidth=2;
这个._paintStrokeNormal.Color=Color.White;
这个.u paintStrokeNormal.SetStyle(Android.Graphics.Paint.Style.Stroke);
此项。_paintStrokeNormal.antialas=true;
此._paintStrokePressed=新油漆(PaintFlags.antialas);
这是._paintStrokePressed.StrokeWidth=2;
此._paintStrokePressed.Color=新颜色(51,51,51,51);
这个.u paintStrokePressed.SetStyle(Android.Graphics.Paint.Style.Stroke);
此项。_paintStrokePressed.antialas=true;
}
私人住宅已启用;
公共覆盖布尔已启用
{
get=>这个;
设置
{
如果(此项已启用!=值)
{
此项。_isEnabled=值;
这个。使无效();
}
}
}
公共覆盖bool ONTOUCHENT(运动事件e)
{
如果(!此项已启用)
返回(假);
float x=e.GetX();
float y=e.GetY();
int-width=此.MeasuredWidth;
PointF point1Draw;
点f点2draw;
PointF point3Draw;
if(this._direction==TriangularButtonDirection.Up)
{
point1Draw=新的PointF(0,3f*宽度/4);
point2Draw=新的PointF(宽度,3f*宽度/4);
point3Draw=新的PointF(宽度/2f,0);
}
其他的
{
point1Draw=新的PointF(0,0);
point2Draw=新的PointF(宽度,0);
point3Draw=新的PointF(宽度/2f,3f*宽度/4);
}
布尔测试=点三角形(新点F(x,y)、点1Draw、点2Draw、点3Draw);
如果(测试)
{
基孔(e);
}
开关(电动)
{
案例MotionEventActions.Down:
此._state=TriangularButtonState.Pressed;
测试=真;
这个。使无效();
打破
case MotionEventActions.HoverEnter:
这个州=
    class TriangularButton : Button
{
    public TriangularButton(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
        this.Initialize(null);
    }

    public TriangularButton(Context context) : base(context)
    {
        this.Initialize(null);
    }

    public TriangularButton(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        this.Initialize(attrs);
    }

    public TriangularButton(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
    {
        this.Initialize(attrs);
    }

    public TriangularButton(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
    {
        this.Initialize(attrs);
    }

    private TriangularButtonDirection _direction = TriangularButtonDirection.Down;
    private TriangularButtonState _state = TriangularButtonState.Normal;
    private Paint _paintFillNormal;
    private Paint _paintStrokeNormal;
    private Paint _paintFillPressed;
    private Paint _paintStrokePressed;
    private void Initialize(IAttributeSet attributeSet)
    {
        if (attributeSet != null)
        {
            TypedArray a = this.Context.ObtainStyledAttributes(attributeSet, Resource.Styleable.TriangularButton);

            int direction = a.GetInt(Resource.Styleable.TriangularButton_direction, -1);
            if (direction > -1)
                this._direction = (TriangularButtonDirection)direction;
            a.Recycle();
        }

        this._paintFillNormal = new Paint(PaintFlags.AntiAlias);
        this._paintFillNormal.StrokeWidth = 2;
        this._paintFillNormal.Color = new Color(242, 180, 54);
        this._paintFillNormal.SetStyle(Android.Graphics.Paint.Style.Fill);
        this._paintFillNormal.AntiAlias = true;

        this._paintFillPressed = new Paint(PaintFlags.AntiAlias);
        this._paintFillPressed.StrokeWidth = 2;
        this._paintFillPressed.Color = new Color(255, 255, 255, 51);
        this._paintFillPressed.SetStyle(Android.Graphics.Paint.Style.Fill);
        this._paintFillPressed.AntiAlias = true;


        this._paintStrokeNormal = new Paint(PaintFlags.AntiAlias);
        this._paintStrokeNormal.StrokeWidth = 2;
        this._paintStrokeNormal.Color = Color.White;
        this._paintStrokeNormal.SetStyle(Android.Graphics.Paint.Style.Stroke);
        this._paintStrokeNormal.AntiAlias = true;

        this._paintStrokePressed = new Paint(PaintFlags.AntiAlias);
        this._paintStrokePressed.StrokeWidth = 2;
        this._paintStrokePressed.Color = new Color(51, 51, 51, 51);
        this._paintStrokePressed.SetStyle(Android.Graphics.Paint.Style.Stroke);
        this._paintStrokePressed.AntiAlias = true;



    }

    private bool _isEnabled;
    public override bool Enabled
    {
        get => this._isEnabled;
        set
        {
            if (this._isEnabled != value)
            {
                this._isEnabled = value;
                this.Invalidate();
            }
        }
    }

    public override bool OnTouchEvent(MotionEvent e)
    {
        if (!this._isEnabled)
            return (false);
        float x = e.GetX();
        float y = e.GetY();
        int width = this.MeasuredWidth;
        PointF point1Draw;
        PointF point2Draw;
        PointF point3Draw;
        if (this._direction == TriangularButtonDirection.Up)
        {
            point1Draw = new PointF(0, 3f * width / 4);
            point2Draw = new PointF(width, 3f * width / 4);
            point3Draw = new PointF(width / 2f, 0);
        }
        else
        {
            point1Draw = new PointF(0, 0);
            point2Draw = new PointF(width, 0);
            point3Draw = new PointF(width / 2f, 3f * width / 4);
        }
        bool test = PointInTriangle(new PointF(x, y), point1Draw, point2Draw, point3Draw);
        if (test)
        {
            base.OnTouchEvent(e);
        }
        switch (e.Action)
        {
            case MotionEventActions.Down:
                this._state = TriangularButtonState.Pressed;
                test = true;
                this.Invalidate();
                break;

            case MotionEventActions.HoverEnter:
                this._state = TriangularButtonState.Hovered;
                this.Invalidate();
                break;

            case MotionEventActions.Up:
                this._state = TriangularButtonState.Normal;
                this.Invalidate();
                break;
            case MotionEventActions.HoverExit:
                this._state = TriangularButtonState.Normal;
                this.Invalidate();
                break;
        }
        return (test);
    }

    public static bool PointInTriangle(PointF p, PointF p0, PointF p1, PointF p2)
    {
        float s = p0.Y * p2.X - p0.X * p2.Y + (p2.Y - p0.Y) * p.X + (p0.X - p2.X) * p.Y;
        float t = p0.X * p1.Y - p0.Y * p1.X + (p0.Y - p1.Y) * p.X + (p1.X - p0.X) * p.Y;
        if ((s < 0) != (t < 0))
            return false;
        float a = -p1.Y * p2.X + p0.Y * (p2.X - p1.X) + p0.X * (p1.Y - p2.Y) + p1.X * p2.Y;
        if (a < 0.0)
        {
            s = -s;
            t = -t;
            a = -a;
        }
        return s > 0 && t > 0 && (s + t) <= a;
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
        this.SetMeasuredDimension(this.MeasuredWidth, 3 * this.MeasuredWidth / 4);
    }

    public override void Draw(Canvas canvas)
    {
        int width = this.MeasuredWidth;

        PointF point1Draw;
        PointF point2Draw;
        PointF point3Draw;
        if (this._direction == TriangularButtonDirection.Up)
        {
            point1Draw = new PointF(0, 3f * width / 4);
            point2Draw = new PointF(width, 3f * width / 4);
            point3Draw = new PointF(width / 2f, 0);
        }
        else
        {
            point1Draw = new PointF(0, 0);
            point2Draw = new PointF(width, 0);
            point3Draw = new PointF(width / 2f, 3f * width / 4);
        }

        Path path = new Path();
        path.SetFillType(Path.FillType.EvenOdd);
        path.MoveTo(point1Draw.X, point1Draw.Y);
        path.LineTo(point2Draw.X, point2Draw.Y);
        path.LineTo(point3Draw.X, point3Draw.Y);
        path.LineTo(point1Draw.X, point1Draw.Y);
        path.Close();
        if (!this.Enabled)
        {
            canvas.DrawPath(path, this._paintStrokeNormal);
        }
        else
        {
            canvas.DrawPath(path, this._state == TriangularButtonState.Normal ? this._paintFillNormal : this._paintFillPressed);
            canvas.DrawPath(path, this._state == TriangularButtonState.Normal ? this._paintStrokeNormal : this._paintStrokePressed);
        }
    }
}
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <rotate
        android:fromDegrees="45"
        android:toDegrees="45"
        android:pivotX="-40%"
        android:pivotY="87%">
      <shape
          android:shape="rectangle">
        <stroke android:color="#800000" android:width="5dp" />
        <solid
            android:color="#ee9ca8" />
      </shape>
    </rotate>
  </item>
</layer-list>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true"
        android:drawable="@drawable/triangleClick" />
  <!-- pressed -->
  <item android:state_focused="true"
        android:drawable="@drawable/triangleHover" />
  <!-- focused -->
  <item android:drawable="@drawable/triangleNormal" />
  <!-- default -->
</selector>
<Button android:layout_height="70dp"
        android:layout_width="70dp"
        android:layout_gravity="center_horizontal"
        android:background="@drawable/triangleSelector"
        style="?android:attr/borderlessButtonStyle" />
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <rotate
        android:fromDegrees="45"
        android:toDegrees="45"
        android:pivotX="-40%"
        android:pivotY="87%">
      <shape
          android:shape="rectangle">
        <stroke android:color="#800000" android:width="5dp" />
        <solid
            android:color="#ee9ca8" />
      </shape>
    </rotate>
  </item>
  <item android:top="65dp" android:right="5dp" android:left="5dp">
    <shape android:shape="rectangle">
      <solid android:color="#800000" />
    </shape>
  </item>
</layer-list>
public override bool OnTouchEvent(MotionEvent e)
{
    float x = e.GetX();
    float y = e.GetY();
    int width = this.MeasuredWidth;
    PointF point1Draw;
    PointF point2Draw;
    PointF point3Draw;
    if (this._direction == TriangularButtonDirection.Up)
    {
        point1Draw = new PointF(0, 3f * width / 4);
        point2Draw = new PointF(width, 3f * width / 4);
        point3Draw = new PointF(width / 2f, 0);
    }
    else
    {
        point1Draw = new PointF(0, 0);
        point2Draw = new PointF(width, 0);
        point3Draw = new PointF(width / 2f, 3f * width / 4);
    }

    bool test = PointInTriangle(new PointF(x, y), point1Draw, point2Draw, point3Draw);
    if (test)
        base.OnTouchEvent(e);

    switch (e.Action)
    {
        case MotionEventActions.Down:
            mstate = state.pressed;
            this.Invalidate();
            break;

        case MotionEventActions.HoverEnter:
            mstate = state.hovered;
            this.Invalidate();
            break;

        case MotionEventActions.Up:
            mstate = state.normal;
            this.Invalidate();
            break;

        case MotionEventActions.HoverExit:
            mstate = state.normal;
            this.Invalidate();
            break;
    }

    return (test);
}

private state mstate = state.normal;

private enum state
{
    normal,
    pressed,
    hovered
}

public static bool PointInTriangle(PointF p, PointF p0, PointF p1, PointF p2)
{
    float s = p0.Y * p2.X - p0.X * p2.Y + (p2.Y - p0.Y) * p.X + (p0.X - p2.X) * p.Y;
    float t = p0.X * p1.Y - p0.Y * p1.X + (p0.Y - p1.Y) * p.X + (p1.X - p0.X) * p.Y;
    if ((s < 0) != (t < 0))
        return false;
    float a = -p1.Y * p2.X + p0.Y * (p2.X - p1.X) + p0.X * (p1.Y - p2.Y) + p1.X * p2.Y;
    if (a < 0.0)
    {
        s = -s;
        t = -t;
        a = -a;
    }
    return s > 0 && t > 0 && (s + t) <= a;
}

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
    this.SetMeasuredDimension(this.MeasuredWidth, 3 * this.MeasuredWidth / 4);
}

public override void Draw(Canvas canvas)
{
    int width = this.MeasuredWidth;
    switch (mstate)
    {
        case state.normal:
            Paint paintFill = new Paint(PaintFlags.AntiAlias);
            paintFill.StrokeWidth = 2;
            paintFill.Color = this.Hovered ? Color.Red : new Color(242, 180, 54);
            paintFill.SetStyle(Android.Graphics.Paint.Style.Fill);
            paintFill.AntiAlias = true;

            Paint paintStroke = new Paint(PaintFlags.AntiAlias);
            paintStroke.StrokeWidth = 2;
            paintStroke.Color = Color.White;
            paintStroke.SetStyle(Android.Graphics.Paint.Style.Stroke);
            paintStroke.AntiAlias = true;

            PointF point1Draw;
            PointF point2Draw;
            PointF point3Draw;
            if (this._direction == TriangularButtonDirection.Up)
            {
                point1Draw = new PointF(0, 3f * width / 4);
                point2Draw = new PointF(width, 3f * width / 4);
                point3Draw = new PointF(width / 2f, 0);
            }
            else
            {
                point1Draw = new PointF(0, 0);
                point2Draw = new PointF(width, 0);
                point3Draw = new PointF(width / 2f, 3f * width / 4);
            }

            Path path = new Path();
            path.SetFillType(Path.FillType.EvenOdd);
            path.MoveTo(point1Draw.X, point1Draw.Y);
            path.LineTo(point2Draw.X, point2Draw.Y);
            path.LineTo(point3Draw.X, point3Draw.Y);
            path.LineTo(point1Draw.X, point1Draw.Y);
            path.Close();

            canvas.DrawPath(path, paintFill);
            canvas.DrawPath(path, paintStroke);
            break;

        case state.hovered:
            //TODO:
            break;

        case state.pressed:
            //TODO:
            break;
    }
}