// This fragment displays all of the AndroidMe images in one large list
// The list appears as a grid of images
public class MasterListFragment extends Fragment {
// Define a new interface OnImageClickListener that triggers a callback in the host activity
OnImageClickListener mCallback;
// OnImageClickListener interface, calls a method in the host activity named onImageSelected
public interface OnImageClickListener {
void onImageSelected(int position);
}
// Override onAttach to make sure that the container activity has implemented the callback
@Override
public void onAttach(Context context) {
super.onAttach(context);
// This makes sure that the host activity has implemented the callback interface
// If not, it throws an exception
try {
mCallback = (OnImageClickListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnImageClickListener");
}
}
// Mandatory empty constructor
public MasterListFragment() {
}
// Inflates the GridView of all AndroidMe images
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_master_list, container, false);
// Get a reference to the GridView in the fragment_master_list xml layout file
GridView gridView = (GridView) rootView.findViewById(R.id.images_grid_view);
// Create the adapter
// This adapter takes in the context and an ArrayList of ALL the image resources to display
MasterListAdapter mAdapter = new MasterListAdapter(getContext(), AndroidImageAssets.getAll());
// Set the adapter on the GridView
gridView.setAdapter(mAdapter);
// Set a click listener on the gridView and trigger the callback onImageSelected when an item is clicked
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// Trigger the callback method and pass in the position that was clicked
mCallback.onImageSelected(position);
}
});
// Return the root view
return rootView;
}
}
public class AndroidMeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_me);
// Only create new fragments when there is no previously saved state
if(savedInstanceState == null) {
// Create a new head BodyPartFragment
BodyPartFragment headFragment = new BodyPartFragment();
// Set the list of image id's for the head fragment and set the position to the second image in the list
headFragment.setImageIds(AndroidImageAssets.getHeads());
headFragment.setListIndex(1);
// Add the fragment to its container using a FragmentManager and a Transaction
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.head_container, headFragment)
.commit();
// Create and display the body and leg BodyPartFragments
BodyPartFragment bodyFragment = new BodyPartFragment();
bodyFragment.setImageIds(AndroidImageAssets.getBodies());
fragmentManager.beginTransaction()
.add(R.id.body_container, bodyFragment)
.commit();
BodyPartFragment legFragment = new BodyPartFragment();
legFragment.setImageIds(AndroidImageAssets.getLegs());
fragmentManager.beginTransaction()
.add(R.id.leg_container, legFragment)
.commit();
}
}
}
public class BodyPartFragment extends Fragment {
// Final Strings to store state information about the list of images and list index
public static final String IMAGE_ID_LIST = "image_ids";
public static final String LIST_INDEX = "list_index";
// Tag for logging
private static final String TAG = "BodyPartFragment";
// Variables to store a list of image resources and the index of the image that this fragment displays
private List<Integer> mImageIds;
private int mListIndex;
/**
* Mandatory empty constructor for the fragment manager to instantiate the fragment
*/
public BodyPartFragment() {
}
/**
* Inflates the fragment layout file and sets the correct resource for the image to display
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Load the saved state (the list of images and list index) if there is one
if(savedInstanceState != null) {
mImageIds = savedInstanceState.getIntegerArrayList(IMAGE_ID_LIST);
mListIndex = savedInstanceState.getInt(LIST_INDEX);
}
// Inflate the Android-Me fragment layout
View rootView = inflater.inflate(R.layout.fragment_body_part, container, false);
// Get a reference to the ImageView in the fragment layout
final ImageView imageView = (ImageView) rootView.findViewById(R.id.body_part_image_view);
// If a list of image ids exists, set the image resource to the correct item in that list
// Otherwise, create a Log statement that indicates that the list was not found
if(mImageIds != null){
// Set the image resource to the list item at the stored index
imageView.setImageResource(mImageIds.get(mListIndex));
// Set a click listener on the image view
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Increment position as long as the index remains <= the size of the image ids list
if(mListIndex < mImageIds.size()-1) {
mListIndex++;
} else {
// The end of list has been reached, so return to beginning index
mListIndex = 0;
}
// Set the image resource to the new list item
imageView.setImageResource(mImageIds.get(mListIndex));
}
});
} else {
Log.v(TAG, "This fragment has a null list of image id's");
}
// Return the rootView
return rootView;
}
// Setter methods for keeping track of the list images this fragment can display and which image
// in the list is currently being displayed
public void setImageIds(List<Integer> imageIds) {
mImageIds = imageIds;
}
public void setListIndex(int index) {
mListIndex = index;
}
/**
* Save the current state of this fragment
*/
@Override
public void onSaveInstanceState(Bundle currentState) {
currentState.putIntegerArrayList(IMAGE_ID_LIST, (ArrayList<Integer>) mImageIds);
currentState.putInt(LIST_INDEX, mListIndex);
}
}
public class MasterListAdapter extends BaseAdapter {
// Keeps track of the context and list of images to display
private Context mContext;
private List<Integer> mImageIds;
/**
* Constructor method
* @param imageIds The list of images to display
*/
public MasterListAdapter(Context context, List<Integer> imageIds) {
mContext = context;
mImageIds = imageIds;
}
/**
* Returns the number of items the adapter will display
*/
@Override
public int getCount() {
return mImageIds.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
/**
* Creates a new ImageView for each item referenced by the adapter
*/
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// If the view is not recycled, this creates a new ImageView to hold an image
imageView = new ImageView(mContext);
// Define the layout parameters
imageView.setAdjustViewBounds(true);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
// Set the image resource and return the newly created ImageView
imageView.setImageResource(mImageIds.get(position));
return imageView;
}
}
public class MainActivity extends AppCompatActivity implements MasterListFragment.OnImageClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Define the behavior for onImageSelected
public void onImageSelected(int position) {
// Create a Toast that displays the position that was clicked
Toast.makeText(this, "Position clicked = " + position, Toast.LENGTH_SHORT).show();
}
}