Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-11760] Make TableViewRow reuse conditional

GitHub Issuen/a
TypeSub-task
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2012-11-20T23:08:06.000+0000
Affected Version/sn/a
Fix Version/sRelease 3.0.0, Release 3.1.0, 2012 Sprint 24, 2012 Sprint 24 Core
ComponentsiOS
Labelscore, tableview
ReporterMax Stepanov
AssigneeMax Stepanov
Created2012-11-14T00:52:44.000+0000
Updated2017-03-16T21:03:00.000+0000

Description

Test case
var REUSABLE = true;
var win = Ti.UI.createWindow();
var tableView = Ti.UI.createTableView();
var toolbar = createToolbar();
var data = [];
var selectedRows = {};
var nbSelected = 0;
 
function createRow(c) {
    var row = Ti.UI.createTableViewRow({
        selectionStyle:'none',
		reusable: REUSABLE
    });
    row.selected = false;
    row.unread = !! Math.round(Math.random() * 1);
    row.starred = !! Math.round(Math.random() * 1);
    row.attachment = !! Math.round(Math.random() * 1);
    var important=Math.floor(Math.random()*5);
    var label=Math.floor(Math.random()*3);
    row.selectedBackgroundColor = '';
    row.height = 80;
    row.className = 'datarow';
    row.clickName = 'row';
     
  
    var selectButton = Ti.UI.createView({
        backgroundImage:'images/select_off.png',
        left:10,
        width:20,
        height:20,
        clickName:'select'
    });
     
    var viewCenter = Ti.UI.createView({
        layout:'vertical', 
        left:40, 
        right:40
    });
 
    var viewSenderDate = Ti.UI.createView({
        height:30,
        bottom:5
    });
  
    var senderView = Ti.UI.createLabel({
        color:'black',
        font:{fontSize:16,fontWeight:(row.unread?'bold':'normal')},
        left:0,
        top:0,
        height:Ti.UI.FILL,
        right:50,
        clickName:'user',
        text:'Fred Smith '
    });
     
    var attachmentView = Ti.UI.createView({
        backgroundImage:'images/button_attach.png',
        right:38,
        top:5,
        width:24,
        height:16,
        clickName:'attachment'
    });
    attachmentView.visible = row.attachment;
     
    var dateView = Ti.UI.createLabel({
        color:'#444',
        font:{fontSize:14,fontWeight:'normal'},
        width:35,
        top:0,
        right:0,
        height:20,
        clickName:'date',
        text:'7/31'
    });
     
    var viewimportanceSubject = Ti.UI.createView({
        height:20
    });
     
    var importanceView = Ti.UI.createView({
        left:0,
        width:16,
        height:10,
        clickName:'importance'
    });
     
         
    var subjectView = Ti.UI.createLabel({
        color:(row.unread?'black':'#444'),
        font:{fontSize:14,fontWeight:(row.unread?'bold':'normal')},
        left:20,
        top:0,
        height:Ti.UI.FILL,
        right:0,
        wordWrap:false,
        clickName:'subject',
        text:'This is a sample subject'
    });
     
    if (important === 0)
    {
        subjectView.left = 0;
        importanceView.visible = false;
    }
    else
        importanceView.backgroundImage = '/images/importance' + important + '.png';
     
     var viewmessageLabels = Ti.UI.createView({
        height:20
    });
     
    var messageView = Ti.UI.createLabel({
        color:'#444',
        font:{fontSize:14,fontWeight:'bold'},
        left:0,
        top:0,
        height:Ti.UI.FILL,
        wordWrap:false,
        clickName:'message',
        text:'This is a sample core message text which actually needs to be pretty long so that we see what we want to see'
    });
     
    // var labelsView = Ti.UI.createWebView({
        // color:'#444',
        // top:0,
        // height:24,
        // right:0,
        // wordWrap:false,
        // clickName:'labels'
    // });
    // labelsView.html = '<html><body><div style="border: 1px solid green;background-color:#aea;overflow: hidden;width:30;padding-left:4;padding-right:4">Label</div></body></html>';
    // labelsView.width = label*25;
    // messageView.right = labelsView.width;
     
    var starButton = Ti.UI.createView({
        right:10,
        width:20,
        height:20,
        clickName:'star'
    });
    starButton.backgroundImage = 'images/star_' + (row.starred?'on':'off') + '.png';
  
    viewSenderDate.add(senderView);
    viewSenderDate.add(attachmentView);
    viewSenderDate.add(dateView);
     
    viewimportanceSubject.add(importanceView);
    viewimportanceSubject.add(subjectView);
     
    viewmessageLabels.add(messageView);
    // viewmessageLabels.add(labelsView);
     
    viewCenter.add(viewSenderDate);
    viewCenter.add(viewimportanceSubject);
    viewCenter.add(viewmessageLabels);
     
    row.add(selectButton);
    row.add(viewCenter);
    row.add(starButton);
     
    row.select = function()
    {
        this.backgroundColor = '#D9E7FD';
        this.separatorColor = '#B9CFF5';
        this.selected = true;
        selectButton.backgroundImage = 'images/select_on.png';
    }
     
    row.unselect = function()
    {
        this.backgroundColor = this.unread?'white':'#efefef';
        this.separatorColor = '#777';
        this.selected  = false;
        selectButton.backgroundImage = 'images/select_off.png';
    }
     
    row.star = function()
    {
        this.starred = true;
        starButton.backgroundImage = 'images/star_' + (this.starred?'on':'off') + '.png';
    }
     
    row.unstar = function()
    {
        this.starred = false;
        starButton.backgroundImage = 'images/star_' + (this.starred?'on':'off') + '.png';
    }
     
    row.unselect();
    return row;
}
  
