c# - Triangle button android click / hovered -




i have created triangular button in android. works well. want change fill color / stroke color when button hovered / pressed (like in default button).

i try invalidate view when hovered property changed , change color in ondraw method without success.

this code:

public enum triangularbuttondirection {     = 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 = 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 = -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;         }         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);     } } 

edit : final code

    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 = 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     {         => 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 = -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;         }         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);         }     } } 

thanks help

yes, use xamarin.android. can customize button can't have desired result. triangle border not possible style file...

just code, think "triangle border" means triangle button stroke, can create drawable resource file, example, create 3 drawable normal, pressed , hovered state:

normal(the code triangle shape comes this blog):

<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> 

the code "pressed" , "focused" state same, changed color of stroke , solid.

then can apply drawable selector this:

<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> 

finally use selector this:

<button android:layout_height="70dp"         android:layout_width="70dp"         android:layout_gravity="center_horizontal"         android:background="@drawable/triangleselector"         style="?android:attr/borderlessbuttonstyle" /> 

checked result of demo (state order is: normal->pressed->hovered):

enter image description here

update:

you can 3 sides stroked this:

<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> 

you can calculate margin make more beautiful, it's idea add item layer.

update 2:

besides method wrote in comments, continue work doing in custom button class, can code example this:

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 = -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;     }     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;     } } 




wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

python - Read npy file directly from S3 StreamingBody -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -