So I thought I would try out Parcelling in Android today, quickly mocked this up:
public class Unit implements Parcelable {
private String unitName;
private int view;
private Double value;
/**
* Constructor
*/
public Unit() { }
/**
* Constructor
* @param unitName
*/
public Unit(String unitName) {
this.unitName = unitName;
}
/**
* Constructor
* @param unitName
* @param view
*/
public Unit(String unitName, int view, Double value) {
this.unitName = unitName;
this.view = view;
this.value = value;
}
/**
* Set the name of the unit of measurement
* @param name
*/
public void setUnitName(String name) {
this.unitName = name;
}
/**
* Set whether the unit of measurement is viewable
* @param view
*/
public void setView(int view) {
this.view = view;
}
/**
* Set the value of the unit
* @param value
*/
public void setValue(Double value) { this.value = value; }
/**
* Return the unit name
* @return unitName
*/
public String getUnitName() {
return unitName;
}
/**
* Return whether the unit is viewable
* @return view
*/
public int getView() {
return view;
}
/**
* Return the value of this unit
* @return value
*/
public Double getValue() { return value; }
/**
* Methods for parcelling here
*/
/**
* Constructor for parcelling
* @param in
*/
public Unit(Parcel in) {
//
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(new ArrayList<Unit>() {
//huh?
});
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Unit createFromParcel(Parcel in) {
return new Unit(in);
}
public Unit[] newArray(int size) {
return new Unit[size];
}
};
}
As you will probably note my implementation of the methods that I override from the Parcelable
interface are incomplete. But Carrying on, this class is just an object that is supposed to be parcelable to another class.
Now here is my main activity:
public class MyActivity extends Activity {
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button send = (Button) findViewById(R.id.sendParcel);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ArrayList<Unit> units = getUnits();
Intent i = new Intent(getApplicationContext(), UnitListActivity.class);
i.putParcelableArrayListExtra("units", units);
startActivity(i);
}
});
}
/**
* Return an arraylist of units
* @return units
*/
public ArrayList<Unit> getUnits() {
ArrayList<Unit> units = new ArrayList<Unit>();
units.add(new Unit("acceleration", 1, 56.45));
units.add(new Unit("kilograms", 0, 5830.54345));
units.add(new Unit("metres", 1, 543.54));
units.add(new Unit("kilometres", 1, 32.43));
units.add(new Unit("grams", 1, 453.654));
units.add(new Unit("kilograms", 0, 8.5));
units.add(new Unit("litres", 1, 344.3));
units.add(new Unit("millilitres", 0, 4543.879));
units.add(new Unit("decimeter", 1, 5084903.564567));
return units;
}
}
Basically there is a button when pressed will create an Intent
and try to parcel an ArrayList
with the Object that implements the Parcelable
interface. The class it is trying to pass it to is a ListActivity
the code for which is here:
public class UnitListActivity extends ListActivity {
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
UnitListAdapter mTypeAdapter = new UnitListAdapter(getApplicationContext(), bundle.getParcelableArrayList("units"));
setListAdapter(mTypeAdapter);
}
}
I made this adapter for the ListActivity
here:
public class UnitListAdapter extends ArrayAdapter<Unit> {
private ArrayList<Unit> unitsList;
private Context context;
public UnitListAdapter(Context c, ArrayList<Unit> units) {
super(c, R.layout.unit_values, units);
this.context = c;
this.unitsList = units;
}
@Override
public View getView(int position, View convertView, ViewGroup parentView) {
View view = null;
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflator.inflate(R.layout.unit_values, null);
TextView textView = (TextView) view.findViewById(R.id.unit_name);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.check);
//check box set on check changed listener if I get this far for later
if(unitsList.get(position).getView() == 1) {
textView.setText(unitsList.get(position).getUnitName());
checkBox.setChecked(true);
} else {
textView.setText(unitsList.get(position).getUnitName());
}
return view;
}
}
Now what I don't understand is why in the ListActivity
this line:
UnitListAdapter mTypeAdapter = new UnitListAdapter(getApplicationContext(), bundle.getParcelableArrayList("units"));
complains that instead of getting Unit objects, it is getting Parcelable
objects, since class Unit
implements them.
Does this mean that in my adapter I have to change the list to expect Parcelable objects and if, it means it is going to change how I read them??
I also don't understand writeToParcel
, the documentation says that it will flatten the object, so I thought that since I want to flatten the the list I am going to need the writeList
method, but what after that? it seems like it is flattening the Unit object not the list.
This also leads me to ask about the constructor:
public Unit(Parcel in) {
//
}
I am guessing that I need to do something like this:
readTypedList()
- I don't understand why I have to do this since I will be creating parcels. So I am not sure how to go about implementing this thing...I would really like insight into how parcelling is working, I didn't find the documentation that helpful and how in this example it would work successfully. Help and advice is very much appreciated.