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

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

问题描述

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

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

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

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> 而不是 <View> 中用相同的 id 注释以查看差异:

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.

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

任何想法如何为 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天全站免登陆