FLex 4.5 : strange scrolling behaviour in custom layout used in a list - apache-flex

I created a custom layout for a list, to be used on a mobile (android).
I used this as example : http://corlan.org/2011/07/11/creating-flex-mobile-lists-part-ii-using-virtualization, using virtualization.
Now the problem I have is with scrolling : when scrolling to the bottom of the list, there seems to be always a "bounce back", as if the list would have reached and as if the bounce/pull effect is taking place.
But in fact the list has not reached the end at all, in fact I can not even scroll to the last element in the list.
When going back from bottom to top, there's no problem at all.
I trace the top and bottom of the Scrolling Rectangle (Rectangle.getScrollRect) and there I can see that when scrolling down, the top and bottom parameters increase, but when releasing the touchscreen, all of a sudden the parameters decrease again with a certain amount, and so never reaching the end of the list.
All my code is available on google project hosting : http://code.google.com/p/helpdiabetes-air/source/browse/trunk/src/myComponents/TrackingViewLayout.as

solved. Double checked with the example given by Mihai Corlan
and actually I had left out one statement at the end of function measure :
layoutTarget.setContentSize(dataGroupTarget.width, totalHeight);
works fine now.

Related

Xamarin.Forms ScrollView ScrollToAsync behaviour

I have been having issues with using the ScrollToAsync function of a ScrollView when running on Android, not tested on iOS yet.
I'm using Xamarin.Forms version 2.5.1.444934 using .Net Standard
Testing on the Android Emulator (8.0, API26) and a Google Pixel (8.1 API27), both have the same issue.
I use NavigationPage and Navigation.PushAsync to move between pages (therefore have navigation bars on every page).
I want to create an auto populate field control, the user types in the first few letters and I look up the results in a database / static list of string and display the results below for the user to click/tap.
I have this working using a composite control (the contents of the frame marked interesting below).
The problem I have is scrolling the view to show the results.
My page has this layout hierarchy:-
ContentPage
StackLayout
ScrollView
StackLayout
Frame (some label and entry fields inside a stack layout)
Frame (some label and entry fields inside a stack layout)
Frame (some label and entry fields inside a stack layout)
Frame (the interesting one that deals with scrolling)
StackLayout
Heading Label
StackLayout
Label x:Name="ScrollToLabel"
Entry x:Name="ScrollToEntry"
Grid x:Name="ScrollToGrid"
Entry x:Name="Hidden" Text="I should stay visible as you type"
/StackLayout
/StackLayout
/Frame
Frame (some label and entry fields inside a stack layout)
Frame (some label and entry fields inside a stack layout)
/StackLayout
/ScrollView
StackLayout
Button Text = Done
/StackLayout
/StackLayout
/ContentPage
When the user clicks/taps in to ScrollToEntry, the keyboard opens and pans the control to above the keyboard (ok so far).
When the user starts typing in ScrollToEntry, the code populates ScrollToGrid with up to 5 results.
At this point I want to make sure that the grid results are visible for the user to tap on.
I have tried 2 different options, ScrollToAsync(ScrollToLabel, Start) and ScrollToAsync(Hidden, MakeVisible).
Neither work as I would like 100% of the time.
ScrollToAsync(ScrollToLabel, Start)
If the ScrollToEntry is at the bottom of the screen, the navigation bar is hidden and the view pans up too far.
The ScrollToLabel is now off the top of the screen.
When the second letter is clicked/tapped, the Navigation bar is restored and the scroll scrolls correctly, ScrollToLabel at the top of the screen.
If the ScrollToEntry is near the top of the screen, the navigation bar is not hidden and it scrolls correctly.
ScrollToAsync(Hidden, MakeVisible)
This is my preferred option because it would only scroll as far as needed to display all the results (not all the way to the top).
This works even worse than the first one.
In most cases, it does not scroll at all, I assume it thinks it already visible but is actually behind the keyboard?
If it does scroll, the label Hidden is still not displayed (I tested with both a HeightRequest="0" version and a visible version, both the same result).
I tried using the below code to change the adjust to resize.
Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);
2 issues,
1. Because it resizes, the Done button now is above the keyboard, taking up space.
2. When clicking the hardware back button (not the done or navigation back button) the previous view now has a white space where the keyboard was.
If using the done or navigation back, the screen initially appears with the white space but then refreshes to full screen.
I have created a sample app that highlights the issues (by default using pan, not resize).
It's the most simple version of the layout I'm using...
Am I doing something wrong or is this just how it works? If its how it works, this must be a bug? If I'm doing it wrong, can someone tell me what or suggest a different way of doing it?

