diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9a63ea85..c68dcaa01 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,13 +8,18 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/android/android_me/ui/AndroidMeActivity.java b/app/src/main/java/com/example/android/android_me/ui/AndroidMeActivity.java index 7e5d243b0..dd0a6ba78 100644 --- a/app/src/main/java/com/example/android/android_me/ui/AndroidMeActivity.java +++ b/app/src/main/java/com/example/android/android_me/ui/AndroidMeActivity.java @@ -16,29 +16,53 @@ package com.example.android.android_me.ui; +import android.support.v4.app.FragmentManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import com.example.android.android_me.R; +import com.example.android.android_me.data.AndroidImageAssets; // This activity will display a custom Android image composed of three body parts: head, body, and legs public class AndroidMeActivity extends AppCompatActivity { - // TODO (1) Create a layout file that displays one body part image named fragment_body_part.xml - // This layout should contain a single ImageView - - // TODO (2) Create a new class called BodyPartFragment to display an image of an Android-Me body part - // In this class, you'll need to implement an empty constructor and the onCreateView method - // TODO (3) Show the first image in the list of head images - // Soon, you'll update this image display code to show any image you want - - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_android_me); - // TODO (5) Create a new BodyPartFragment instance and display it using the FragmentManager + // 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(); + } + } } diff --git a/app/src/main/java/com/example/android/android_me/ui/BodyPartFragment.java b/app/src/main/java/com/example/android/android_me/ui/BodyPartFragment.java new file mode 100644 index 000000000..225bdb061 --- /dev/null +++ b/app/src/main/java/com/example/android/android_me/ui/BodyPartFragment.java @@ -0,0 +1,120 @@ +/* +* Copyright (C) 2017 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.example.android.android_me.ui; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.example.android.android_me.R; + +import java.util.ArrayList; +import java.util.List; + +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 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 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) mImageIds); + currentState.putInt(LIST_INDEX, mListIndex); + } + + +} diff --git a/app/src/main/java/com/example/android/android_me/ui/MainActivity.java b/app/src/main/java/com/example/android/android_me/ui/MainActivity.java new file mode 100755 index 000000000..d8442038b --- /dev/null +++ b/app/src/main/java/com/example/android/android_me/ui/MainActivity.java @@ -0,0 +1,43 @@ +/* +* Copyright (C) 2017 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.example.android.android_me.ui; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.widget.Toast; + +import com.example.android.android_me.R; + +// This activity is responsible for displaying the master list of all images +// Implement the MasterListFragment callback, OnImageClickListener +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(); + } + +} diff --git a/app/src/main/java/com/example/android/android_me/ui/MasterListFragment.java b/app/src/main/java/com/example/android/android_me/ui/MasterListFragment.java new file mode 100755 index 000000000..82095b898 --- /dev/null +++ b/app/src/main/java/com/example/android/android_me/ui/MasterListFragment.java @@ -0,0 +1,94 @@ +/* +* Copyright (C) 2017 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.example.android.android_me.ui; + +import android.content.Context; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.GridView; + +import com.example.android.android_me.R; +import com.example.android.android_me.data.AndroidImageAssets; + + +// 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; + } + +} diff --git a/app/src/main/res/layout/activity_android_me.xml b/app/src/main/res/layout/activity_android_me.xml index 71bd30adb..c65bc721b 100644 --- a/app/src/main/res/layout/activity_android_me.xml +++ b/app/src/main/res/layout/activity_android_me.xml @@ -29,9 +29,24 @@ android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> - - + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100755 index 000000000..70ace7801 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_body_part.xml b/app/src/main/res/layout/fragment_body_part.xml new file mode 100644 index 000000000..1455ea00b --- /dev/null +++ b/app/src/main/res/layout/fragment_body_part.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_master_list.xml b/app/src/main/res/layout/fragment_master_list.xml new file mode 100755 index 000000000..af422d9e0 --- /dev/null +++ b/app/src/main/res/layout/fragment_master_list.xml @@ -0,0 +1,27 @@ + + + + + +