1

Я использую титановый сплав версии 3.2. У меня есть сбор сообщений в списке. Мои данные выглядят так:Титановый сплав ListView Вложенная модель Массив тегов

[ 
    { username: 'dude', imageUrl: 'url', tags: ['tag1','tag2','tag3']  }, 
    { username: 'wheres', imageUrl: 'url', tags: ['tag1']      }, 
    { username: 'my',  imageUrl: 'url', tags: ['tag1','tag2','tag3','tag4'] }, 
    { username: 'car', imageUrl: 'url', tags: ['tag1','tag2']    } 
    ] 

И вот xml. Это работает только для имени пользователя и изображения. Я не могу понять, как добавить теги к каждому сообщению.

<ListView id="streamListview"> 

     <Templates> 
      <ItemTemplate name="template" id="template"> 
       <View class="item-container">    
        <ImageView bindId="pic" class="pic"/> 
        <Label bindId="username" class="username"/> 
       </View> 
      </ItemTemplate> 
     </Templates> 

     <ListSection id="section"> 
      <ListItem template="template" class="list-item"/> 
     </ListSection>     

    </ListView> 

И мой код контроллера (без тегов)

var posts = []; 
    for (var i=0; i<data.length; i++){ 
     var post = { 
      template : "template", 
      pic  : { image : data[i].get("imageUrl") }, 
      username : { text : data[i].get("username") } 
     }; 
     posts.push(post);    
    } 
    $.section.setItems(posts); 

Как добавить метки (которые являются интерактивными) к сообщению, если я должен объявить КАЖДОЕ представление в шаблоне, прежде чем руки? Каждому массиву тегов в моем примере понадобилось бы другое количество просмотров в зависимости от длины массива. Каждый тег в идеале должен быть его собственным элементом UI.Label. Я считаю, что это можно сделать с помощью TableView, но я бы предпочел использовать ListView по соображениям производительности.

ответ

0

Это должно быть возможно с помощью ListView, если вы создадите шаблон в контроллере динамически. Вам также потребуется выполнить итерацию каждого объекта «теги» и создать «тип» Ti.UI.Label для каждого элемента тега. Однако я не уверен, что этот метод будет более эффективным, чем использование объекта TableView, потому что по существу каждый создаваемый вами ListItem будет содержать другой шаблон.

Чтобы создать динамический шаблон, он будет похож на приведенный ниже: Имейте в виду, что вам нужно будет перебирать «теги» и генерировать x типов Ti.UI.Label, где x - длина «тегов». Кроме того, событие click должно работать с использованием Titanium SDK 3.2.1.

var plainTemplate = { 
childTemplates: [ 
    { 
     type: 'Ti.UI.Label', 
     bindId: 'username' 
    }, 
    { 
     type: 'Ti.UI.ImageView', 
     bindId: 'pic'  

    },      
    { 
     type: 'Ti.UI.Label', 
     bindId: 'tags', 
     events: { click : handleTagClickEvent } // Binds a callback to click event 
    } 
]}; 


function handleTagClickEvent(e) { 
    Ti.API.info('You clicked a tag label: ' + e.type); 
} 


var listView = Ti.UI.createListView({ 
    templates: { 'plain': plainTemplate }, 
    defaultItemTemplate: 'plain'   
}); 

Надеюсь, это поможет вам в некотором роде!

+0

Спасибо Nando, но я не думаю, что это сработает, потому что вы объявляете один Ti.UI.Label для тегов. Теги представляют собой массив строк, каждая строка нуждается в собственном Ti.UI.Label. Поскольку вы должны объявлять дочерние шаблоны, прежде чем создавать экземпляр ListView, я не верю, что у вас есть возможность добавлять переменное число Ti.UI.Labels в зависимости от array.length – TheBigC

5

Я думаю, что я знаю, что вам нужно, в этом случае, так как вы хотите генерировать каждый элемент динамически (например, сценарий, когда вы сначала открываете свое окно с помощью ListView и делаете вызов API для получения удаленных данных и заполнения ListView с указанными данными), вам нужно будет использовать ItemTemplates, объявленные в своих собственных контроллерах.

Вы просто создать новый контроллер, как нормальные и в представлении XML вы кладете ItemTemplate:

<Alloy> 
    <ItemTemplate name="template" id="template"> 
     <View class="item-container">    
      <ImageView bindId="pic" class="pic"/> 
      <Label bindId="username" class="username"/> 
     </View> 
    </ItemTemplate> 
</Alloy> 

В вашем TSS вы положили все стили, упомянутым к каждому элементу в шаблоне, так как вы Ждете» т предоставить пример TSS я не могу сказать, что ваши свойства стиля, но в TSS вам нужно определить стиль шаблона, например, позволяет сказать что-то вроде:

"#template": // this is the id of your template in your xml 
{ 
    width : Ti.UI.FILL, 
    height : '44dp', 
    backgroundColor : '#FFFFFF' 
} 

