0

ここでは「キャッチ22」という状況があります。Android 5.1.xでネイティブの日付/時刻のピッカーを使用した場合のレイアウトの問題

私はAppcelerator Titatium SDK 5.1.2を使用しています。画面サイズが非常に小さいAndroid 5.1.xでは、ネイティブのピッカーを使用して日付と時刻を正しく選択するソリューションが見つかりません。ピッカーを完全に見えるようにコンテンツを移動できるようにするには、を追加する必要があります。ただし、Android 5.1.xでこれを行うと、日付選択ツールで前の月にスクロールできなくなります。<View>コントロールに変更すると、日付ピッカーが予想どおりに動作します。しかし、ピッカーの一部が可視領域外にある場合、ユーザーはそこから値を選択する機会がありません。

私はこれを説明する簡単な例を作成しました。

ビュー:

<Alloy> 
    <Window class="container"> 
     <View id="form" onClick="clickHandler"> 
     <!-- 
     <ScrollView id="form" onClick="clickHandler"> 
     --> 
      <View id="formRow"> 
       <Label id="title">Picker demo</Label> 
      </View> 
      <View id="formRow"> 
       <Label id="label">Date</Label> 
       <TextField id="startDate" bubbleParent="true" editable="false"></TextField> 
      </View> 
      <View id="formRow"> 
       <Label id="label">Time</Label> 
       <TextField id="startTime" bubbleParent="true" editable="false"></TextField> 
      </View> 
     <!-- 
     </ScrollView> 
     --> 
     </View> 
    </Window> 
</Alloy> 

スタイル:

".container": { 
    top: 20, 
    backgroundColor:"#fa0", 
    orientationModes: [Ti.UI.PORTRAIT] 
} 
"Label": { 
    width: Ti.UI.SIZE, 
    height: Ti.UI.SIZE, 
    backgroundColor: 'transparent', 
    left:10, 
    color: "#000" 
} 

"#title": { top:15, 
    font: { 
     fontSize: '25dp', 
     fontStyle: 'bold' 
    } 
} 
"#label": { top:0, 
    font: { 
     fontSize: '18dp', 
     fontStyle: 'bold' 
    } 
} 
"TextField": { font: { 
     fontSize: '18dp', 
     fontStyle: 'normal' 
    }, 
    backgroundColor:'orange' 
} 
"#formRow":{ 
    top:7, 
    height:Ti.UI.SIZE, 
    width:Ti.UI.FILL 
} 

"#startDate":{ 
    top:0, 
    width:150, 
    right:10, 
} 
"#startTime":{ 
    top:0, 
    width:70, 
    right:10 
} 
"#form":{ 
    showVerticalScrollIndicator:"true", 
    layout:"vertical" 
} 

コントローラー:

var Moment = require('alloy/moment'); 

function clickHandler(e){ 
    if(e && e.source){ 
     console.log("clickHandler. id="+e.source.id); 
     if(e.source.id === 'startDate'){ 
      openDatePicker(e); 
     } else if(e.source.id === 'startTime'){ 
      openTimePicker(e); 
     } 
    } 
} 

// Date/time utils: 
function getAsDate(date) { 
    // Return as Date object 
    var dt = null; 
    if(typeof date === 'number') { 
     dt = new Date(date); 
    } else if(date instanceof Date) { 
     dt = date; 
    } 
    return dt; 
}; 
function getDMY(date) { 
    var dt = getAsDate(date); 
    if(dt) { 
     return Moment(dt).format('DD-MM-YYYY'); 
    } 
    return null; 
} 

function getHMM(date) { 
    // Returns format: H:mm 
    var dt = getAsDate(date); 
    if(dt) { 
     return Moment(dt).format('H:mm'); 
    } 
    return null; 
} 
function fromDMY(dt){ 
    var date = Moment(dt, "DD-MM-YYYY"); 
    if(date){ 
     date = new Date(date); 
    } 
    return date; 
} 