Position jQuery Mobile popup allways 20 pixels below top position of visible area

I´m working on a tool only for tablets (Android, iPad) based on Cordova and jQuery Mobile (1.4.5). In the first phase of this tool, many of the users who have to work with it were asking for some more comfort regarding the behavior of the form popups.
The problem was:
As a user came to one section, I provided him with a collapsible-set, consisting of sub-sections. In this sub-sections, the user gets data-grids with Add, Edit and Delete buttons next to each data-set.
So, as the user tapped on Edit button (or Add), I opened up a popup with the necessary form and form-elements to edit this data-set or add new data to the database. But in many of the upcoming popups the amount of the form-elements is as high, so the popup appears higher or even much higher then the collapsible-set (including the data grid) behind the modal popup is.
The popup of jQuery Mobile is centered by default and even if I positionTo origin and pass x and y coordinates to it, the library/widget wants to position the popup to this coordinates by the center point, rather then the upper left corner.
Users always had to scroll around to come to the start point of the form and after submitting the form, they had to scroll up again to where they tapped on the button to open the popup.
Now I tried to do everything I could imagine, to force the popups top position to 20 pixels below the top position of the visible area on the tablet, regardless of where I am, when tapping on any Edit or Add button.
I was playing around with offset() (window.pageYOffset), etc. and set the position of the popup by:
popup2open.popup('open').css({'top':popupTopValue+'px','left':popupLeftValue+'px'});
In fact, the popup is positioned to exactly where I want it, if the top offset is between 0 and 100. On all values above 100, the top position of the popup increases by absolutely incomprehensible value. The only consistent fact is, that the more I scroll down before I tap on a button, the more this value increases - so it does not in/decrease by random.
(BTW: I found out that I have to set "popupLeftValue" to 0, so the popup is positioned in the center horizontally.)
I just can´t see any regularity on increasing value...
Can anybody give me a hint or a punch to the right direction?
Thank you in advance!
PS: I experimented also with .css({'position':'[fixed|absolute]','top':popupTopValue+'px','left':popupLeftValue+'px'}); and that worked well. Only to find out one show-stopper: If I set the focus to an input-field inside the form and than closing the virtual keyboard on the tablet, a reposition-event is triggered and by this, the popup is re-positioned massively below the former position (in fact around 300 pixels below and just marginalized to the right border of visual area). The Cancel and Save buttons are even out of scroll-able area.
(some more funny fact, btw.: if I set the focus to the same input-field, than not closing the virtual-keyboard but directly setting the focus to a select element and after this pressing the back button of the tablet to escape the select menu, no reposition-event is triggered...!?)
On 18th of July 2013 Gabriel Schulhof added this line to a feature-request from one user, who asked exactly for what I´m struggling around with:
"We are indeed considering adding such a feature..."

QDialogBox flickers

I create a custom QDialogBox class and try to display it in the centre of my window using the 'move' command. However, I am facing an issue.
The dialog box appears at a random position on the screen and then moves to the position set by me after 1 second. This happens at random instances. I open the dialog box 10 times and I do not see this flickering. However, this happens the 11th time. There is no specific pattern. Is this a performance issue? This happens more frequently on slower machines.
If I run the dialog box as loginDialog->show(); the flickering is not there. However, it happens when I use: loginDialog->exec(). How can I resolve this issue?
CustomDialog *loginDialog = new CustomDialog( this );//a QDialogBox class
float width=350,height=180;
dialogBoxPosition(&width, &height);
_mFinalPoint.setX(width);
_mFinalPoint.setY(height);
loginDialog->move(_mFinalPoint);//moving it to a window center
loginDialog->loginWindow();//calling a member function
loginDialog->exec();

GWT - PopupPanel, change layout when flipped

I'm creating a context menu for certain elements using a PopupPanel; the menu itself is going to be fairly large and complex. What I'm looking to do is to have a list of buttons, plus an image and some text, related to the element clicked.
My problem is that I'd like the buttons to always display directly under the clicked element, because that's convenient for the user; the issue is that when PopupPanel is near the edges of the screen, it automatically changes position to be fully visible, not aligning its left side to the element as usual. I like this behavior, but it moves the position of the buttons away.
So what I'd like to happen is: normally the buttons are on the left of the panel, the other stuff is to the right. When the panel is close to the right of the screen, I'd like the buttons to instead be on the right (and thus under the clicked element) and the other stuff on the left.
Is there a clever way to do this, either in GWT or better yet, using only CSS? PopupPanel itself doesn't seem to tell you when it's going to get flipped, sadly. The only solution I currently have is to manually check the position and width of the popup before showing it and adjust accordingly, but I'm hoping there's a better solution.
Here is what I suggest (based on my own implementation of a similar use case):
Have the position callback implementation accept references (in constructor) on:
PopupPanel element
element on which user right cliked
the content you put in the PopupPanel
Replicate (I know this not DRY but implementation is package private) the code from default position callback
When opening to the right invoke a method that changes the layout of your content (CSS based or otherwise)
I hope it helps. If you find something better let me know.

