android - Handle custom view's different touch states -
i have custom view, extending relativelayout
, using list item in listview
. it's rectangle funky angle on left. depending on return in ontouchevent
, can end in 2 possible states:
- the list item display pressed state , return unpressed state not send click listview.
- the list item remain in pressed state (and can't out) send click listview fine.
i have never done custom views of type before appreciate advice. assume i'm missing simple, i've spent way time on @ point go on without asking questions!
here's code:
public class listitembackgroundview extends relativelayout { private final path path = new path(); private final paint brush = new paint(paint.anti_alias_flag); private static int mbackgroundcolor = -1; private static int mpressedbackgroundcolor = -1; private static int mangleoffset = -1; private boolean ispressed; public listitembackgroundview(context context) { super(context); setwillnotdraw(false); } public listitembackgroundview(context context, attributeset attrs) { super(context, attrs); setwillnotdraw(false); } public listitembackgroundview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); setwillnotdraw(false); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); final int w = canvas.getwidth(); final int h = canvas.getheight(); if (mbackgroundcolor == -1) { mbackgroundcolor = getresources().getcolor(r.color.color_1); mpressedbackgroundcolor = getresources().getcolor(r.color.color_2); mangleoffset = getresources().getdimensionpixelsize(r.dimen.list_view_angle_offset); } path.moveto(0, 0); path.lineto(mangleoffset, h * (0.35f)); path.lineto(0, h); path.lineto(w, h); path.lineto(w, 0); path.lineto(0, 0); path.close(); brush.setstyle(paint.style.fill); brush.setcolor(ispressed ? mpressedbackgroundcolor : mbackgroundcolor); canvas.drawpath(path, brush); } @override public boolean ontouchevent(motionevent event) { boolean result = super.ontouchevent(event); switch (event.getaction()) { case motionevent.action_down: ispressed = true; result = false; invalidate(); break; case motionevent.action_up: case motionevent.action_cancel: ispressed = false; result = true; invalidate(); break; } return result; } }
the solution use statelistdrawable
background.
public class listitemstatelistdrawable extends statelistdrawable { private final int mbackgroundcolor, mpressedbackgroundcolor, mangleoffset; private final path path = new path(); private final paint brush_pressed = new paint(paint.anti_alias_flag); private final paint brush = new paint(paint.anti_alias_flag); private boolean isdrawn = false; private boolean ispressed = false; public listitemstatelistdrawable(int backgroundcolor, int pressedbackgroundcolor, int angleoffset) { this.mbackgroundcolor = backgroundcolor; this.mpressedbackgroundcolor = pressedbackgroundcolor; this.mangleoffset = angleoffset; } @override protected boolean onstatechange(int[] stateset) { for(int st : stateset){ boolean pressed = st == android.r.attr.state_pressed; boolean not_pressed = st == android.r.attr.statenotneeded || st == -android.r.attr.state_pressed || st == android.r.attr.state_accelerated || st == android.r.attr.state_focused; if(pressed || not_pressed){ ispressed = pressed; invalidateself(); break; } } return super.onstatechange(stateset); } @override public void draw(canvas canvas) { if(!isdrawn){ final int w = canvas.getwidth(); final int h = canvas.getheight(); path.moveto(0, 0); path.lineto(mangleoffset, h * (0.35f)); path.lineto(0, h); path.lineto(w, h); path.lineto(w, 0); path.lineto(0, 0); path.close(); brush.setstyle(paint.style.fill); brush.setcolor(mbackgroundcolor); brush_pressed.setstyle(paint.style.fill); brush_pressed.setcolor(mpressedbackgroundcolor); canvas.drawpath(path, brush); isdrawn = true; }else { canvas.drawpath(path, ispressed ? brush_pressed : brush); } } }
Comments
Post a Comment