чтобы заполнить ваш ListView с ListItems динамически, вам нужно будет сделать что-то подобное в своем обратный вызов из вашего API:

function displayListItems(items) 
{ 
    var itemCollection = []; 
    for(var i=0; i < items.length; i++) 
    { 
     var tmp = { 
      pic : { 
       image : items[i].image 
      }, 
      username : { 
       text : items[i].text 
      }, 
      template : 'template' // here goes the name of the template in your xml, **do not confuse name with id, both are different and using one doesn't replace the other** 
     }; 
     itemCollection.push(tmp); 
    } 
    $.ListView.sections[0].items = itemCollection; 
} 

И воила, вы получаете динамический список ListView. Теперь вы можете сделать несколько дополнительных шагов.

В контроллере шаблона вы можете оставить это поле пустым, так как ListView может управлять событие itemclick, но если вы хотите различные действия, которые имеют место, когда определенный элемент в ListItem для запуска, необходимо указать функции вызывается в вашем контроллере для каждого элемента.

Например позволяет сказать, что вы прошли свойство dataInfo к вашему ImageView и вашей этикетки в шаблоне, как это:

function displayListItems(items) 
{ 
    var itemCollection = []; 
    for(var i=0; i < items.length; i++) 
    { 
     var tmp = { 
      pic : { 
       image : items[i].image 
       dataInfo : items[i].fooA //lets pass to the ImageView the object fooA 
      }, 
      username : { 
       text : items[i].text, 
       dataInfo : items[i].fooB //lets pass to the Label the object fooB 
      }, 
      template : 'template' // here goes the name of the template in your xml, **do not confuse name with id, both are different and using one doesn't replace the other** 
     }; 
     itemCollection.push(tmp); 
    } 
    $.ListView.sections[0].items = itemCollection; 
} 

И вы хотите ImageView и этикетки для вызова различных функций, вы будете необходимо изменить XML, как это:

<Alloy> 
    <ItemTemplate name="template" id="template"> 
     <View class="item-container">    
      <ImageView bindId="pic" class="pic" onClick="imageFunction"/> <!-- added onClick event --> 
      <Label bindId="username" class="username" onClick="labelFunction"/> <!-- added onClick event --> 
     </View> 
    </ItemTemplate> 
</Alloy> 

в контроллере вы объявите каждую функцию:

function imageFunction(e) 
{ 
    var dataInfo; 
    if(Ti.Platform.osname === 'android') 
    { 
     var item = e.section.items[e.itemIndex]; 
     var bindObject = item[e.bindId]; 
     dataInfo = bindObject.fooA; 
    } 
    else 
    { 
     dataInfo = e.source.fooA; 
    } 

} 

function labelFunction(e) 
{ 
    var dataInfo; 
    if(Ti.Platform.osname === 'android') 
    { 
     var item = e.section.items[e.itemIndex]; 
     var bindObject = item[e.bindId]; 
     dataInfo = bindObject.fooB; 
    } 
    else 
    { 
     dataInfo = e.source.fooB; 
    } 
} 

Теперь вы можете спросить, почему нужно проверить имя оперативной системы, так что Android и iOS получают разные объекты, даже если вы используете ту же функцию. В прошивке любой недвижимости, которые Вы передаете на источник события можно получить непосредственно e.source.propertyName в Android вам нужно получить доступ к элементу в e.section использования e.itemIndex, после того, что вы получить представление внутри элемента связанным с ним связанным с ним связанным с ним e.bindId.

Одним из самых больших ограничений для ListItems является обновление представлений внутри ListItem, для этого вам необходимо обновить весь элемент, который вы хотите изменить визуально, и назначить ему другой шаблон, но скорость, с которой это делается. не сможет заметить какого-либо отставания, серьезно, производительность ListView - это нечто иное, в отличие от ScrollView, и не будем говорить о ужасном и ошибочном TableView.

Предупреждение, что в Titanium SDK 3.2.0.GA есть ошибка в ItemTemplates, которая вызывает просмотр внутри дочерних представлений в шаблоне, чтобы изменить их zIndex на Android без возможности его контролировать. Существуют два известных экземпляра для это: Если вы не используете макет в дочернем представлении, это может привести к тому, что представление, которое должно отображаться под другим видом, появится поверх него.

Если вы используете вертикальную компоновку в дочернем виде: это может привести к скремблированию позиций каждого вида, это связано с тем, что zIndex изменяет порядок отображения в вертикальном макете.

Эта ошибка запускается случайным образом, и команда Appcelerator не много работала над ней, проверьте билет JIRA здесь TIMOB-16704.

Этого можно избежать, если вы используете шаблон с фиксированными позициями и убедитесь, что нет надписи поверх другого, также помните, что нет вертикальных макетов, не проверял это горизонтально, но лично я стараюсь избегать горизонтальных макеты, так как есть и другие ошибки, связанные с ним при использовании в scrollviews, нормальных взглядов и т.д.

