在Android 5.1.x上使用本机日期/时间选择器时的布局挑战 [英] Layout challenge when using native date/time picker on Android 5.1.x

查看:84
本文介绍了在Android 5.1.x上使用本机日期/时间选择器时的布局挑战的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这里有一种赶上22"的情况.

I have a kind of "catch 22" situation here.

我正在使用Appcelerator Titatium SDK 5.1.2.在屏幕尺寸非常小的Android 5.1.x上,我找不到使用本机选择器正确选择日期和时间的解决方案.我需要添加<ScrollView>以允许用户移动内容以使选择器完全可见.但是,在Android 5.1.x上执行此操作时,用户无法滚动到日期选择器中的前几个月....将其更改为<View>控件将使日期选择器的行为符合预期.但是,如果选择器的一部分在可见区域之外,则用户没有机会从那里选择值...

I am using Appcelerator Titatium SDK 5.1.2. On Android 5.1.x with a very small screen size I cannot find a solution to correctly select date and time using the native pickers. I need to add a <ScrollView> to allow the user to move the contents to make the picker entirely visible. However, when doing this on Android 5.1.x the user cannot scroll back to previous months in the date picker.... Changing it to a <View> control makes the date picker behave as expected. However, if part of the picker is outside of the visible area the user has no chance to select values from there...

我创建了一个简单的示例来说明这一点.用<ScrollView>而不是具有相同ID的<View>进行注释以查看区别:

I have created a simple example to illustrate this. Comment in <ScrollView> instead of <View> with same id to see difference:

查看:

<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();

很抱歉,冗长的代码(无法真正缩短代码的长度)-但这是一个有效的示例.

Sorry for the lengthy code (couldn't really make it shorter) - but it is a working example.

在其他版本的Android上,<ScrollView>并不优先于本机日期选择器-因此,用户可以轻松地重新放置整个内容的位置以查看选择器,然后选择日期.

On other versions of Android the <ScrollView> does not take precedence over the native date picker - and thus allows the user to easily reposition the entire contents to see the picker and then select the dates.

我已在运行API 22的Genymotion VM中使用480 x 800(240 dpi)的屏幕尺寸验证了上述应用程序.它很好地说明了这个问题:-)

有什么想法如何针对Android 5.1.x做到这一点?

Any ideas how to do this for Android 5.1.x?

提前谢谢!

/约翰

推荐答案

嵌套的可滚​​动UI组件可以解决问题.在这种情况下,您可能要使用对话框.

Nested scrollable UI components is a recipe for problems. In this case you might want to use the dialog instead.

这篇关于在Android 5.1.x上使用本机日期/时间选择器时的布局挑战的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