Create a Button glSurfaceView in Android - android

I'm having a bit of a problem with this. I wanted to make a push button. However, I don't know how to use the Button class with OpenGL. I am not using the "R" class within Java instead I am using the old "assets" folder for compatibility.
I have it setup to find if you have touched the button and on "touch up" load the next screen. The flaw in this is that you can touch the screen and then drag your finger over to the button and then lift your finger. The next screen will load, because it has registered the touch up event at that position.
The easiest way to fix this would be to use the Button class, but how do I use it (especially because I won't be able to use findViewById)?
This is the code I was using but when onTouchUp check for a collision touchDown has magically changed to be the same as TouchUp?
private void onTouchDown(Vector2 point)
{
if (test.justUp)
{
test.setTouchDown(point);
test.justUp = false;
}
}
private void onTouchUp(Vector2 point)
{
test.setTouchUp(point);
test.justUp = true;
if(OverlapTester.pointInRectangle(test.bounds, test.touchUp) &&
OverlapTester.pointInRectangle(test.bounds, test.touchDown))
{
game.setScreen(new LevelSelect(game));
return;
}
}

When creating your own button class, register the "touch down" position and the "touch up" position. If they've both been registered inside your button graphic area, the button is pressed.

Related

PanGestureRecognizer inside ListView (Xamarin.Forms)

I'm making a messaging app in Xamarin.Forms (Android and iOS).
Messages are being shown in a ListView.
Now I want to add a new feature. When I drag the message balloon to the side, it shows the message info.
The user holds the message, drags to right or left.
If he drags enough, a new page with the info shows
If he releases before this "threshold", the balloon bounces back to its place.
I tried implementing this with a PanGestureRecognizer (PGR in this context) on the balloon, but it worked partially.
Android
I can drag, release, release before the threshold, and it works! But if I drag vertically while dragging to horizontally, the ListView "steals" the pan gesture, the PGR "forgets" it and doesn't return any event. So the balloon just keeps there, a bit to the side.
-- Initial state.
-- Dragging the message to the right
-- I've already released the message, but it is still to the right.
This doesn't happen if I release the finger without dragging down.
It may look obvious: "Why don't you just make it go back when the finger is "forgotten"?"
Because when the problem happens, it doesn't generate another event. (And the ListView doesn't have the Scrolled event as the ScrollView)
iOS
When I try to use the PGR, the ListView doesn't work. But the side drag works. Looks like the PGRs are grabbing the pan gesture always first.
Is there any way to make the PGR and the ListView work simultaneously?
For iOS you can try adding:
Application.Current.On<iOS>().SetPanGestureRecognizerShouldRecognizeSimultaneously(true)
References: https://github.com/xamarin/Xamarin.Forms/issues/2299#issuecomment-399578363
https://learn.microsoft.com/ru-ru/xamarin/xamarin-forms/platform/ios/application-pan-gesture
For Android i made a workaround with timer:
private System.Threading.Timer timer;
private void PanGesture_PanUpdated(object sender, PanUpdatedEventArgs e)
{
var statusType = e.StatusType;
if (statusType != GestureStatus.Started && timer == null)
{
// after gesture was broken down, next event will be with wrong
// status, like the gesture is continues. So, reset status to Started,
// consider it is new gesture:
statusType = GestureStatus.Started;
}
var slidingView = yourView;
switch (statusType)
{
case GestureStatus.Started:
// do any initializations..
timer = new System.Threading.Timer(_ => {
finishTranslation(slidingView);
});
break;
case GestureStatus.Running:
{
// do any animations..
timer.Change(TimeSpan.FromMilliseconds(100), TimeSpan.Zero);
}
break;
}
}
private void finishTranslation(View slidingView)
{
timer = null;
// finish your animation
}
But problem with tap gesture still here((

Solution for OnPointerExit() Triggering on Touch Release On Android?

I have created some custom radial menu buttons for my Android game. The radial menu displays when the game object with the menu is touched. I'm using mouse events to activate the menu, which works in Unity and also when built to Android. When the menu is active, you can mouse or slide over a menu item to select it. If you then release on that menu item, it will pass the selection to the radial menu, which then takes the appropriate action.
The following works in Unity:
public void OnPointerEnter (PointerEventData eventData)
{
myMenu.selected = this;
Debug.Log ("Menu selection is now: " + this.action.ToString ());
defaultColor = circle.color;
circle.color = Color.white;
}
public void OnPointerExit (PointerEventData eventData)
{
myMenu.selected = null;
Debug.Log ("Menu selection has been nulled out.");
circle.color = defaultColor;
}
However, it does not work correctly when built to Android. Via some debug testing, I've determined that in Unity, if I activate the menu and mouse over a menu item, then release the mouse, myMenu.selected is correctly assigned. However, on Android only, lifting my finger over the menu item processes a final OnPointerExit, which nulls it out, meaning that menu never gets a proper selection. The mouse does not behave this way--it doesn't treat the pointer as having exited when the mouse button is released.
I can "solve" this problem by switching everything to touch, but then I cannot test using the Unity player and my mouse. So far, everything via mouse also worked correctly via touch. This is the first issue I've run into. Is there any clean solution for this? Or is the best solution to use macros to determine if I'm in the editor and have separate mouse and touch code for each?
It depends on the behavior you trying to implement.
Touch input does not have the notion of "hover" so you should probably be using the IPointerClickHandler interface and/or the IPointerDownHandler and IPointerUpHandler interfaces instead.
I recommend separating the hover logic vs touch/click clearly by using the preprocessor directive #if UNITY_STANDALONE around your hover-code.

Titanium: How to prevent Google Maps auto panning to marker when clicking on said marker?

I'm writing a cross-platform mobile app with Titanium (v5.0.4, sdk 5.1.2GA). The app displays a map with markers for points of interest close to current location. If the user moves the map to a new region, all previously displayed markers are removed and a new set of markers is calculated and displayed, according to the new location. The user can click on a marker, and have an infoWindow appear. Clicking the infoWindow opens a new window for further informations.
This works fine on IOS (with MapKit). However, on Android (with Google Maps), clicking on a marker displays the infoWindow, but also centers the map on the marker, which triggers 'regionchanged' event, which causes my app to remove markers and display a new set. Basically, the user can never click the infoWindow nor reach the new window for further informations.
What I'd like to do: prevent Google Maps from auto panning to a marker when clicking on it.
Alternatively, is there a way to make a distinction between a 'regionchanged' event fired after clicking a marker, and a 'regionchanged' event triggered by the user moving the map? This would allow me to react only on the latter.
I've found this (Impossible to prevent auto panning to a marker when clicking on it (google maps)) but this is ruby on rails. Something else I came accross (can't find back the link, though) involved overloading the 'click' event handler or using the disableAutoPan infoWindow option (Google Maps: How to prevent InfoWindow from shifting the map), but this were all for the Javascript API.
So, has someone any idea?
I recently had the same problem. Although it's been a long time since you asked the question, I think the solution is worth noting here.
Make the map view respond to both click and regionchanged events
<View id="mapView"
module="ti.map"
onClick="click"
onRegionchanged="regionChanged"
method="createView">
</View>
Use a flag variable that both event listeners have access to.
var clicked = 0;
click event sets the variable.
var click = function(e) {
clicked = 1;
...
}
Wrap the functionality of regionchanged event with _.defer(...).
var regionChanged = function(e) {
_.defer(function(){
... (regionchanged code goes here)
});
}
regionchanged code should not execute if the variable is set.
var regionChanged = function(e) {
_.defer(function(){
if (clicked == 0) {
... (regionchanged code goes here)
}
});
}
Unset the variable at the end of the regionchanged code.
var regionChanged = function(e) {
_.defer(function(){
if (clicked == 0) {
... (regionchanged code goes here)
}
clicked = 0;
});
}
Here defer somehow makes sure when both events are fired (it seems to) regionchanged event comes after the click event. I think that may not always be the case but my tests didn't fail me yet.
And I know I could use boolean for clicked :)

