2014-05-21 176 views
0

我想创建水平滚动图像。如果你看到“黑莓旅行”应用程序,在这个应用程序的顶部图像动态滚动。我想创建相同的滚动视图。同样在图片的底部,我们可以看到圈子。随着图像变化,特定的圆圈变暗。这个滚动有两种方式意味着它及时滚动,并通过点击鼠标滚动。 所以,请帮我创建这样的滚动。我刚来这地方。谢谢...水平滚动图像

+0

有没有谁知道这个问题的答案吗? – GoNish

+0

自从你提出这个问题以来,我一直在考虑这个问题。这是一个相当简单的概念,但提出一个干净的实施将需要一些周密的计划。我想你想要的是两个自定义控件。一个将通过滑动手势处理滚动图像的功能,可将中心和所有其他预期行为提供给中心。第二个自定义控件将提供“点”UI并接受触摸和滑动手势。然后这两个控件将与信号和插槽进行通信。也许是提供图像的数据模型对象。我会看到我可以放在一起。 – Richard

+0

理查德,我已经通过ListView与xmldatamodel尝试过它,但我无法创建“点”和他们正确的工作。 – GoNish

回答

1

这是一个基于Container的自定义控件,它提供了一排圆圈/点选择范例。出于演示目的,我不保证能够捕捉到所有错误条件等。具体而言,计算选择哪个索引项目的数学计算有点偏离,因为默认情况下,容器不会在每一端放置足够多的空间它在两个项目之间做。我不得不离开你做点什么;)

您还将必须提供选定和取消选择表单的图像,但这并不困难。

下面是类的定义:

/* 
* ScrollGadget.hpp 
* 
* Created on: May 22, 2014 
*  Author: richard 
*/ 

#ifndef SCROLLGADGET_HPP_ 
#define SCROLLGADGET_HPP_ 

#include <QObject> 
#include <bb/cascades/Container> 
#include <bb/cascades/ImageView> 
#include <bb/cascades/Layout> 
#include <QUrl> 

using namespace bb::cascades; 

namespace net 
{ 
    namespace test 
    { 

     class ScrollGadget : public Container 
     { 
      Q_OBJECT 

      Q_PROPERTY(int selectedIndex READ selectedIndex WRITE setSelectedIndex NOTIFY selectedIndexChanged) 
      Q_PROPERTY(int itemCount READ itemCount WRITE setItemCount NOTIFY itemCountChanged) 

     public: 
      ScrollGadget(Container *parent = 0); 
      virtual ~ScrollGadget(); 

      int selectedIndex() const; 
      int itemCount() const; 

     public slots: 
      void setSelectedIndex(int index); 
      void syncSelectedIndex(int index); 
      void setItemCount(int count); 


     private slots: 
      void onTouch(bb::cascades::TouchEvent*); 
      void handleLayoutFrameUpdated(QRectF); 

     signals: 
      void selectedIndexChanged(int selectedIndex); 
      void itemCountChanged(int count); 

     private: 
      int mSelectedIndex, mItemCount, mSaveIndex; 
      qreal mWidth, mHeight; 
      QUrl mSelected, mDeselected; 
      ImageView **mImageView; 
     }; 

    } /* namespace test */ 
} /* namespace net */ 

#endif /* SCROLLGADGET_HPP_ */ 

而C++源:

/* 
* ScrollGadget.cpp 
* 
* Created on: May 22, 2014 
*  Author: richard 
*/ 

#include <QDebug> 
#include <src/ScrollGadget.hpp> 
#include <bb/cascades/TouchBehavior> 
#include <bb/cascades/TouchType> 
#include <bb/cascades/PropagationPhase> 
#include <bb/cascades/TouchResponse> 
#include <bb/cascades/StackLayout> 
#include <bb/cascades/LayoutOrientation> 
#include <bb/cascades/LayoutUpdateHandler> 


using namespace bb::cascades; 

namespace net 
{ 
    namespace test 
    { 

     ScrollGadget::ScrollGadget(Container *parent) : Container(parent), 
       mSelectedIndex(0), 
       mItemCount(0), 
       mSaveIndex(0), 
       mWidth(0), 
       mHeight(0), 
       mSelected("asset:///active.png"), 
       mDeselected("asset:///inactive.png"), 
       mImageView(NULL) 
     { 
      qDebug() << __PRETTY_FUNCTION__; 

      setLayout(StackLayout::create().orientation(LayoutOrientation::LeftToRight)); 

      addTouchBehavior(
       TouchBehavior::create() 
        .addTouchReaction(TouchType::Down, 
             PropagationPhase::AtTarget, 
             TouchResponse::StartTracking)); 

      LayoutUpdateHandler::create(this) 
        .onLayoutFrameChanged(this, SLOT(handleLayoutFrameUpdated(QRectF))); 


      bool c = this->connect(this, SIGNAL(touch(bb::cascades::TouchEvent*)), this, SLOT(onTouch(bb::cascades::TouchEvent*))); 
      Q_ASSERT(c); 
      Q_UNUSED(c); 
     } 