EDIT

Еще одна вещь, которую вы можете сделать с этим назначить другой взгляд на элементы, которые вы оказываете , у вас есть варианты:

  • Применение стилей при объявлении ListItem.
  • Чтобы применить различные макеты к каждому элементу ListItem в зависимости от ряда условий.

Для первого варианта вам нужно опустить или переписать декларацию определенных свойств в шаблоне:

Например, давайте использовать другой цвет фона, где свойство fooA существует и если он другого цвета не имеет:

function displayListItems(items) 
{ 
    var itemCollection = []; 
    for(var i=0; i < items.length; i++) 
    { 
     var properties = {}; 
     if(typeof items[i].fooA !== 'undefined') 
     { 
      properties = { 
       backgroundColor : 'red' 
      }; 
     } 
     else 
     { 
      properties = { 
       backgroundColor : 'blue' 
      }; 
     } 
     var tmp = { 
      properties : properties, // properties for the template 
      pic : { 
       image : items[i].image 
       dataInfo : items[i].fooA //lets pass to the ImageView the object fooA 
      }, 
      username : { 
       text : items[i].text, 
       dataInfo : items[i].fooB //lets pass to the Label the object fooB 
      }, 
      template : 'template' // here goes the name of the template in your xml, **do not confuse name with id, both are different and using one doesn't replace the other** 
     }; 
     itemCollection.push(tmp); 
    } 
    $.ListView.sections[0].items = itemCollection; 
} 

Вы можете изменить ширину, высоту, backgroundColor, расположение и т. д. в соответствии с вашими потребностями.

Теперь, если вы хотите, чтобы каждый элемент имел четкий вид (что означает разные виды для отображения различного контента) и, возможно, другое поведение, вам нужно использовать разные шаблоны.

Это может показаться назойливым, но это не так, шаблоны быстро создаются после того, как вы привыкнете к ним, что не займет много времени, может быть, еще один downer может быть, если вы хотите 11 разных взглядов, это может означать, что вам понадобится 11 шаблонов, но это крайний случай, и вы можете пересмотреть свой интерфейс, если вы имеете дело с этим множеством шаблонов.

Несмотря на то что ограничительные, шаблоны товаров предлагают широкий спектр возможностей для вас, малое воображение является единственным ингредиентом, необходимым для выявления всех возможностей.

EDIT 2

я, наконец, понял, в чем вы проблема, если вам нужно создать шаблон, содержание которого меняется в зависимости от топора переменной, то вы должны попробовать объявить шаблон на контроллере ListView, но это должно быть сделано до открытия окна были вы будете показывать ListView, так как шаблоны свойства можно установить только на создании, вы должны добавить что-то вроде:

function createTemplate(items) 
{ 
    var template = {}; 
    for(var i=0; i < items.length; i++) 
    { 

     template.childTemplates = []; 
     for(var j=0; items[i].tags.length; j++) 
     { 
      var childTemplate = { 
       type: 'Ti.UI.Label', 
       bindId: 'tag' + j, 
       properties : { 
        width : Ti.UI.SIZE, // Here you define how your style 
        height : Ti.UI.SIZE, 
        font : { 
         fontSize : '18dp' 
        }, 
        text : items[i].tags[j].text // you can pass the text here or if you want to on the later for 
       } 
      }; 
      template.childTemplates.push(childTemplate); 
     } 
    } 
    // After this you should end up with a template with as many childTemplates as tags each item have, so send the template to the controller with your ListView 
    Alloy.createController('ListViewWindow', {customTemplate: template}); 
} 

И в контроллере ListView вы retriev е шаблон:

var args = arguments[0] || {}; 
var template = args.customTemplate; 

$.ListView.templates = {'customTemplate' : template}; // before any window open call, do this 

Это должно добавить шаблон к вашему ListView, вы можете также создать ListView в контроллере вместо того, чтобы объявить его в Alloy XML, используйте тот, который соответствует вашим потребностям больше.

+0

Я ценю подробный ответ, но я не знаю, Думаете, вы ответили на основную часть вопроса. Вопрос имеет массив сообщений, каждый столбец имеет массив тегов. Массив тегов является динамическим по длине. Наличие шаблона набора не учитывает различное количество тегов. – TheBigC

+0

проверить мой отредактированный ответ, высота вашего шаблона может быть установлена ​​на Ti.UI.SIZE и независимо от того, какой размер контента вы на него набросите, он настроится на него. Просто помните, а не вертикальные макеты и избегайте совпадающих представлений сверху друг с другом. –

+0

Я думаю, что я только что понял ваш вопрос, говоря о наличии ListItem, который может содержать один или несколько ярлыков, верно? проверить мой отредактированный ответ –

Смежные вопросы