How can I create a custom button like this?
It should be just clickable area not a real button.
I use a crapload of irregular shaped buttons on my app, and to change the "hot zone" or "clickable area" of the button, I just use the Bitmap.getPixel() method to check for alpha on the image used. If the method returns 0, then don't perform click event.
Example:
(1) Create your button as usual, whichever way you would like.
(2) Define a Bitmap and assign to it the same image drawable used for the button.
(3) Get the X and Y coordinates of the touch or click action.
(4) Pass the coordinates to the .getPixel(x,y) method.
Sample Code:
// ** Declare your Bitmap somewhere **
final Bitmap TheBitmap;
TheBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.TheImage);
// ** My onTouch code **
public boolean onTouch(View v, MotionEvent event) {
int eventPadTouch = event.getAction();
switch (eventPadTouch) {
case MotionEvent.ACTION_DOWN:
if (iX>=0 & iY>=0 & iX<TheBitmap.getWidth() & iY<TheBitmap.getHeight()) { // ** Makes sure that X and Y are not less than 0, and no more than the height and width of the image.
if (TheBitmap.getPixel(iX,iY)!=0) {
// * A non-alpha area was clicked, do something
}
}
return true;
}
return false;
}
The event.getX() and event.getY() simply give you the coordinates of where you touched the button.
** The above sample is to guide you in the correct direction. There are some checks to add to the code to assure no errors occur.
ceate using your own canvas or make a image using photoshop like this and then using Bitmap.createScaledBitmap scale it according to dimension of your button and hence you will get this button.
using canvas you have to write more code just do this it will work fine
Simply just create an image like that and you can use either ImageView or Button w/o text, and implement an OnClickListener. It just works!
save that as a png and and put it in your drawables folder. Then in your xml use something like this
<Button
android:height="wrap_content"
android:width="wrap_content"
android:background="#drawable/your_png"
/>
I am not 100% positive that the corner cut out is going to work properly. That corner area that is gone may end up being clickable. If that is the case and if you don't want it to be then you'll have to slice your picture in half somewhere create two buttons that you can set next to each other to make up that shape and use the same click listener for both. From the users perspective it will still seem like one button.
Related
I'm having troubles with a transparent button background. I have a 90 degree triangle with the second side transparent. The problem I'm facing is that you can activate the image button by pressing on the transparent side. is there anyway to limit it through the first side? Thanks.
ps: I'm sorry i'm new to all this.
You can achieve that by setOnTouchListener for your button (not OnClick) then you can calculate the onRawX and onRawY then compare the values if it's on your sensitive region do your work else ignore.
Yes it is possible, but you have to do it manually. It means you should build your own View class and override public boolean onTouchEvent(MotionEvent event) method. and then calculate if the x and y coordinates mathces your region.
My parent view is a RelativeLayout, I added a triangle to it extending the View class. I draw the triangle using canvas and paint. The problem i am facing is that, when i touch on the relative layout, both touch listeners , the relative layout and triangle are being triggered. I just want the triangle to take the exact space as it requires. How can i limit my customview , triangle in this case to take it's space, rather than occupying the entire parent layout.
Actually my requirement is: i have one relative layout on the layout i am adding some custom views dynamically. those have touch listeners for for dragging points in the triangle,but those are taking full screen of my parent view, because of that i am unable to trigger touch listeners separately for parent and child view's.
I've spent countless hours developing solutions for this problem and I just couldn't get my head around it. Any help would be greatly appreciated.
From what I am gathering you are saying,you have a triangle drawn within a RelativeLayout in a CustomView. The actual View size is FILL_PARENT for both width and height. So the square representing the touchable area of the triangle is the same as the square representing the touchable area of the parent RelativeLayout.
You would like touch events inside the triangle's drawn area to be received by the triangle View and anything outside to be received by the parent. It is not possible to define a custom touch area from what I understand.
That doesn't stop you manipulating drawing bounds and touch focus to accomplish what you want though.
How it can be done
Ensure that your CustomView with the triange always receives the touch event. When it receives the touch event, it perform basic maths to figure out if the touch was within your triangle area (you must have your triangle bounds you use to draw your triangle saved as global variables for the CustomView).
Then a simple conditional statement to determine whether to act on and consume or pass the event on (do you even want a TouchEvent on your RelativeLayout to do anything? If not that makes this a lot easier).
Example code skeleton:
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean inTriangle = false;
float x = event.getX();
float y = event.getY();
// This really depends on what behaviour you want, if a drag extends outside the
// triangle bounds, do you want this to end the touch event? This code could be done
// more efficiently depending on your choices / needs
// Do maths to figure out if the point is actually inside the triangle. Once again,
// many solutions and some much easier than others depending on type of triangle
// This flow will only register events in the triangle, and do nothing when outside
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (inTriangle) {
// Do whatever it is you want to do
return true; // to say you consumed the event if necessary
} else {
return false; // parent RelativeLayout should now get touch event
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (inTriangle) {
// Do whatever it is you want
return true;
} else {
// Do nothing
return true; // So is stil consumed
}
}
return true;
}
To be honest, the question is way to open-ended / unclear to give anything more specific. But this is how you would accomplish what you asked. Just apply it to your specific scenario.
Note: I have encountered issues with TouchEvent passing, so if you really do want to pass them to specific places, you may have to investigate toying with View.dispatchTouchEvent() if the order your Touches are being processed becomes an issue.
You have an issue to handle the touch events of the triangle because you are getting touch on both the view RalativeLayout and Your customview.
To solve this issue you have to do some changes in the customview's onTouchEvent.
Like If you are touching on the customview and if you want to handle the event then from onTouchEvent you will have to return true instead of false so that your parent view will not get the touch events.
A B C D
E F G H --figure.
I am working on Book App on Android. In my book App, there are many images-pages. In first image-page there are 26 alphabets(A-Z),4 alphabets in a raw(as shown in my picture).
My Problem is:
I want to developed a click-able area for each and every alphabets (A-Z) . when user click or touch on any of alphabet then a square box should be appear like "image A is clicked"(shown in above figure).
On every touch or click on alphabets images(A-Z) i will pass corresponding sound. Means i want to call different-different Listeners for different-different area on a single image-page.
i have no idea about how to implement click-able area on an image which click able area or coordinates doesn't vary emulator to emulator.
please provide me some sample code or an idea or reference link.
Thank in Advance
I remember answering a very similar question just a few days ago. In order to implement this as the image, you'll need to know what areas of the image mean what (i.e. if you get coordinates of of a touch event, which action these coordinates would correspond to). Provided you have this info, you can then register OnTouchListener with your ImageView:
imageView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch (View v, MotionEvent event) {
int x = event.getX();
int y = event.getY();
//now deal with coordinates (x, y)
}
});
However in your case, I would suggest using a layout with 26 buttons and just use OnClickListener with each of them. You can easily set the buttons up in the shape you want and you can easily set individual background drawables to them to make it look as one whole image.
I have a activity where I have two imageViews. In onTouch I recognize which imageView was clicked. Now I have a question. How I can draw new very small image in place where I clicked. I know that onTouch i have getX() and getY() and I save this position when I touch the screen, but I don't know how I can draw image in place where I clicked. My image is in drawable resources. I need to use canvas or is better way. I need draw this picture and after that I need run animation this image.
edit1: How can I set positionX and positionY my image. I have position where I click but I don't know how I can set image in this coordinates.
you should have a image view with visible attribute of FALSE and after touch (or any event you want) set three attribute : visible = true; x = getX() and y = getY();
is it enough or explain more?
I see the following approach.
Replace the ImageView by a custom view derived from ImageView.
Override onDraw.
call super.onDraw to draw the image
paint your image using onDraw's canvas at the last touch position.
each time you get a touch, you need to invalidate the custom view
I would like to produce an android user interface which allows the user to move added components/widgets around the screen by selecting them and then dragging them around.
Is this possible using the standard android apis?
Yes. It depends what you are trying to achieve.
It can be done using the standard APIs, but this functionality is not part of the standard APIs. That is, there is no widget.DragOverHere() method unless you write one.
That said, it would not be terribly complicated to do. At a minimum, you would need to write a custom subclass of View and implement two methods: onDraw(Canvas c) and onTouch(MotionEvent e). A rough sketch:
class MyView extends View {
int x, y; //the x-y coordinates of the icon (top-left corner)
Bitmap bitmap; //the icon you are dragging around
onDraw(Canvas c) {
canvas.drawBitmap(x, y, bitmap);
}
onTouch(MotionEvent e) {
switch(e.getAction()) {
case MotionEvent.ACTION_DOWN:
//maybe use a different bitmap to indicate 'selected'
break;
case MotionEvent.ACTION_MOVE:
x = (int)e.getX();
y = (int)e.getY();
break;
case MotionEvent.ACTION_UP:
//switch back to 'unselected' bitmap
break;
}
invalidate(); //redraw the view
}
}
To some degree. It depends on what degree of freedom you want to give the user. One solution that comes to mind is a TableLayout with predefined cells. A user can then tap and drag components. When dragging a component you'll just want to draw an image of it under the user's finger, but when they release, remove the component from it's previous parent and add it to the new parent using the ViewGroup add/remove methods.
While you can programmatically shift Views around, it would be difficult/impossible to switch layouts on the fly as far as I can see.
The way I have done this is to have an absolute layout and then just update the object position as it is dragged. You have to implement dragging yourself. If the widgets have a natural order (a toolbar where you want to be able to drag buttons around) you can stack an absolute layout on top of the toolbar and when the drag starts, you add it to the absolute layout and when it finishes, you add it back to the original layout in the new position.