Creating and using compound components

For the National Weather Service application I’m working on, initially I created the main display using a dynamically created table. One of the problems with that is that if I want to add more data to be displayed to the user, it would become very complicated quickly. So, I needed another way to display the repetitive data. My solution is to create a compound component.

The original table layout had one row for the days of the week, another row for the graphical images, another row for the day high temperatures, and the final row for the day low temperatures. So, I created a new component made up of a TextView, an ImageView, followed by 2 more TextViews. Here’s the layout xml:

LinearLayout android:id="@+id/llTempDisp"  xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="60dip"
    android:layout_height="120dip" android:orientation="vertical"
    TextView android:id="@+id/tvDate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"
    ImageView android:id="@+id/ivIcon" android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/ic_launcher"
    TextView  android:id="@+id/tvTempHigh" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"
    TextView  android:id="@+id/tvTempLow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"
/LinearLayout

Declare a class that extends LinearLayout

public class TempCompoundView extends LinearLayout {
	public TempCompoundView(Context context) {
		super(context);
	}

	public TempCompoundView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
}

Override the constructor to inflate the layout resource using the inflate method from the LayoutInflate system service. And, get references to the child controls.

public class TempCompoundView extends LinearLayout {

	TextView tvDate;
	ImageView ivIcon;
	TextView tvTempHigh;
	TextView tvTempLow;

	public TempCompoundView(Context context) {
		super(context);
		// Inflate the view from layout resource
		String infService = Context.LAYOUT_INFLATER_SERVICE;
		LayoutInflater li;
		li = (LayoutInflater)getContext().getSystemService(infService);
		li.inflate(R.layout.tempdisplay, this, true);
		tvDate = (TextView)findViewById(R.id.tvDate);
		ivIcon = (ImageView)findViewById(R.id.ivIcon);
		tvTempHigh = (TextView)findViewById(R.id.tvTempHigh);
		tvTempLow = (TextView)findViewById(R.id.tvTempLow);
	}

	public TempCompoundView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
}

Now, it’s time to use the control in the main Activity. Since I prefer to create the controls dynamically, there’s no reference to the new component in my main layout resource. Therefore, I have a reference to the LinearLayout that will be the parent of the component. In this case, it is llTCV.

TempCompoundView tcv;
for (int x = 0; x < 7; x++)
{
     tcv = new TempCompoundView(ServiceDemoActivity.this);
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
     Date tmpDate = null;
     try {
          tmpDate = sdf.parse(ndfdReader.dwml.data.timeLayout.get(0).startValidTime.get(x).value.substring(0, 10));
     } catch (ParseException e) {
	e.printStackTrace();
     }
     SimpleDateFormat sdf1 = new SimpleDateFormat("EEEE");
     tcv.tvDate.setText(sdf1.format(tmpDate).substring(0, 3));
     if (ndfdReader.dwml.data.parameters.get(0).conditionsIcon.get(0).bitmap.get(x) != null)
     {
          tcv.ivIcon.setImageBitmap(ndfdReader.dwml.data.parameters.get(0).conditionsIcon.get(0).bitmap.get(x));
          tcv.ivIcon.setLayoutParams(new LinearLayout.LayoutParams(80,80));
       	  tcv.ivIcon.setScaleType(ScaleType.FIT_CENTER);
      }
     tcv.tvTempHigh.setText(ndfdReader.dwml.data.parameters.get(0).temperature.get(0).value.get(x).value);
     try
     {
          int hi = Integer.parseInt(ndfdReader.dwml.data.parameters.get(0).temperature.get(0).value.get(x).value);
	  if (hi > 89)
		tcv.tvTempHigh.setTextColor(Color.RED);
          else if (hi > 49)
		tcv.tvTempHigh.setTextColor(Color.WHITE);
    	  else
		tcv.tvTempHigh.setTextColor(Color.BLUE);
     }
     catch (NumberFormatException nfe)
     {
     }
     tcv.tvTempLow.setText(ndfdReader.dwml.data.parameters.get(0).temperature.get(1).value.get(x).value);
     try
     {
          int lo = Integer.parseInt(ndfdReader.dwml.data.parameters.get(0).temperature.get(1).value.get(x).value);
	  if (lo > 89)
		tcv.tvTempLow.setTextColor(Color.RED);
	  else if (lo > 49)
		tcv.tvTempLow.setTextColor(Color.WHITE);
      	  else
		tcv.tvTempLow.setTextColor(Color.BLUE);
     }
     catch (NumberFormatException nfe)
     {
     }
     tcv.setPadding(10, 0, 10, 0);
     llTCV.addView(tcv);
}

That’s all it takes to create and use a compound component. Now, go create an awesome UI using this information.