[Qt Quick 2.0 (qml) - Android]
I searched but I don't get how one can increase the velocity of the scrolling in a listview:
ListView {
width: 180; height: 200
Component {
id: contactsDelegate
Rectangle {
id: wrapper
width: 180
height: yeah.height
Column{
id:yeah
Text {
id: contactInfo
text: name + ": " + number
}
Image{
source: jpgsrc
}
}
}
}
model: ContactModel {}
delegate: contactsDelegate
focus: true
}
Question
Say my ContactModel has 200 elements. My problem is that the scrolling speed over those elements is too slow. It takes too long to scroll the whole list.
I would like to know how to modify that code to make the scrolling experience faster (at least with a higher velocity).
Thanks
To improve speed of scrolling you can play with 2 ListView properties: cacheBuffer and maximumFlickVelocity.
maximumFlickVelocity directly impacts speed whereas cacheBuffer should be updated if you have speed issues due to slow dynamic loading of ListView elements.
Related
I'm trying to make a react-native scrollview with 3 (or more) elements where the element in the middle of the screen is always 1.75 times the normal element size, and while scrolling the size changes dynamically. Can I find when the element is in the center of screen if the size of the scrollview will be changing? Is it possible to do without some complicated mathematical approach?
I was trying putting conditions to all elements' styles but can't find a way to determine when the condition is met.
handleScroll(event) {
var x = event.nativeEvent.contentOffset.x;
var page = x / this.state.totalWidth;
this.setState({ position: page })
}
isElementFocused(start, stop) {
return (this.state.position >= start && this.state.position < stop);
}
Element:
<View style={styles.swipeBox,
{
backgroundColor: this.isElementFocused(1, 2) ? this.getColor(1) : colors.primary,
width: this.isElementFocused(1, 2) ? this.getWidth(1) : this.state.baseWidth,
height: this.isElementFocused(1, 2) ? this.getHeight(1) : this.state.baseHeight,
}}>
<Text>test</Text>
</View>
I think you want to use smoothScrollToPosition()
please visit https://www.programcreek.com/java-api-examples/?class=android.support.v7.widget.RecyclerView&method=smoothScrollToPosition
Anyone knows how to change the speed of the scroll animation in ScrollToAsync method for Xamarin.Forms.ScrollView control?
I'm developing an Android App with Xamarin Forms.
Thanks
Unfortunately, at the time of this writing, the ScrollToAsync speed is hardcoded to 1000 ms (at least for Android).
I was able to work around this by just animating the scroll myself:
Point point = scrollView.GetScrollPositionForElement(targetElement, ScrollToPosition.Start);
var animation = new Animation(
callback: y => scrollView.ScrollToAsync(point.X, y, animated: false),
start: scrollView.ScrollY,
end: point.Y - 6);
animation.Commit(
owner: this,
name: "Scroll",
length: 300,
easing: Easing.CubicIn);
And here's the documentation for animation.
Modified from Taylor Lafrinere's answer, here is the same snippet as a horizontal scroll animation:
Point point = scrollView.GetScrollPositionForElement(screenContent, ScrollToPosition.Start);
// insert fix for iOS jumping here
var animation = new Animation(
callback: x => scrollView.ScrollToAsync(x, point.Y, animated: false),
start: scrollView.ScrollX,
end: point.X);
animation.Commit(
owner: this,
name: "Scroll",
length: 300,
easing: Easing.CubicIn);
It is worth pointing out that on iOS, this code displaced the view also towards the top. Something which you do not want. I believe the reason for this is that iOS understands the input for the animation as the lower edge of the scrollview whereas Android understands it as the upper edge of the scrollview.
To avoid this jump, set point.Y to 0 on iOS:
// iOS seems to understand the input for the animation as the lower edge of the scrollview
// Android the upper edge.
if (Xamarin.Forms.Device.RuntimePlatform == Xamarin.Forms.Device.iOS)
{
point.Y = 0;
}
I still think this answer should have been an edit, but since it was rejected as "Should be an answer or a comment" and it certainly cannot be a comment, here it is as an answer. The intent is to make it more clear that Taylor's Answer covers the vertical animation, and to show how to do a horizontal one instead.
To simulate the increase of speed of AsyncToScroll I've used the FadeTo method of scrollview and set the parameter "animated" of AsyncToScroll to false. (My example is for an horizontal scrollview)
await MyScrollView.FadeTo(1, 200, Easing.CubicIn);
await MyScrollView.ScrollToAsync(_newScrollX_value, 0, false);
Part of my game includes a table in which there is a ball rotating. There are also two rectangles like rackets that a player can use for the game. At first I used a simple rectangle with a mouse area filling the racket and some drag properties. It was somewhat fine when I ran the program on my Desktop but on Android devices, touching (i,e. by finger) the rackets is:
hard making the game unpleasant and also moving the rackets affects
the movement of the ball!
So I searched the Web and faced MultiPointTouchArea. So I tried to use it in both rackets with that hope it solves the issues.
I used this code:
import QtQuick 2.9
Rectangle {
id: root
width: 15; height: 65
property int oldY: y
property bool yUwards: false
property bool yDwards: false
onYChanged: {
if(y > oldY) yDwards = true
else if (y < oldY) yUwards = true
oldY = y
}
MultiPointTouchArea {
anchors.fill: root
mouseEnabled: true
minimumTouchPoints: 1
maximumTouchPoints: 1
touchPoints: [
TouchPoint { id: root }
]
drag.target: root
drag.axis: Drag.YAxis
drag.minimumY: table.y
drag.maximumY: table.height - height - 10
}
}
But there are errors like:
qrc:/Racket.qml:22 id is not unique
I mean, what is the correct use of that method for the rackets, please?
While testing out an application on Android I noticed something funky going on. A double click event handler has been triggering without any double clicks occurring on that particular item.
Trying to isolate the issue I discovered that pretty much every chain of clicks rapid as a double click on regardless what two objects would cause the second click on the second object to register as a double click, when in fact it is just a single click.
Below is an example consisting of a row of 3 randomly colored rectangles, each one with a mouse area inside of it. The double click of each mouse area is rigged to set the parent rectangle's color to a different random color. Clicking rapidly two different rectangles under android triggers a double click and a color change for the second. This does not happen on Windows or Ubuntu Linux.
Window {
id: main
visible: true
width: 400
height: 400
title: qsTr("Hello World")
Row {
Rectangle {
width: main.width * .33
height: main.height
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
border.width: 2
MouseArea {
anchors.fill: parent
onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
Rectangle {
width: main.width * .33
height: main.height
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
border.width: 2
MouseArea {
anchors.fill: parent
onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
Rectangle {
width: main.width * .33
height: main.height
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
border.color: "black"
border.width: 2
MouseArea {
anchors.fill: parent
onDoubleClicked: parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
}
}
It looks as if the "previous click" or whatever property that's supposed to be used to detect double clicks is shared between different mouse areas instead of being per mouse area. The issue manifests in both Qt 5.7 and 5.7.1.
It definitely looks like my 10th discovered Qt bug this year, but I still feel like asking on the odd chance someone knows what's going on and how to fix it, because I need this fixed, and the Qt bugreport process is not speedy. So any ideas are more than welcome.
Until there is a better answer with an actual solution, it may be useful to know that it is possible to somewhat mitigate the devastating effect this issue has on user experience by reducing the global interval for double click detection.
By default it is the rather lethargic 500 msec. I found out that by reducing it to 250 msec helps to avoid over 90% of the incorrect double clicks:
QGuiApplication app(argc, argv);
app.styleHints()->setMouseDoubleClickInterval(250);
Additionally, there is a quick and hacky qml-only way to create a "fixed" copy of MouseArea:
// MArea.qml
Item {
id: main
property alias mouseX : ma.mouseX
property alias mouseY : ma.mouseY
property alias acceptedButtons: ma.acceptedButtons
// etc aliases
signal clicked(var mouse)
signal doubleClicked(var mouse)
// etc signals, function accessors
MouseArea {
id: ma
property real lClick : 0
anchors.fill: parent
onClicked: {
var nc = Date.now()
if ((nc - lClick) < 500) main.doubleClicked(mouse)
else main.clicked(mouse)
lClick = nc
}
}
}
This one actually works as intended and can be made almost entirely "plug and play" compatible with the original one.
I have a requirement where I display a WebView with a checkbox beneath it. The checkbox is initially in disabled state. Only when the user scrolls down to the bottom of the webview , the checkbox is enabled. I do this by extending Webview class and writing my onScrollChanged listener as below:
#Override
protected void onScrollChanged(int left, int top, int oldLeft, int oldTop) {
if ( (getContentHeight() - (top + getHeight())) <= mMinDistance )
{
Log.i("MYACT","content height: "+getContentHeight()+" top: "+top+" Height: "+getHeight()+" minDistance: "+mMinDistance);
Log.i("MYACT", "Reached bottom");
mOnBottomReachedListener.onBottomReached(this);
}
else{
Log.i("MYACT","content height: "+getContentHeight()+" top: "+top+" Height: "+getHeight()+" minDistance: "+mMinDistance);
Log.i("MYACT", "Not at bottom");
mOnBottomReachedListener.onNotAtBottom(this);
}
super.onScrollChanged(left, top, oldLeft, oldTop);
}
The problem is the condition
(getContentHeight() - (top + getHeight())) <= mMinDistance) //mMinDistance is 0 in my case
is satisfied even before i scroll down to the bottom of the page. As you can see, I tried printing the values of each in log and found that the parameter "top" sometimes exceeds the value "getContentHeight".
Sample log values:
08-14 11:28:19.401: I/MYACT(1075): content height: 3020 top: 3861
Height: 416 minDistance: 0
How can i make avoid this scenario in this case? Should i use a different way of checking whether i have scrolled down to the bottom of the page?
Thanks
I found the issue with this after some research. Webview usually scales the web page based on the screen size and then renders it. It usually zooms the page so that it doesn't look too small in the phone. You can get this scale factor by using the method getScale()
So, in my case, i would use the following condition to check whether end of page has been reached
(getContentHeight()*getScale() - (top + getHeight())) <= mMinDistance)
//mMinDistance is 0 in my case
If memory serves values returned by getContentHeight() may depend on implementation of a WebView and its rendering mode (software/hardware). But I'm not sure. Perhaps this talk at Google IO will help you more in this question.
But generally speaking it's always hard and tricky to mix WebView with other views, especially when it comes to scrolling.
So my advice would be to put your checkbox into HTML displayed by the WebView. You have pretty much options of doing that like injecting some additional HTML code before passing it to loadData() method or invoking JavaScript with loadUrl("javascript:whatever();"), which can modify the initial DOM structure.
As a rule I do not put other views to Activity window when I have to deal with a WebView there.