I developed a small Javafx application and deployed in my Android device, I have a ListView which is configured something like this:
stuboutList.setOnMouseClicked(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event) {
Dialog.show("You click the ListView!");
}
});
Here's the problem: Every time I scroll the ListView the Dialog will keep on popping.
QUESTION: How to disable setOnMouseClicked while SCROLLING?
When you scroll a ListView the swipe gesture triggers a Mouse Drag Event. You can set a flag, when the drag event is detected, and consume the following Mouse Clicked Event.
public class ScrollListener {
private BooleanProperty scrolling;
public ScrollListener(Node observableNode) {
scrolling = new ReadOnlyBooleanWrapper(false);
observableNode.addEventHandler(MouseEvent.DRAG_DETECTED, e -> scrolling.set(true));
observableNode.addEventFilter(MouseEvent.MOUSE_CLICKED, evt -> {
if (scrolling.get()) {
scrolling.set(false);
evt.consume();
}
});
observableNode.addEventHandler(MouseEvent.MOUSE_EXITED, e -> scrolling.set(false));
}
public ReadOnlyBooleanProperty scrollingProperty() {
return scrolling;
}
public boolean isScrolling() {
return scrolling.get();
}
}
Another possiblity is to you use Gluon's CharmListView, which takes care of the Mouse Click Event on its own, but (until now) is not as conveniend to use as the standard ListView, e.g. when you need to access the SelectionModel, as you can see in this question: CharmListView SelectedItemProperty?
Related
All I want is to capture when I drop ImageView on Button:
I tried to the following:
button.setOnDragOver(event -> {
System.out.println("drop");
});
button.setOnMouseDragReleased(event -> {
System.out.println("drop");
});
And nothing seems to work, any ideas?
Try The following code to create an event handler for handling event of dragging the image over the button:
button.setOnDragOver(new EventHandler() {
#Override
public void handle(final DragEvent event) {
mouseDragOver(event);
}
});
Then declare the event method which needs to be executed when event occurs
private void mouseDragDropped(final DragEvent e) {
System.out.println("drop");
}
How would I create a dialog which does not consume touch events. Ie. I want to be able to interact with the underlying activity as normal.
public class LoadingDialog extends Dialog {
public LoadingDialog(Context context) {
super(context);
setContentView(R.layout.loading_dialog);
setCanceledOnTouchOutside(false);
getWindow().setBackgroundDrawable(new
ColorDrawable(android.graphics.Color.TRANSPARENT));
}
}
I tried the following with no success
#Override
public boolean dispatchTouchEvent(#NonNull MotionEvent ev) {
return false;
}
Thanks
Rather than use a dialogue, you can use a view that covers the whole screen with a tint and another view that looks like a dialogue on top of the tint and pass all touch events to the view below. Remove and show the dialogue by toggling the visibility of the view.
When you click button in my app if you are fast enough before the screen/popup loads it loads them multiple times. I know how to disable the click on the button but that's not an option, because when you close the popup or return to the previous screen the button is disabled. I tried with Handler and Runnable to wait for 1s before the button is active again but this solution is not optimal in case if the OS needs more time to open the next screen. So I am searching for the most optimal solution. Any ideas?
Edit: setClickable(false) and then setting it back to true doesn't work because it loads my screen/popup slower than expected the button is enabled again and it opens the screen/popup multiple times again.
You can disable the multiple click at the same time using the following code
private boolean isClicked;
#Override
public void onClick(final View v) {
if(isClicked) {
return;
}
isClicked = true;
v.postDelayed(new Runnable() {
#Override
public void run() {
isClicked = false;
}
}, 1000);
}
Implement logic in your onClick to determine whether you want to ignore the click.
You can disable the button. When you close the popup enable the button and when the popup is visible make it disable. Keep listening the actions for popup and when the user get back to the previous screen.
Maintain one variable on button onClick listener and change the value to determine when you want to click button..
You can stop multiple operations by this way.
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick()
{
performOperation();
}
});
public void performOperation()
{
static boolean working = true;
if(working)
{
return;
}
working = true;
//Do you work here;
working = false;
}
I found a workaround to actually enable the ActionBar home button on the nested PreferenceScreen... however it doesn't call OnOptionsItemSelected in my PreferenceActivity. Anyone know a way to actually use the home button on a nested PreferenceScreen?
Modification of post 35 here:
http://code.google.com/p/android/issues/detail?id=4611
#Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
{
super.onPreferenceTreeClick(preferenceScreen, preference);
if (preference!=null)
if (preference instanceof PreferenceScreen)
if (((PreferenceScreen)preference).getDialog()!=null)
((PreferenceScreen)preference).getDialog().getActionBar().setHomeButtonEnabled(true);
return false;
}
I had this problem recently and this is how I solved it. Firstly to access the PreferenceScreen I use the exact same method you mentioned above.
#Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
super.onPreferenceTreeClick(preferenceScreen, preference);
// If the user has clicked on a preference screen, set up the action bar
if (preference instanceof PreferenceScreen) {
initializeActionBar((PreferenceScreen) preference);
}
return false;
}
From here I looked into what a PreferenceScreen is, and I was saddened to find out it is just wrapper of a Dialog. Moving forward, I then set the actionbar display options and attempt find the home button area. This unfortunately wasn't too easy to get, but with the help of the hierarchy viewer I managed to gain access by finding the home icon and then its parent views. Once we have access to the containing LinearLayout, we can attach an onClickListener where we dismiss the PreferenceScreen's dialog, which calls PreferenceScreen's onDismissListener and returns us to the previous screen.
/** Sets up the action bar for an {#link PreferenceScreen} */
public static void initializeActionBar(PreferenceScreen preferenceScreen) {
final Dialog dialog = preferenceScreen.getDialog();
if (dialog != null) {
// Inialize the action bar
dialog.getActionBar().setDisplayHomeAsUpEnabled(true);
// Apply custom home button area click listener to close the PreferenceScreen because PreferenceScreens are dialogs which swallow
// events instead of passing to the activity
// Related Issue: https://code.google.com/p/android/issues/detail?id=4611
View homeBtn = dialog.findViewById(android.R.id.home);
if (homeBtn != null) {
OnClickListener dismissDialogClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
};
// Prepare yourselves for some hacky programming
ViewParent homeBtnContainer = homeBtn.getParent();
// The home button is an ImageView inside a FrameLayout
if (homeBtnContainer instanceof FrameLayout) {
ViewGroup containerParent = (ViewGroup) homeBtnContainer.getParent();
if (containerParent instanceof LinearLayout) {
// This view also contains the title text, set the whole view as clickable
((LinearLayout) containerParent).setOnClickListener(dismissDialogClickListener);
} else {
// Just set it on the home button
((FrameLayout) homeBtnContainer).setOnClickListener(dismissDialogClickListener);
}
} else {
// The 'If all else fails' default case
homeBtn.setOnClickListener(dismissDialogClickListener);
}
}
}
}
I have a TabActivity with 2 tabs that contain a control that responds to Scale and Scroll events.
When I fire up my app to begin with it starts on Tab 1 and I can scale and scroll the view shown on the 1st Tab's activity.
When I switch to Tab 2 again I can scale and scroll the view shown on the 2nd tab's activity.
All looks good.
When I switch back to the 1st tab suddenly I can no longer scale or scroll. If i switch back to the 2nd again then that one works fine. Its as if the touch focus is being taken by the view on the 2nd tab and never being surrendered.
I've even tried re-initialising my GestureDetectors in case they somehow get destroyed when one Activity gets backgrounded.
I've tried the following code to no avail:
public void onPause()
{
super.onPause();
mView.clearFocus();
}
public void onResume()
{
super.onResume();
mView.requestFocus();
mView.InitGestureDetectors( this );
}
Where InitGestureDetectors simply does the following:
public void InitGestureDetectors( Context ctx )
{
mScaleGestureDetector = new ScaleGestureDetector( ctx, new ScaleGestureListener() );
mGestureDetector = new GestureDetector( ctx, new GestureListener() );
}
Can anyone tell me how I can get my touch gestures working again when i subsequently switch tabs?
I've eventually tracked down the source of my problems. This was being caused by a custom OnTabChangeListener used to create a transition animation when you change tabs. This caused, for some reason, the visibility state to not get set to GONE when a view moved into the background. So i added a custom AnimationListener to set the visibility flag appropriately in onAnimationEnd and onAnimationStart.
outAnim.setAnimationListener( new Animation.AnimationListener()
{
public void onAnimationEnd( Animation animation )
{
outView.setVisibility( View.GONE );
}
public void onAnimationRepeat( Animation animation )
{
}
public void onAnimationStart( Animation animation )
{
inView.setVisibility( View.VISIBLE );
}
} );
and now my touch events are being handled as I would expect!