     ScrollGadget::~ScrollGadget() 
     { 
      if (mImageView) { 
       delete mImageView; 
      } 
     } 

     int ScrollGadget::selectedIndex() const { 
      return mSelectedIndex; 
     } 

     int ScrollGadget::itemCount() const { 
      return mItemCount; 
     } 

     void ScrollGadget::setSelectedIndex(int index) { 
      if (index != mSelectedIndex && index >= 0 && index < mItemCount) { 
       syncSelectedIndex(index); 
       emit selectedIndexChanged(mSelectedIndex); 
       qDebug() << "selectedIndexChanged(" << mSelectedIndex << ")"; 
      } 

     } 

     void ScrollGadget::syncSelectedIndex(int index) { 
      if (index != mSelectedIndex && index >= 0 && index < mItemCount) { 
       mImageView[mSelectedIndex]->setImageSource(mDeselected); 
       mSelectedIndex = index; 
       mImageView[mSelectedIndex]->setImageSource(mSelected); 
      } 
     } 

     void ScrollGadget::setItemCount(int count) { 
      qDebug() << __PRETTY_FUNCTION__; 
      if (count != mItemCount && count > 0) { 
       if (mItemCount > 0 && mImageView != NULL) { 
        for (int i = 0; i < mItemCount; i++) { 
         if (mImageView[i] != NULL) { 
          remove(mImageView[i]); 
          mImageView[i]->deleteLater(); 
         } 
        } 
       } 

       mItemCount = count; 
       if (mSelectedIndex < 0 || mSelectedIndex >= mItemCount) { 
        mSelectedIndex = 0; 
       } 

       mImageView = new ImageView*[mItemCount]; 
       for (int i = 0; i < mItemCount; i++) { 
        mImageView[i] = new ImageView(this); 
        if (i == mSelectedIndex) { 
         mImageView[i]->setImageSource(mSelected); 
        } else { 
         mImageView[i]->setImageSource(mDeselected); 
        } 
        add(mImageView[i]); 
       } 

       emit selectedIndexChanged(mSelectedIndex); 
       qDebug() << "selectedIndexChanged(" << mSelectedIndex << ")"; 
      } 
     } 

     void ScrollGadget::onTouch(TouchEvent *event) { 
      //qDebug() << __PRETTY_FUNCTION__ << *event; 
      int index = event->localX()/(mWidth/mItemCount); 
      qDebug() << "index" << index; 
      if (index < 0) index = 0; 
      if (index >= mItemCount) index = mItemCount - 1; 

      switch (event->touchType()) { 
       case TouchType::Down: 
        mSaveIndex = mSelectedIndex; 
        setSelectedIndex(index); 
        break; 
       case TouchType::Move: 
       case TouchType::Up: 
        setSelectedIndex(index); 
        break; 
       case TouchType::Cancel: 
        setSelectedIndex(mSaveIndex); 
        break; 
      } 
     } 

     void ScrollGadget::handleLayoutFrameUpdated(QRectF rect) { 
      qDebug() << __PRETTY_FUNCTION__ << rect; 
      mWidth = rect.width(); 
      mHeight = rect.height(); 
     } 
} /* namespace test */ 
} /* namespace net */ 

此QML文件将证明它在一个空的黑莓项目:

import bb.cascades 1.2 
import net.test 1.0 

Page { 
    Container { 
     Label { 
      id: label 
      // Localized text with the dynamic translation and locale updates support 
      text: qsTr("Hello World ") + scroll.selectedIndex + Retranslate.onLocaleOrLanguageChanged 
      textStyle.base: SystemDefaults.TextStyles.BigText 
     } 

     ScrollGadget { 
      id: scroll 
      itemCount: 3 
     } 
    } 
} 

不过不要在加载applicationui.cpp中的QML文档之前,请不要忘记注册ScrollGadget:

#include "ScrollGadget.hpp" 
... 
qmlRegisterType<ScrollGadget>("net.test", 1, 0, "ScrollGadget"); 

// Create scene document from main.qml asset, the parent is set 
// to ensure the document gets destroyed properly at shut down. 
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this); 
... 

这是我使用的活动和非活动图像。

要使用此小工具,请将selectedIndex连接到图像显示对象,如列表。您可以将图像显示中的选择信号(如列表中的selectedIndex)连接到ScrollGadget的syncSelectedIndex,以便列表中的更改反映在小工具中。

Active Image

Inactive Image

Screen capture

+0

嘿理查德,我刚刚复制并粘贴代码和输出是“世界你好0”没有别的。现在做什么? – GoNish

+0

如果您有“asset:/// active.png”,“asset:///inactive.png”的图片,您应该看到其中三张图片。第一个是活动的,另外两个是非活动的。然后,您应该可以点击这些图像来选择3个中的哪一个处于活动状态,或者来回滑动手指。 – Richard

+0

嗨,理查德,非常感谢。我试图理解代码的一部分,我理解。现在,假设我不知道有多少图像进入滚动表示可能有3个图像,或者可能是5个。实际上,我想从服务器提供图像,以使活动和非活动图像的数量也发生变化。你有什么主意吗? – GoNish