2015-06-25 7 views
6

geändert Was ich brauche zu tun: Ich brauche ein Chat-Fenster mit einem ListView in QML erstellen, die die Chat-Nachrichten speichert. Ich setze listView.positionViewAtEnd(), um den letzten Nachrichten zu folgen. Ich deaktiviere positionViewAtEnd, wenn ich nach oben scrolle, so dass ich die letzten Nachrichten lesen kann, ohne jedes Mal, wenn ich eine neue Nachricht erhalte, am Ende zu springen.Wie Listview stoppen für „springen“, wenn Modell

Das Problem: Nach dem Scrollen nach oben, erhalten Sie jedes Mal ich eine neue Nachricht, die er am Anfang Liste springt. Zu lösen, dass ich zu speichert die contentY der Liste verwalten und setzen Sie es jedes Mal, onCountChanged Handler aufgerufen wird (siehe den Code unten):

ListView { 
    id: messagesList 
    model: contact? contact.messages: [] 
    delegate: delegate 
    anchors.fill: parent 
    anchors.bottomMargin: 20 
    height: parent.height 
    anchors.margins: 10 

    property int currentContentY 

    onMovementEnded: { 
     currentContentY = contentY 
    } 

    onCountChanged: { 
     contentY = currentContentY 
    } 
    onContentYChanged: { 
     console.log(".....contentY: " + contentY) 
    } 
} 

Das Problem ist, dass, obwohl ich die letzten contentY gesetzt hatte ich , bevor das Modell geändert wurde, springt die Liste immer noch ein wenig (mehrere Pixel, nicht am Ende oder Anfang) und es springt nicht immer. Und wenn ich an die Spitze der Liste gehe und die contentY drucke bekomme ich negative Werte. Theoretisch sollte contentY am Anfang der Liste 0 sein.

Kann mir jemand sagen, was schief läuft? Oder schlagen Sie vielleicht eine andere Lösung vor, um meine Nachrichtenliste zu erstellen?

Als Sie im Voraus! :)

+0

Wie füllen Sie/ändern 'contact.messages'? – GrecKo

+0

Es ist eine Liste von C++ mit qqmllistproperty ausgesetzt. Wenn es von C++ geändert wird (nachdem eine Nachricht hinzugefügt wurde), gebe ich ein Signal aus und der Listview von qml weiß, dass sein Modell aktualisiert werden soll. –

+0

Wird dieser 'MovementEnded'-Handler konsistent aufgerufen? Niemals 'QQmlListProperty' als Modell verwendet, scheint aber [ziemlich gut] zu funktionieren (http://stackoverflow.com/a/28534291/2538363). Wie dem auch sei, eine Unterklasse von 'QAbstractListModel' würde die Arbeit hier perfekt machen. – BaCaRoZzo

Antwort

1

Warum nicht onCountChanged Steckplatz verwenden, um die ListView am Ende zu setzen?

onCountChanged: { 
    messagesList.positionViewAtEnd() 
} 
+0

Ich habe das verwendet, aber ich möchte nicht am Ende springen, wenn ich eine neue Nachricht bekomme, wenn ich nicht am Ende bin (nach oben scrollen, wenn ich in der Mitte der Liste bin) –

+0

In diesem Fall können Sie deaktivieren positionViewAtEnd() basiert auf einem Ereignis und aktiviert es für ein anderes Ereignis. Ich finde Ihre Anforderungen eher widersprüchlich. –

+0

Dies ist nicht die Antwort. Und warum ist meine Frage widersprüchlich? Nehmen Sie das Skype-Beispiel. Ich möchte etwas ähnliches erschaffen. positionViewAtEnd löst das Problem nur, wenn ich am Ende der Liste stehe! I Wenn ich in der Mitte der Liste positioniert bin, möchte ich nicht am Ende springen, ich möchte dort bleiben. –

1

Eine mögliche Lösung schould Einsatz in Listview Flickable und deaktivieren interaktive Flagge für Listview

Flickable { 
     id: fparent 
     anchors.fill: parent 
     anchors.bottomMargin: 20 
     anchors.margins: 10 

     interactive: true 
     clip: true 
     flickableDirection: Flickable.VerticalFlick 
     contentHeight: messagesList.height 

     ListView { 
      id: messagesList 
      width: parent.width 
      height: childrenRect.height 
      clip: true 
      model: contact? contact.messages: [] 
      delegate: delegate 
      interactive: false 
      onCountChanged: { 
       fparents.returnToBounds(); 
      } 
     } 
    } 
Verwandte Themen