var updating = false;
var loadingRow = Ti.UI.createTableViewRow({
    height:80,
    title:"Show more messages...",
    clickName: 'loadingRow',
    color:'blue'
});
 
function addRows()
{
    updating = true;
    tableView.deleteRow(loadingRow);
    var lastCurrentRow = data.length -1;
    var lastRow = 50;
    for (var c=0;c<lastRow;c++)
    {
        var row = createRow(c);
        data.push(row);
    }
    Ti.API.info('adding ' + data.length + ' rows');
    tableView.data = data;
    // if (lastCurrentRow > 0)
//         tableView.scrollToIndex(lastCurrentRow,{animated:false,position:Ti.UI.iPhone.TableViewScrollPosition.BOTTOM}); 
    tableView.appendRow(loadingRow);
    updating = false;
}
 
tableView.addEventListener('click', function(e){
    if (e.source.clickName === 'loadingRow')
        addRows();
    else if (e.source.clickName === 'select')
    {
        if (e.row.selected)
        {
            delete selectedRows[e.index];
            e.row.unselect();
            nbSelected -= 1;
            toolbar.setNbSelected(nbSelected);
            if (nbSelected === 0)
                toolbar.hideMe();
        }
        else
        {
            selectedRows[e.index] = e.row;
            e.row.select();
            nbSelected += 1;
            toolbar.setNbSelected(nbSelected);
            if (nbSelected === 1) //first selected
                toolbar.showMe();
        }
    }
    else if (e.source.clickName === 'star')
    {
        if (e.row.starred)
            e.row.unstar();
        else
            e.row.star();
    }
     
})
 
addRows();
win.add(tableView);
win.add(toolbar);
 
function createToolbar()
{
    var toolbar = Ti.UI.createView({
        left:-1,
        right:-1,
        height:38,
        bottom:-1,
        borderColor:'#6E6E6F',
        borderWidth:1,
        backgroundGradient: {
            type: 'linear',
            startPoint: { x: '50%', y: 0 },
            endPoint: { x: '50%', y:'100%' },
            colors: [ { color: '#424245', offset: 0.0}, { color: '#181819', offset: 1.0 } ],
            backfillStart:true
        }
    });
    toolbar.transform = Ti.UI.create2DMatrix().translate(0,toolbar.height);
 
     
    var labelNbSelected = Ti.UI.createLabel({
        color:'white',
        textAlign:'center',
        font:{fontSize:14,fontWeight:'normal'},
        left:10,
        width:25,
        height:25,
        wordWrap:false,
        backgroundColor:'#48484A',
        borderRadius:2
    });
     
    toolbar.setNbSelected = function(_nb)
    {
        labelNbSelected.text = _nb;
    }
     
     var buttonUnselect = Ti.UI.createButton({
        image:'images/button_close.png',
        style:'plain',
        font:{fontSize:15,fontWeight:'normal'},
        right:5,
        width:30,
        height:30
    });
     
    buttonUnselect.addEventListener('click', function(_event)
    {
        if (nbSelected === 0) return;
        for (var index in selectedRows)
        {
            selectedRows[index].unselect();
        }
        selectedRows = {};
        nbSelected = 0;
        toolbar.setNbSelected(0);
        toolbar.hideMe();
    });
     
     
    toolbar.showMe = function()
    {
        var animation = Ti.UI.createAnimation();
        animation.transform = Ti.UI.create2DMatrix();
        toolbar.animate(animation);
    }
     
    toolbar.hideMe = function()
    {
        var animation = Ti.UI.createAnimation();
        animation.transform = Ti.UI.create2DMatrix().translate(0,toolbar.height);
        toolbar.animate(animation);
    }
     
    toolbar.add(labelNbSelected);
    toolbar.add(buttonUnselect);
    return toolbar;
}
win.add(toolbar);
 
win.open();
Run the example above in Instruments with REUSABLE both true and false. In case REUSABLE=true, number of TiUITableViewRowContainer instances should match number of UITableViewCell. In case REUSABLE=false (default), number of TiUITableViewRowContainer instances should grow as scrolled down, but not up. On simulate memory warning it should drop to number of visible UITableViewCells.

Comments

  1. Max Stepanov 2012-11-14

    PR https://github.com/appcelerator/titanium_mobile/pull/3424
  2. Max Stepanov 2012-11-21

    3_0_X PR https://github.com/appcelerator/titanium_mobile/pull/3464
  3. Danny Pham 2012-12-24

    Is this feature already available in latest release SDK 3.0.0 GA? Because it didn't find anything about it in the official docs and with Instruments I see no differences using reusable=true or reusable=false.
  4. Lee Morris 2017-03-16

    Closing ticket as fixed.

JSON Source