Thursday, February 2, 2012

DataGrid Part 5 - Customized ListView as table

If you have not read the previous posts, you might want to start from the first post.

We will discuss the Customized ListView in this post. Customized ListView is actually the table view under the header. I use ListView to achieve this table appearance by customize it. In order to do that, we need following classes.
class cls_datagrid_adapter extends BaseAdapter {

    private Context mContext;
    private cls_datagrid.members_collection mc;
    
    public cls_datagrid_adapter(Context context, cls_datagrid.members_collection mc) {
        mContext = context;
        this.mc = mc;
    }

    public int getCount() {
        return mc.DATA_SOURCE.getRowSize();
    }

    public Object getItem(int position) {
     return mc.DATA_SOURCE.getRow(position);
    }

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

    public View getView(int position, View convertView, ViewGroup parent) {
     cls_item_view iv; 
     
     cls_datatable.cls_datarow data = mc.DATA_SOURCE.getRow(position);
     
        if(convertView == null)
        {
         iv = new cls_item_view(mContext, mc, data); 
        }
        else 
        {
         iv = (cls_item_view)convertView;
         iv.populate(data);
        }
        
        return iv;
    }
}

class cls_item_view extends LinearLayout {

 private TextView[] aryTextView;
 private Context mContext;
 private cls_spliter2_view mTxtContent;
 private cls_datagrid.members_collection mc;
 
 public cls_item_view(Context context, cls_datagrid.members_collection mc, cls_datatable.cls_datarow data) {
  super(context);
  mContext = context;
  this.mc = mc;
        
  setOrientation(HORIZONTAL);

  artTextView = new TextView[data.getColumnSize()];
  int intCellSpliter = 0;
        
  for(int i = 0; i < mc.COLUMN_STYLE.size(); i++)
  {
   aryTextView[i] = new TextView(mContext);
   aryTextView[i].setTextSize(DataCell.FontSize);
   aryTextView[i].setPadding(5,5);
   aryTextView[i].setBackgroundColor(DataCell.BackgroundColor);
   aryTextView[i].setText(data.get(mc.COLUMN_STYLE.get(i).getFieldName()));
   aryTextView[i].setSingleLine(true);
   aryTextView[i].setGravity(DataCell.Gravity);

   addView(artTextView[i], new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            
    if(intCellSpliter < mc.COLUMN_STYLE.size())
    {
     mTxtContent = new cls_spliter2_view(getContext(),mc, i);
     mc.SPLITER_VIEW.get(i).add(mTxtContent);
     addView(mTxtContent,new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
     intCellSpliter++;
    }
  }
 }
    
 public void populate(cls_datatable.cls_datarow data)
 {
  for(int i = 0; i <  mc.COLUMN_STYLE.size(); i++)
  {
   artTextView[i].setWidth(mc.COLUMN_STYLE.get(i).getWitdh() * mc.SCALE);
   artTextView[i].setText(data.get(mc.COLUMN_STYLE.get(i).getFieldName()));
  }
 }
}
Customize a ListView is quite a common task, there are a lot of examples in the Internet demonstrate this so I will briefly explain this.
  • cls_item_view takes 3 parameters in constructor. The last parameter of data typecls_datatable.cls_datarow is the record to be displayed at each row
  • All the data population happen in the foor lop in the constructor. It is similar to the initHeader(). Each TextView will be separated by a Splitter.
Back to the cls_datagrid class, we now have couple of new things to add in:
  • LIST_VIEW and DATAGRID_ADAPTER in members_collection
  • initListView() which basically initialize the ListView
  • 2 statements: initListView(); and addView(mc.LIST_VIEW); in create()
public class cls_datagrid extends LinearLayout{

 private Context mContext;
 private members_collection mc;
 private String strNoDataText;
 private LinearLayout mDataGridHeader;

 class members_collection{
  public ArrayList<column> COLUMN_STYLE;
  public cls_datatable DATA_SOURCE;
  public ListView LIST_VIEW;
  public cls_datagrid_adapter DATAGRID_ADAPTER;
 }

 public static class column{
  
  private String strColumnName;
  private String strFieldName;
  private int intWidth;
  private int intIndex;
  
  public column(String DisplayName, String FieldName, int width)
  {
   strColumnName = DisplayName;
   strFieldName = FieldName;
   intWidth = width;
  }
  
  public void setIndex(int index)
  {
   intIndex = index;
  }
  
  public int getIndex()
  {
   return intIndex;
  }
  
  public String getColumnName()
  {
   return strColumnName;
  }
  
  public String getFieldName()
  {
   return strFieldName;
  }
  
  public int getWitdh()
  {
   return intWidth;
  }
  
  public void setWidth(int width){
   intWidth = width;
  }
 }

 public cls_datagrid(Context context , AttributeSet attrs) throws Exception {        
  super(context, attrs);
  setOrientation(VERTICAL);
  mContext = context;        
  mc = new members_collection();
  mc.COLUMN_STYLE = new ArrayList<column>();
 }

 public void addColumnStyle(column columnStyle)
 {
  mc.COLUMN_STYLE.add(columnStyle);
 }

 public void setNoDataText(String strText)
 {
  strNoDataText = strText;
 }

 public void refresh()
 {
  if(mDataGridHeader == null)create();
 }

 public void create()
 {
  mDataGridHeader = new LinearLayout(mContext);
  mDataGridHeader.setOrientation(LinearLayout.HORIZONTAL);
  mc.LIST_VIEW = new ListView(mContext);

  initHeader();
  initListView();

  addView(mDataGridHeader);
  addView(mc.LIST_VIEW);
 }

 private void initHeader()
 {
  cls_spliter_view Spliter;
  cls_header_view HeaderView;
  int intCellSpliter = 0;
  
  for(int i = 0; i < mc.COLUMN_STYLE.size(); i++)
  {  
   HeaderView = new cls_header_view(getContext(), mc);
   HeaderView.setText((mc.COLUMN_STYLE.get(i)).getColumnName());
   HeaderView.setTag(mc.COLUMN_STYLE.get(i));
   HeaderView.setWidth(mc.COLUMN_STYLE.get(i).getWitdh());
   mDataGridHeader.addView(HeaderView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
      
   if(intCellSpliter < mc.COLUMN_STYLE.size())
   {
    Spliter = new cls_spliter_view(getContext(), mc, i);
    mDataGridHeader.addView(Spliter,new LinearLayout.LayoutParams(5,5));
    intCellSpliter++;
   }
  }
 }
 
 private void initListView()
 {
  mc.DATAGRID_ADAPTER = new cls_datagrid_adapter(getContext(), mc);
  mc.LIST_VIEW.setDividerHeight(2);
  mc.LIST_VIEW.setAdapter(mc.DATAGRID_ADAPTER);
 }

 public void setDataSource(cls_datatable data)
 {
  mc.DATA_SOURCE = data;
 }

}