首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使Flickable确保项目在其中的可见性?

如何使Flickable确保项目在其中的可见性?
EN

Stack Overflow用户
提问于 2017-08-30 03:06:56
回答 2查看 2K关注 0票数 3

我有一个Flickable,它在一列中包含大量的TextField对象,每个TextField都锚定在前一个TextField的底部。一切都很好,除了当我使用Tab键在这些字段中导航时,最终焦点转到Flickable的可见矩形之外的TextField,然后用户在手动向下滚动可闪烁之前看不到光标。

本质上,我寻找的是某种".ensureVisible()“方法,这样当TextField接收到焦点时,Flickable就会自动滚动,这样刚刚聚焦的TextField就完全可见了。

EN

回答 2

Stack Overflow用户

发布于 2017-08-30 04:40:43

你有没有考虑过一种更符合模型的方法?我的意思是,如果你使用像ListView这样的东西,你可以简单地改变currentItem,当它超出可见范围时,视图将自动滚动到它。

此外,它将只加载可见范围内的文本元素,从而节省一些内存。

但是,即使使用您当前的方法,确保可见性也不会那么复杂。

代码语言:javascript
复制
  Flickable {
    id: flick
    anchors.fill: parent
    contentHeight: col.height
    function ensureVisible(item) {
      var ypos = item.mapToItem(contentItem, 0, 0).y
      var ext = item.height + ypos
      if ( ypos < contentY // begins before
          || ypos > contentY + height // begins after
          || ext < contentY // ends before
          || ext > contentY + height) { // ends after
        // don't exceed bounds
        contentY = Math.max(0, Math.min(ypos - height + item.height, contentHeight - height))
      }
    }
    Column {
      id: col
      Repeater {
        id: rep
        model: 20
        delegate: Text {
          id: del
          text: "this is item " + index
          Keys.onPressed: rep.itemAt((index + 1) % rep.count).focus = true
          focus: index === 0
          color: focus ? "red" : "black"
          font.pointSize: 40
          onFocusChanged: if (focus) flick.ensureVisible(del)
        }
      }
    }
  }

解决方案是快速而粗糙的,但将其投入生产是微不足道的。映射到contentItem而不是flickable很重要,因为后者会给出错误的结果,并考虑到当前滚动量。使用映射将使解决方案与您可能使用的任何定位方案无关,并且还将支持任意级别的嵌套对象。

票数 3
EN

Stack Overflow用户

发布于 2019-05-07 20:17:04

dtech的回答恰到好处。它很容易与一个很好的snap-to动画结合在一起,也很容易为x方向的flickables进行修改。此外,用户可能故意轻弹或拖动可闪烁对象。在我的例子中,C++代码控制网格布局中包含在flickable中的项的文本或显示效果。当C++代码指示flickable这样做时,flickable需要很好地闪烁,但如果用户故意拖动或闪烁,则不需要。以下是dtech的函数针对x方向的flickable进行了修改:

代码语言:javascript
复制
function ensureVisible(item) {
    if (moving || dragging)
        return;
    var xpos = item.mapToItem(contentItem, 0, 0).x
    var ext = item.width + xpos
    if ( xpos < contentX // begins before
              || xpos > contentX + width // begins after
              || ext < contentX // ends before
              || ext > contentX + width) { // ends after
        // don't exceed bounds
        var destinationX = Math.max(0, Math.min(xpos - width + item.width, contentWidth - width))
        ensureVisAnimation.to = destinationX;
        ensureVisAnimation.from = contentX;
        ensureVisAnimation.start();
    }
}
//This animation is for the ensure-visible feature.
NumberAnimation on contentX {
    id: ensureVisAnimation
    to: 0               //Dummy value - will be set up when this animation is called.
    duration: 300
    easing.type: Easing.OutQuad;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45946637

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档