水平滚动图像

时间:2014-05-21 11:11:48

标签: qml blackberry-10 blackberry-cascades

我想创建水平滚动图像。如果你看到" Blackberry Travel"应用程序,在此应用程序中的顶部图像动态滚动。我想创建相同的滚动视图。同样在图像的底部我们可以看到圆圈。随着图像的变化,特定的圆变暗。这个滚动有两种方式意味着它及时滚动,并通过点击鼠标它也滚动。 所以,请帮我创建这样的滚动。我是新来的。谢谢......

1 个答案:

答案 0 :(得分:1)

这是一个基于Container的自定义控件,它提供了一行圆/点选择范例。标准免责声明适用于演示目的,我不保证已捕获所有错误条件等。具体而言,计算选择哪个索引项的数学运算有点偏,因为默认情况下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文件将在空的BlackBerry项目中演示它:

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