2015-06-25 17 views
6

gì tôi cần phải làm: Tôi cần phải tạo ra một cửa sổ trò chuyện sử dụng một ListView trong QML mà các cửa hàng trò chuyện tin nhắn. Tôi đặt listView.positionViewAtEnd() để theo dõi các tin nhắn cuối cùng. Tôi vô hiệu hóa positionViewAtEnd khi tôi cuộn lên trên để tôi có thể đọc các tin nhắn trước đây mà không cần phải nhảy vào cuối mỗi khi tôi nhận được một tin nhắn mới.Làm thế nào để ngăn chặn ListView cho "nhảy" khi mô hình được thay đổi

Sự cố: Sau khi cuộn lên, mỗi lần Tôi nhận được thông báo mới, nó nhảy ở đầu danh sách. Để giải quyết mà tôi quản lý để cửa hàng contentY danh sách và thiết lập lại nó mỗi khi onCountChanged handler được gọi (xem mã dưới đây):

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) 
    } 
} 

Vấn đề là mặc dù tôi thiết lập cuối cùng contentY tôi đã , trước khi mô hình được thay đổi, danh sách vẫn nhảy một chút (nhiều pixel, không phải ở cuối hoặc đầu) và nó không nhảy luôn. Và khi tôi lên đầu danh sách và in contentY Tôi nhận được các giá trị âm. Về mặt lý thuyết, contentY ở đầu danh sách phải là 0.

Ai đó có thể cho tôi biết điều gì đang xảy ra không? Hoặc có thể đề xuất một giải pháp khác để tạo danh sách thư của tôi?

Hơn bạn trước! :)

+0

Làm thế nào để bạn cư/sửa đổi 'contact.messages'? – GrecKo

+0

Đó là danh sách được hiển thị từ C++ sử dụng qqmllistproperty. Khi nó được sửa đổi từ c + + (sau khi một tin nhắn được thêm vào) tôi phát ra một tín hiệu và listview từ qml biết để cập nhật mô hình của nó –

+0

Trình xử lý 'MovementEnded' đó có được gọi là nhất quán không? Không bao giờ sử dụng 'QQmlListProperty' làm mô hình nhưng dường như nó hoạt động [khá tốt] (http://stackoverflow.com/a/28534291/2538363). Nhưng dù sao, một phân lớp của 'QAbstractListModel' sẽ làm công việc ở đây hoàn toàn tốt đẹp. – BaCaRoZzo

Trả lời

1

Tại sao không sử dụng vị trí trênCountChanged để đặt ListView ở cuối?

onCountChanged: { 
    messagesList.positionViewAtEnd() 
} 
+0

Tôi đã sử dụng điều đó, nhưng tôi không muốn nhảy vào cuối nếu tôi nhận được bất kỳ tin nhắn mới nào khi tôi không ở cuối (cuộn lên trên, khi tôi đang ở giữa danh sách) –

+0

Trong trường hợp này bạn có thể vô hiệu hóa positionViewAtEnd() dựa trên một số sự kiện và kích hoạt nó trên một sự kiện khác. Tôi thấy yêu cầu của bạn khá mâu thuẫn. –

+0

Đây không phải là câu trả lời. Và tại sao câu hỏi của tôi mâu thuẫn? Lấy ví dụ skype. Tôi muốn làm một cái gì đó tương tự. positionViewAtEnd giải quyết vấn đề chỉ khi tôi ở dưới cùng của danh sách! Khi tôi được đặt ở giữa danh sách, tôi không muốn nhảy vào cuối, tôi muốn ở đó. –

1

Một giải pháp khả thi schould được ListView chèn vào Flickable và vô hiệu hóa tương tác cờ cho 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(); 
      } 
     } 
    } 
Các vấn đề liên quan