function fromHMM(time){ 
    var datetime = Moment(time, "H:mm"); 
    if(datetime) { 
     return new Date(datetime); 
    } 
    return null; 
} 

function openDatePicker(){ 
    // Inner helper class to clean up and remove picker items 
    function cleanup(){ 
     console.log("openDatePicker.cleanup..."); 
     pickerOpen = null; 
     $.startDate.value = getDMY(picker.value); 
     $.formRow.remove(picker); 
     $.startDate.bubbleParent = true; 
     $.form.removeEventListener('click',cleanup); 
    } 

    var v = $.startDate.value; 
    if(v && fromDMY(v)) { 
     v = fromDMY(v); 
     console.debug("startDate.value=" + $.startDate.value + " --> v=" + v + " - type: " + typeof v); 
    }else{ 
     v = new Date(); 
    } 
    var picker = Ti.UI.createPicker({ 
      type:Ti.UI.PICKER_TYPE_DATE, 
      maxDate:new Date(), 
      top:35, 
      value:v 
    }); 
    $.formRow.add(picker); 
    $.startDate.bubbleParent = false; 
    $.form.addEventListener('click',cleanup); 
} 

function openTimePicker(){ 
    // Inner helper class to clean up and remove picker items 
    function cleanup(){ 
     console.log("openTimePicker.cleanup..."); 
     pickerOpen = null; 
     $.startTime.value = getHMM(picker.value); 
     $.formRow.remove(picker); 
     $.startTime.bubbleParent = true; 
     $.form.removeEventListener('click',cleanup); 
    } 

    var v = $.startTime.value; 
    if(v && fromHMM(v)) { 
     v = fromHMM(v); 
     console.debug("startTime.value=" + $.startTime.value + " --> v=" + v + " - type: " + typeof v); 
    }else{ 
     v = new Date(); 
    } 
    var picker = Ti.UI.createPicker({ 
      type:Ti.UI.PICKER_TYPE_TIME, 
      format24:true, 
      minuteInterval:5, 
      top:35, 
      value:v 
    }); 
    $.formRow.add(picker); 
    $.startTime.bubbleParent = false; 
    $.form.addEventListener('click',cleanup); 
} 

$.index.open(); 
違いを参照するには、同じIDを持つ <ScrollView>の代わり <View>でコメント

長いコードを残念に思ってしまいました(実際には短くできませんでした)が、の作業の例です。

他のバージョンのAndroidでは、<ScrollView>がネイティブ日付ピッカーより優先されないため、ユーザーはピッカーを表示して日付を選択するためにコンテンツ全体を簡単に再配置できます。

私は480×800(240 dpi)の画面サイズを使用するGenymotion VM実行API 22で上記のアプリケーションを確認しました。これは問題を非常にうまく示しています:-)

Android 5.1.xでこれを行う方法はありますか?

ありがとうございます! /ジョン・

答えて

0

ネストされたスクロール可能UIコンポーネントは、問題のレシピです。この場合は、代わりにdialogを使用します。

+0

Hmmmm ....私はそれを理解しています。しかし、Android 5.xのネイティブコントロールに達するまで、それが「スクロール可能なUIコンポーネント」であることは実際には分かっていませんでした... - 迷惑なのは、他のAndroidバージョンやiOSでうまく動作することですUIエクスペリエンスはうまくいくようです...まあ、代わりにダイアログコントロールを見る必要があると思います。おかげで –

+0

ちょうどフォローアップ。ダイアログは、さまざまな状況をよりよく扱うようです:-)ありがとう! –

0

あなたはScrollViewにcanCancelEvents: falseを設定しようとしたことがありますか?デフォルトのtrueの場合、ScrollViewはその子のものであってもすべてのイベントに反応します。

+0

いいえ私はその属性を設定しようとしていませんでした。しかし、それを設定すると、 ''も無効になっているように見えます。 - ビュー全体をスクロールすることはできません。 –

関連する問題