![](https://habrastorage.org/files/1db/0ec/b98/1db0ecb9813b46559734d9b35dac10b7.gif)
もちろん、このパスで多くの問題が待っていました(そして待っていました)。そのほとんどはここで説明されています 。 現時点では、かなりの量の作業が既に蓄積されています。この記事が、経験を体系化して文書化するサイクルの先駆けになることを願っています。 まず、シンプルで必要なもの、つまり、ピッカーと呼ばれる英語のデジタル値を選択するためのウィジェットから始めましょう。 これは、日付、時刻、または特定の値を入力する必要があるときにAndroidで使用されます。
ボンネットの下
繰り返すためには、最初に元のウィジェットを分析し、それがどの部分で構成されているかを理解する必要があるのは論理的です。 では、何がありますか?
1)スクロール可能なリスト( 青でマーク)に基づいており、選択された要素は表示部分の中央にあります。 そのため、標準のListViewを基礎として使用します。 中心的な要素の選択を実現するには、次のものが必要です。
- 動きの終わりを追跡します。
- 垂直に幾何学的中心にある要素を見つけます。
- 必要に応じて、半分の位置からアニメーションでねじります。
- 中央インデックスを最新にします。
- 要素の変更に関する信号を生成します。
結果のコード
オリジナルではリストはしばしば循環的であることに注意する必要がありますが、これまでの結果のqml-cloneでは通常のもののみを使用できます。 import QtQuick 2.0 Rectangle { id: rootRect property double itemHeight: 8*mm property alias model: listView.model signal indexChanged(int value) function setValue(value) { listView.currentIndex = value listView.positionViewAtIndex(value, ListView.Center); } ListView { id: listView clip: true anchors.fill: parent contentHeight: itemHeight*3 delegate: Item { property var isCurrent: ListView.isCurrentItem id: item height: itemHeight width: listView.width Rectangle { anchors.fill: parent Text { text: model.text font.pixelSize: 3*mm anchors.centerIn: parent } MouseArea { anchors.fill: parent onClicked: { rootRect.gotoIndex(model.index) } } } } onMovementEnded: { var centralIndex = listView.indexAt(listView.contentX+1,listView.contentY+itemHeight+itemHeight/2) gotoIndex(centralIndex) indexChanged(currentIndex) } } function gotoIndex(inIndex) { var begPos = listView.contentY; var destPos; listView.positionViewAtIndex(inIndex, ListView.Center); destPos = listView.contentY; anim.from = begPos; anim.to = destPos; anim.running = true; listView.currentIndex = inIndex } NumberAnimation { id: anim; target: listView; property: "contentY"; easing { type: Easing.OutInExpo; overshoot: 50 } } function next() { gotoIndex(listView.currentIndex+1) } function prev() { gotoIndex(listView.currentIndex-1) } }
![](https://habrastorage.org/files/f86/732/c53/f86732c53386444698491e2fa9e914ac.png)
2)セパレーター( オレンジ色でマーク)はリストの一番上にあります。 選択したアイテムを視覚的に強調表示する必要がありました。 それらは、指定されたオフセット(それぞれ、1つおよび2つの要素の高さ)を使用して、希望する色の簡単な長方形で実装されます。
3)上部要素と下部要素( 緑色でマーク)の照明効果を得るために、白から透明へのグラデーションの画像が使用されます。 また、位置決めの問題もあり、上に重ねられます。
2番目と3番目の要素のコード
import QtQuick 2.0 import "../Global" Rectangle { property alias model: pickerList.model signal indexSelected(int value) function setValue(value) { pickerList.setValue(value) } width: 10*mm height: 25*mm ACPickerList { id: pickerList width: parent.width height: parent.height onIndexChanged: { indexSelected(value) } } Image { id: upShadow sourceSize.height: 10*mm sourceSize.width: 10*mm source: "qrc:/img/images/icons/pickerShadowUp.svg" anchors { top: parent.top } } Image { id: downShadow sourceSize.height: 10*mm sourceSize.width: 10*mm source: "qrc:/img/images/icons/pickerShadowDown.svg" anchors { bottom: parent.bottom } } Rectangle { id: topSelector width: parent.width height: parseInt(0.3*mm) color: ACGlobal.style.holoLightBlue anchors { top: parent.top topMargin: pickerList.itemHeight } } Rectangle { id: bottomSelector width: parent.width height: parseInt(0.3*mm) color: ACGlobal.style.holoLightBlue anchors { top: parent.top topMargin: pickerList.itemHeight*2 } } }
タイミング
これで、ウィジェット自体ができました。使用例を示すために残っています。 本格的な日付ピッカーは、別の記事のトピックです(ただし、今日ここでそれをよく見ることができます )。 したがって、たとえば、タイミングの対話の空白としてpicersを作成するなど、より簡単な方法で
![](https://habrastorage.org/files/d59/0c9/808/d590c98081c147ee91856000109860ce.png)
Rectangle { ACPicker { id: hoursPicker model: ListModel { id: hoursModel Component.onCompleted: { append({ value: -1, text: " " }) for(var i = 0; i <= 23; i++){ var norm = i.toString(); if( i < 10 ) norm = "0" + i append({ value: i, text: norm }) } append({ value: -1, text: " " }) } } anchors { right: center.left rightMargin: 1*mm verticalCenter: parent.verticalCenter } } Text { id: center text:":" font.pixelSize: 3*mm anchors.centerIn: parent } ACPicker { id: minutesPicker model: ListModel { id: minutesModel Component.onCompleted: { append({ value: -1, text: " " }) for(var i = 0; i <= 59; i++){ var norm = i.toString(); if( i < 10 ) norm = "0" + i append({ value: i, text: norm }) } append({ value: -1, text: " " }) } } anchors { left: center.right leftMargin: 1*mm verticalCenter: parent.verticalCenter } } anchors.fill: parent }
プロジェクト全体のソース。