Titanium mobileでWeightbotのような横スクロール目盛を作ってみた。
主な機能- スクロールラベルの区切りで参照するデータを切り替える
- 目盛の矢印がスクロールラベルの丁度真ん中に来るようにする
2番目の機能を実現するロジック
- 貫性でスクロール中に速度が落ちたらちょうど真ん中に自動スクロール
- 指を離して少し経っても動いていなかったらちょうど真ん中に自動スクロール
Titanium mobile SDK 1.8から"dragEnd"イベントが拾えるようになりやっと実現できました。
パラメータは感覚で適当に決めました。
ご意見、アドバイスいただけたら嬉しいです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var win = Ti.UI.currentWindow; | |
// 仮データ | |
var dataList = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; | |
// 参照データを表示するラベル | |
var dataLabel = Titanium.UI.createLabel({ | |
backgroundColor: 'black', | |
borderRadius: 30, | |
color:'white', | |
font:{ | |
fontFamily:'Helvetica Neue', | |
fontSize:100 | |
}, | |
textAlign:'center', | |
top:50, left:'auto', height: 150, width: 200, | |
text: dataList[0] | |
}); | |
win.add(dataLabel); | |
// 目盛に合わせてスクロールさせることで参照データを切り替えるScrollView | |
var scrollView = Titanium.UI.createScrollView({ | |
contentWidth:'auto', | |
contentHeight:'auto', | |
top:290, | |
height:70, | |
width:320, | |
backgroundColor:'#gray', | |
zIndex:1 | |
}); | |
var labelNum = dataList.length + 1; // 切り替えラベルの数 | |
var labelWidth = 50; // 切り替えラベルの横幅 | |
for(var i = 0; i < labelNum; i++){ | |
if(i < labelNum - 1){ | |
// スクロールメモリのラベル | |
var scrollLabel = Ti.UI.createLabel({ | |
borderColor:'black', | |
backgroundColor:'#A0522D', | |
height:70, width:labelWidth, | |
left: 135 + labelWidth * i, | |
font:{ | |
fontFamily:'Helvetica Neue', | |
fontSize:25 | |
}, | |
textAlign: 'center', | |
text:i | |
}); | |
scrollView.add(scrollLabel); | |
} else { | |
// 選択範囲外は無地グレー | |
var scrollLabel = Ti.UI.createLabel({ | |
backgroundColor:'#gray', | |
height:70, width:135, | |
left: 135 + labelWidth * i | |
}); | |
scrollView.add(scrollLabel); | |
} | |
} | |
win.add(scrollView); | |
// 目盛 | |
var allow = Titanium.UI.createLabel({ | |
text:"▼", | |
font:{fontSize:20}, | |
color:'#gray', | |
top:200, | |
left:150, | |
width:20, | |
textAlign:'center', | |
zIndex:3 | |
}); | |
win.add(allow); | |
// ---------------------------ここからロジック部分--------------------------------- | |
// 変数初期化 | |
var pos_old = 0; | |
var time_old = new Date(); | |
var catchDragEnd = false; | |
var throwDistance = 0; | |
// Titanium mobile SDK 1.8からdragEndイベントが拾えるようになった | |
scrollView.addEventListener('dragEnd', function(){ | |
catchDragEnd = true; | |
// 0.2秒後にあまり動いていなければ切りの良い位置へ自動スクロール | |
setTimeout(function(){ | |
if(pos_old % labelWidth != 0 && throwDistance < labelWidth / 2){ | |
scrollView.scrollTo(Math.round(pos_old / labelWidth) * labelWidth, 0); | |
throwDistance = 0; | |
catchDragEnd = false; | |
} | |
}, 200); | |
}); | |
scrollView.addEventListener('scroll', function(e){ | |
var pos_new = e.x; | |
// 目盛の計算 | |
var index = Math.floor((pos_new + labelWidth / 2) / labelWidth); | |
dataLabel.text = dataList[index]; | |
time_new = new Date(); | |
var time_diff = time_new.getTime() - time_old.getTime(); | |
// あまりにも細かく見すぎても意味が無いので0.1秒間隔でチェック | |
if( 100 < time_diff ){ | |
var pos_diff = Math.abs(pos_new - pos_old); | |
// dragEndイベントを拾ってからのスクロール距離の合計 | |
if(catchDragEnd) { | |
throwDistance += pos_diff; | |
} | |
// スクロール速度の計算 | |
velocity = Math.round(pos_diff / time_diff * 1000); | |
// 0.2秒以上経過していない場合 | |
// かつ、速度が遅くなった場合 | |
if(time_diff < 200 && velocity < 20){ | |
// 中途半端な位置の場合 | |
if(pos_new % labelWidth != 0){ | |
// 切りの良い位置へ自動スクロール | |
scrollView.scrollTo(Math.round(pos_new / labelWidth) * labelWidth, 0); | |
catchDragEnd = false; | |
throwDistance = 0; | |
} | |
} | |
time_old = time_new; | |
pos_old = pos_new; | |
} | |
}); |
شركة المثالية للتنظيف بالقطيف
返信削除شركة تنظيف افران بالاحساء
شركة تركيب ارضيات باركيه بالخرج
شركة تركيب ارضيات باركيه بالرياض
شركة ميس لمكافحة الحشرات
شركة تنظيف كنب بالاحساء