diff --git a/app/build.gradle b/app/build.gradle index 350d0ab..f6f6836 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -24,4 +24,6 @@ dependencies { compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:design:22.2.0' compile 'com.android.support:recyclerview-v7:22.2.0' + compile 'com.github.bumptech.glide:glide:3.6.0' + compile 'com.android.support:support-v4:22.2.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b52b269..516f35f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + + diff --git a/app/src/main/java/android/coding/interview/makeitawesome/Picture.java b/app/src/main/java/android/coding/interview/makeitawesome/Picture.java new file mode 100644 index 0000000..35425c1 --- /dev/null +++ b/app/src/main/java/android/coding/interview/makeitawesome/Picture.java @@ -0,0 +1,31 @@ +package android.coding.interview.makeitawesome; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; + +/** + * Created by pinghelram on 27/07/15. + */ +public class Picture extends Activity { + ImageView myImage; + public static final String IMAGEURL = "image_url"; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_image); + myImage = (ImageView) findViewById(R.id.iv_image); + + Intent myIntent = getIntent(); + String url = myIntent.getStringExtra(IMAGEURL); + + Glide.with(this).load(url).into(myImage); + } + + + + +} diff --git a/app/src/main/java/android/coding/interview/makeitawesome/adapter/PhotosAdapter.java b/app/src/main/java/android/coding/interview/makeitawesome/adapter/PhotosAdapter.java index 366168c..6f16266 100644 --- a/app/src/main/java/android/coding/interview/makeitawesome/adapter/PhotosAdapter.java +++ b/app/src/main/java/android/coding/interview/makeitawesome/adapter/PhotosAdapter.java @@ -1,12 +1,21 @@ package android.coding.interview.makeitawesome.adapter; import android.coding.interview.makeitawesome.R; +import android.coding.interview.makeitawesome.data.ImageData; +import android.content.Context; +import android.media.Image; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.TextView; +import com.bumptech.glide.Glide; + +import org.w3c.dom.Text; + +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -14,10 +23,27 @@ * adapter keeping data for list of photos */ public class PhotosAdapter extends RecyclerView.Adapter { - + // TODO this is a dummy data that you have to replace. You probably need List of some objects representing pictures // rather than just strings - private List mData = Arrays.asList("dummy 1", "dummy 2", "dummy 3", "dummy 4", "etc"); + //private List mData = Arrays.asList("dummy 1", "dummy 2", "dummy 3", "dummy 4", "etc"); + private List mData; + private Context context; + private ClickListener clickListener; + + public PhotosAdapter(ArrayList mData, Context context){ + this.mData = mData; + this.context = context; + } + + public void setClickListener(ClickListener clickListener){ + this.clickListener = clickListener; + } + + public void insertmData(ImageData mImage, int position){ + mData.add(position, mImage); + notifyItemInserted(position); + } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int i) { @@ -27,7 +53,10 @@ public ViewHolder onCreateViewHolder(ViewGroup parent, int i) { @Override public void onBindViewHolder(ViewHolder holder, int i) { - holder.mText.setText(mData.get(i)); + //holder.mText.setText(mData.get(i)); + holder.getImageTitle().setText(mData.get(i).getTitle()); + //holder.getTv_name_search().setImageResource(R.drawable.abc_ab_share_pack_mtrl_alpha); + Glide.with(context).load(mData.get(i).getThumbnailUrl()).into(holder.getIv_image()); } @Override @@ -35,11 +64,34 @@ public int getItemCount() { return mData.size(); } - public static class ViewHolder extends RecyclerView.ViewHolder { - final TextView mText; + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + private final TextView mTitle; + private final ImageView mImageView; + public ViewHolder(View itemView) { super(itemView); - mText = (TextView) itemView; + mTitle = (TextView) itemView.findViewById(R.id.tv_image_title); + mImageView = (ImageView) itemView.findViewById(R.id.iv_image); + itemView.setOnClickListener(this); + } + + public TextView getImageTitle() { + return mTitle; + } + + public ImageView getIv_image() { + return mImageView; } + + @Override + public void onClick(View v) { + if (clickListener!= null){ + clickListener.itemClicked(v, getAdapterPosition()); + } + } + } + + public interface ClickListener { + void itemClicked(View view, int position); } } diff --git a/app/src/main/java/android/coding/interview/makeitawesome/data/ImageData.java b/app/src/main/java/android/coding/interview/makeitawesome/data/ImageData.java new file mode 100644 index 0000000..97d0696 --- /dev/null +++ b/app/src/main/java/android/coding/interview/makeitawesome/data/ImageData.java @@ -0,0 +1,32 @@ +package android.coding.interview.makeitawesome.data; + +/** + * Created by pinghelram on 27/07/15. + */ +public class ImageData { + String title, url, thumbnailUrl; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getThumbnailUrl() { + return thumbnailUrl; + } + + public void setThumbnailUrl(String thumbnailUrl) { + this.thumbnailUrl = thumbnailUrl; + } +} diff --git a/app/src/main/java/android/coding/interview/makeitawesome/fragment/PicturesFragment.java b/app/src/main/java/android/coding/interview/makeitawesome/fragment/PicturesFragment.java index 32a7c34..ce4d882 100644 --- a/app/src/main/java/android/coding/interview/makeitawesome/fragment/PicturesFragment.java +++ b/app/src/main/java/android/coding/interview/makeitawesome/fragment/PicturesFragment.java @@ -1,22 +1,45 @@ package android.coding.interview.makeitawesome.fragment; +import android.coding.interview.makeitawesome.Picture; import android.coding.interview.makeitawesome.R; import android.coding.interview.makeitawesome.adapter.PhotosAdapter; +import android.coding.interview.makeitawesome.data.ImageData; +import android.coding.interview.makeitawesome.utils.DividerItemDecoration; +import android.coding.interview.makeitawesome.utils.JSONResponseHandler; +import android.coding.interview.makeitawesome.utils.QueryResult; +import android.content.Intent; +import android.location.Location; +import android.net.http.AndroidHttpClient; +import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; + +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpGet; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Map; /** * This is Your TASK:
* This is a fragment where you need to show list of pictures and details fetched from API
* Most of skeleton for showing UI is implemented. You need to take care of getting the data from server, updating adapter and displaying results */ -public class PicturesFragment extends Fragment { +public class PicturesFragment extends Fragment implements PhotosAdapter.ClickListener{ + private static final String TAG = "PicturesFragment"; + private final static String URL = "http://jsonplaceholder.typicode.com/photos/"; + private PhotosAdapter mPhotosAdapter; + protected RecyclerView mRecyclerView; + private ArrayList mData = new ArrayList<>(); public static Fragment newInstance() { return new PicturesFragment(); @@ -25,13 +48,87 @@ public static Fragment newInstance() { @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - RecyclerView rv = (RecyclerView) inflater.inflate(R.layout.pictures_list_fragment, container, false); - setupRecyclerView(rv); - return rv; + mPhotosAdapter = new PhotosAdapter(mData, getActivity()); + + //todo if there's no results show it + //tv_no_results = (TextView) findViewById(R.id.tv_no_results); + + new HttpGetTask().execute(); //start background task + + + mRecyclerView = (RecyclerView) inflater.inflate(R.layout.pictures_list_fragment, container, false); + setupRecyclerView(mRecyclerView); + return mRecyclerView; } private void setupRecyclerView(RecyclerView recyclerView) { + mRecyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL_LIST)); + mRecyclerView.setAdapter(mPhotosAdapter); + mPhotosAdapter.setClickListener(this); recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext())); - recyclerView.setAdapter(new PhotosAdapter()); + } + + @Override + public void itemClicked(View view, int position) { + Intent intent = new Intent(getActivity(), Picture.class); + String url = mData.get(position).getUrl(); + + intent.putExtra(Picture.IMAGEURL, url); + startActivity(intent); + } + + /** + * download the data + */ + private class HttpGetTask extends AsyncTask> { + AndroidHttpClient mClient = AndroidHttpClient.newInstance(""); + + + @Override + protected ArrayList doInBackground(Void... unused) { + Log.v(TAG, "doInBackground"); + + HttpGet request = new HttpGet(URL); + JSONResponseHandler searchresponseHandler = new JSONResponseHandler(); + + try { + return mClient.execute(request, searchresponseHandler); + } catch (ClientProtocolException exception) { + exception.printStackTrace(); + } catch (IOException ioexception) { + ioexception.printStackTrace(); + } finally { + if (mClient != null) mClient.close(); + } + return null; + } + + @Override + protected void onPostExecute(ArrayList result) { + Log.v(TAG, "onPostExecute"); + ArrayList searchResults = new ArrayList<>(); + + if (mClient != null && result != null) { + Log.v(TAG, "search complete"); + /*for (Map.Entry mLibraryItem : result.getphotos().entrySet()) { + searchResults.add(mLibraryItem.getValue()); + }*/ + //for (ImageData data : ) + for (ImageData mData : result){ + searchResults.add(mData); + } + } + if ((result == null || result.size() == 0)) { + //todo: if there's no results show no results found + //tv_no_results.setVisibility(View.VISIBLE); + } else { + //tv_no_results.setVisibility(View.GONE); + int counter = 0; + for (ImageData imageData: searchResults) { + mPhotosAdapter.insertmData(imageData, counter); + counter++; + } + } + } } } diff --git a/app/src/main/java/android/coding/interview/makeitawesome/utils/DividerItemDecoration.java b/app/src/main/java/android/coding/interview/makeitawesome/utils/DividerItemDecoration.java new file mode 100644 index 0000000..fadb4de --- /dev/null +++ b/app/src/main/java/android/coding/interview/makeitawesome/utils/DividerItemDecoration.java @@ -0,0 +1,103 @@ +package android.coding.interview.makeitawesome.utils; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +/* + * Copyright (C) 2014 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. + */ +public class DividerItemDecoration extends RecyclerView.ItemDecoration { + + private static final int[] ATTRS = new int[]{ + android.R.attr.listDivider + }; + + public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; + + public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; + + private Drawable mDivider; + + private int mOrientation; + + public DividerItemDecoration(Context context, int orientation) { + final TypedArray a = context.obtainStyledAttributes(ATTRS); + mDivider = a.getDrawable(0); + a.recycle(); + setOrientation(orientation); + } + + public void setOrientation(int orientation) { + if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { + throw new IllegalArgumentException("invalid orientation"); + } + mOrientation = orientation; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent) { + if (mOrientation == VERTICAL_LIST) { + drawVertical(c, parent); + } else { + drawHorizontal(c, parent); + } + } + + public void drawVertical(Canvas c, RecyclerView parent) { + final int left = parent.getPaddingLeft(); + final int right = parent.getWidth() - parent.getPaddingRight(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + final int top = child.getBottom() + params.bottomMargin; + final int bottom = top + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + public void drawHorizontal(Canvas c, RecyclerView parent) { + final int top = parent.getPaddingTop(); + final int bottom = parent.getHeight() - parent.getPaddingBottom(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int left = child.getRight() + params.rightMargin; + final int right = left + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + @Override + public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { + if (mOrientation == VERTICAL_LIST) { + outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); + } else { + outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/android/coding/interview/makeitawesome/utils/JSONResponseHandler.java b/app/src/main/java/android/coding/interview/makeitawesome/utils/JSONResponseHandler.java new file mode 100644 index 0000000..826b66e --- /dev/null +++ b/app/src/main/java/android/coding/interview/makeitawesome/utils/JSONResponseHandler.java @@ -0,0 +1,63 @@ +package android.coding.interview.makeitawesome.utils; + +/** + * Created by pinghelram on 03/03/15. + */ + +import android.coding.interview.makeitawesome.data.ImageData; +import android.util.Log; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.impl.client.BasicResponseHandler; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * parse the results + */ +public class JSONResponseHandler implements ResponseHandler> { + private static final String TAG = "JSONResponseHandler"; + + private static final String ALBUMID = "albumId"; + //private static final String ID = "id"; + private static final String TITLE = "title"; + private static final String URL = "url"; + private static final String THUMBNAIL_URL = "thumbnailUrl"; + + @Override + public ArrayList handleResponse(HttpResponse response) throws ClientProtocolException, IOException { + //QueryResult mQueryResult = new QueryResult(); + ArrayList result = new ArrayList<>(); + if (response.getStatusLine().getStatusCode() == 200){ + String JSONResponse = new BasicResponseHandler().handleResponse(response); + try { + JSONArray responseObject = (JSONArray) new JSONTokener(JSONResponse).nextValue(); + Log.v(TAG, "responseObject" + responseObject.toString()); + for (int i = 0; i < responseObject.length(); i++){ + JSONObject albumObject = (JSONObject) responseObject.get(i); + ImageData imageData = new ImageData(); + imageData.setTitle(albumObject.optString(TITLE)); + imageData.setThumbnailUrl(albumObject.optString(THUMBNAIL_URL)); + imageData.setUrl(albumObject.optString(URL)); + result.add(imageData); + + } + //mQueryResult.setPoints(result); + Log.v(TAG, "got here"); + return result; + } catch (JSONException e) { + e.printStackTrace(); + } + } + return null; + } +} diff --git a/app/src/main/java/android/coding/interview/makeitawesome/utils/QueryResult.java b/app/src/main/java/android/coding/interview/makeitawesome/utils/QueryResult.java new file mode 100644 index 0000000..4107ec9 --- /dev/null +++ b/app/src/main/java/android/coding/interview/makeitawesome/utils/QueryResult.java @@ -0,0 +1,21 @@ +package android.coding.interview.makeitawesome.utils; + +import android.coding.interview.makeitawesome.data.ImageData; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * Created by pinghelram on 27/07/15. + */ +public class QueryResult { + private ArrayList photos = new ArrayList<>(); + + public ArrayList getphotos() { + return photos; + } + + public void setPoints(ArrayList photos) { + this.photos = photos; + } +} diff --git a/app/src/main/res/layout/activity_image.xml b/app/src/main/res/layout/activity_image.xml new file mode 100644 index 0000000..10a3b58 --- /dev/null +++ b/app/src/main/res/layout/activity_image.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/picture_list_item.xml b/app/src/main/res/layout/picture_list_item.xml index 6b5a158..8839069 100644 --- a/app/src/main/res/layout/picture_list_item.xml +++ b/app/src/main/res/layout/picture_list_item.xml @@ -1,11 +1,25 @@ - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:clickable="true" + android:layout_margin="16dp"> + + + + + + + +