How to make whole android screen (current) unresponsive while processing?

I have one activity, which contains header (title bar). This header also contains the image of Sync feature of my app.
As per requirement of client, I want that when the user tap on this button, the animation of this image (button) starts, which is rotating animation (I've achieved this animation). But while this animation is being performed, I want to freeze the whole screen so the user can not tap on other views while sync is in progress.
Till now I've used the following method but with no success :
private boolean stopUserInteractions = false;
public boolean dispatchTouchEvent(int i) {
View v = imgSync;
if (v.getId() == R.list.imgSync) {
System.out.println("UI Blocked...");
return false;
}
else {
return super.dispatchTouchEvent(ev);
}
return false;
}
Can anyone guide me for this? Any trick/snippet or any other hint.
EDIT : I dont want to use ProgressDialog while this sync process is being happening.
Have an OnTouchListener class within your activity, or let your Activity implement OnTouchListener. All children of the activity's layout should set a single object of this if they want to listen touch events. Within listener, check whether you should process the click or not.

Can I make a button appear disabled and still listen for clicks?

I'd like to gray out a button so it appears disabled to the user, but still listen for clicks so that I can display a message to the user that explains why the button isn't applicable.
I'd like to ensure that the Android API is the one configuring whatever is the appropriate standard disabled appearance as opposed to manually setting the button color to gray, etc. What's the best way to do this?
Related: Android - Listen to a disabled button
this is custom button which expose the event of touch when disabled
it working for sure, and tested. designed specific to you
public class MyObservableButton extends Button
{
public MyObservableButton(Context context, AttributeSet attrs)
{
super(context, attrs);
}
private IOnClickWhenEnabledListner mListner;
public void setOnClickWhenEnabledListener(IOnClickWhenEnabledListner listener) {
mListner = listener;
}
private interface IOnClickWhenEnabledListner {
public void onClickWhenEnabled();
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (!isEnabled() && mListner != null) {
mListner.onClickWhenEnabled();
}
}
return super.onTouchEvent(event);
}
}
this is the right way to accomplish what you want from my point of view as android developer.
there is no problem extanding all android's views, and use them on the xml files, and source instead..
good luck
You could also manually set the background of your Button to the default one for disabled. But leave the button enabled and handle the click events in the normal fashion
something like this should do it:
mBtn.setBackgroundResource(android.R.drawable.btn_default_normal_disabled);
I am not an Android expert, so there could be better ways, but what about disabling the button and overlaying a transparent view that will catch the events?
You could have the view always there laying below the button so you just need to change a z-index, or create it dynamically when needed.
If your button is on the newer types that controls color via backgroundTint rather then background, this is what you should do:
if (enabled) {
ViewCompat.setBackgroundTintList(btn, getResources().getColorStateList(R.color.button_states)); // either use a single color, or a state_list color resource
} else {
ViewCompat.setBackgroundTintList(btn, ColorStateList.valueOf(Color.GRAY));
}
// make sure we're always clickable
btn.setEnabled(true);
btn.setClickable(true);
You could also set the Button's style to look grayed out (for both pressed and non-pressed states), then setOnClickListener() as normal, but have the onClick() method give the message that it isn't clickable.
Since button extends textview. You may use the methods in textview such as .setTextColor() or .setBackgroundColor() .
Now for the the display you have 2 options:
AlertDialog - displays an alert but doesn't self close unless specified.
Toast - displays a text over a given time and self closes.
take your pick.

Categories

Resources