Making a Flex DataGrid scroll smoothly

I've noticed that the default behaviour for a DataGrid's vertical scroll bar is to scroll one row at a time. This is all well and good when the rows are all uniform and small (e.g. displaying a single line of text), but gets really ugly as soon as you have rows with variable heights.
I'm curious, is there a way to make DataGrid scrolling "smooth"? For instance, is there a way to have the DataGrid scroll by a set number of pixels, lines of text, etc. rather than scrolling one row at a time?
So far, the only solution I've managed to come up with is to place the DataGrid in a Canvas and have the Canvas do the scrolling instead of the DataGrid. The issue with this approach, though, is that as soon as the Canvas scrolls far enough, the DataGrid headers scroll off-screen. Ideally, I'd like to get the smooth-scrolling nature of the Canvas, but also keep the DataGrid headers visible. Is that possible?
The way that ItemRenderer's work in Flex 3 makes smooth scrolling difficult to achieve. Basically Flex recycles item renderers scrolled off of the top of the list as the display objects used for new data at the bottom of the list. Adobe's implementation of most list components in Flex 3 creates and adds these items as they come on to the screen rather than just off the screen, so they "pop in" and smooth scrolling isn't available. I'm not sure why they couldn't have done it in a similar manner for items +/- one position above or below the current scroll pane, but they didn't, and we're stuck with sticky scrolling by default.
Work-arounds do exist, though the one you've noted (dropping the datagrid into a canvas) negates the display-object saving intention of item renderers and incurs a performance cost. This will be fixed for most list-based Flex components in Flex 4, though it won't be fixed immediately for DataGrid. The DataGrid / AdvancedDataGrid component is maintained by a separate team based in India, last time I heard, and so it tends to be a bit behind the rest of the SDK.
I'd recommend trying something similar to this implementation of a smooth-scrolling list by Alex Harui. I'm not sure exactly how well it'd work for DataGrid or AdvancedDataGrid, but this is the most intuitive technique I can think of for making the list scroll correctly.
Try this... It's still based on Alex's code that was mentioned above. His should still be a great start for removing the snap-to-row behavior. Original source:
http://blogs.adobe.com/aharui/2008/03/smooth_scrolling_list.html
Alex's original some code for smooth vertical scrolling but that was not an issue I had with the DataGrid. It was smooth scrolling horizontally that I needed. I am using the DataGrid in an unorthodox manner for analyzing plain text reports output by our database (great way of providing visual feedback on a document). The code below allows content to go off screen and the user can scroll without that snap-to-column behavior.
You can adapt this to use the same math routines for vertical scrolling and then it will make scrolling possible and ignore the snap to row behavior. In particular switch the usage of the listContent.move method to move the contents vertically and use a inverse of the rounded pixel value you calculate from the vertical scroll bar (as opposed to my using the horizontal).
This method is bit simpler than Alex's method from the link above - a lot less code so try adapting and see how it works.
override protected function scrollHandler(event:Event):void
{
// Override the default scroll behavior to provide smooth horizontal scrolling and not the usual "snap-to-column" behavior
var scrEvt:ScrollEvent = event as ScrollEvent;
if(scrEvt.direction == ScrollEventDirection.HORIZONTAL) {
// Get individual components of a scroll bar for measuring and get a horizontal position to use
var scrDownArrow:DisplayObject = horizontalScrollBar.getChildAt(3);
var sctThumb:DisplayObject = horizontalScrollBar.getChildAt(2);
// I replaced maxHorizontalScrollPosition in Alex's code with "1300" to fix my exact application. In other situations you may finding using some property or different value is more appropriate. Don't rely on my choice.
var hPos:Number = Math.round((sctThumb.y - scrDownArrow.height) / (scrDownArrow.y - sctThumb.height - scrDownArrow.height) * 1300);
// Inverse the position to scroll the content to the left for large reports
listContent.move(hPos * -1, listContent.y);
}
// Go ahead and use the default handler for vertical scrolling
else {
super.scrollHandler(event);
}
}

Resources