Tuesday 23 June 2015

HB Blog 79: Custom Listing In Android And iOS.

In mobile OS, data representation in listing form is most important component. In Android we have listview whereas, we have tableview in iOS. In this post I will try to put how do we create custom listview adapter in Android and custom tableview cell in iOS.
In Android, for custom listview,
We actually don't create custom listview but what we do is, we create custom adapter for listview. This adapter can be created either by extending base adapter class or array adapter class depending on the type of objects that are to be displayed in listview. When we extend base adpater we override getView() method in which inflate our view that is to be display at the specified position in the data set.Also, we have getCount() and getItemId() methods to get number of items in the data set and get the row id associated with the specified position in the list.

Have a look on few code snippets,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
private class MyCustomAdapter extends BaseAdapter {

        private static final int ITEM_TYPE_ONE = 1;
        private static final int ITEM_TYPE_TWO = 2;
        private static final int ITEM_TYPE_MAX_COUNT = ITEM_TYPE_ONE+ITEM_TYPE_TWO+1;

        private ArrayList<DataPojo> mData;
        private LayoutInflater mInflater;

        public MyCustomAdapter(ArrayList<DataPojo> data) {
            this.mData=data;
            mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getItemViewType(int position) {
            int type;
            DataPojo dataPojo=mData.get(position);
            if(dataPojo.flag){
                type=ITEM_TYPE_ONE;
            }
            else {
                type=ITEM_TYPE_TWO;
            }
            return type;
        }

        @Override
        public int getViewTypeCount() {
            return ITEM_TYPE_MAX_COUNT;
        }

        @Override
        public int getCount() {
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            int type = getItemViewType(position);
            if (convertView == null) {
                holder = new ViewHolder();
                switch (type) {
                    case ITEM_TYPE_ONE:
                        convertView = mInflater.inflate(R.layout.item_view_one,  null);
                        holder.textView1 = (TextView)convertView.findViewById(R.id.textView1);
                        holder.imageView=(ImageView)convertView.findViewById(R.id.imageView1);
                        break;
                    case ITEM_TYPE_TWO:
                        convertView = mInflater.inflate(R.layout.item_view_two, null);
                        holder.textView1 = (TextView)convertView.findViewById(R.id.textView1);
                        holder.imageView=(ImageView)convertView.findViewById(R.id.imageView1);
                        break;

                }
                convertView.setTag(holder);
            }

                holder = (ViewHolder)convertView.getTag();

            DataPojo dataPojo=mData.get(position);
            holder.textView1.setText(dataPojo.strValue);
            return convertView;
        }
    }

    public static class ViewHolder {
        public TextView textView1;
        public ImageView imageView;
    }

    public class DataPojo{
        public String strValue;
        public boolean flag;
    }
}

Finally, we use setAdapter() method to set our custom adapter to listview as follows,
1
 listView.setAdapter(mAdapter); 
 

In iOS, for custom tableview cell,
We create custom cell with required UI component design as well as custom class for that cell. Then, this cell is added to the tableview in cellForRowAtIndexPath method of tableview.We use this custom class to  represents the underlying data model of the custom cell by creating respective outlets for components in that cell. We also have delegates to customize height of cell, get number of items in the cell etc.
Have a look on few code snippets,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *customTableIdentifier = @"CustomTableCell";

    CustomTableCell *cell = (CustomTableCell  *)[tableView dequeueReusableCellWithIdentifier:customTableIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }
   
    cell.nameLabel.text = [tableData objectAtIndex:indexPath.row];
    cell.imageView.image = [UIImage imageNamed:[myimage objectAtIndex:indexPath.row]];
    cell.rollNoLabel.text = [prepTime objectAtIndex:indexPath.row];
   
    return cell;
}

No comments:

Post a Comment