diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100644 index 0000000..6c65c9e --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar new file mode 100644 index 0000000..99e063b Binary files /dev/null and b/libs/android-support-v4.jar differ diff --git a/lint.xml b/lint.xml new file mode 100644 index 0000000..f4be1f0 --- /dev/null +++ b/lint.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/proguard.cfg b/proguard.cfg new file mode 100644 index 0000000..b1cdf17 --- /dev/null +++ b/proguard.cfg @@ -0,0 +1,40 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers class * extends android.app.Activity { + public void *(android.view.View); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/project.properties b/project.properties new file mode 100644 index 0000000..730e911 --- /dev/null +++ b/project.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "ant.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-14 diff --git a/res/drawable-hdpi/ic_1.jpg b/res/drawable-hdpi/ic_1.jpg new file mode 100644 index 0000000..4ae7563 Binary files /dev/null and b/res/drawable-hdpi/ic_1.jpg differ diff --git a/res/drawable-hdpi/ic_10.jpg b/res/drawable-hdpi/ic_10.jpg new file mode 100644 index 0000000..e707f48 Binary files /dev/null and b/res/drawable-hdpi/ic_10.jpg differ diff --git a/res/drawable-hdpi/ic_2.jpg b/res/drawable-hdpi/ic_2.jpg new file mode 100644 index 0000000..0b8aa94 Binary files /dev/null and b/res/drawable-hdpi/ic_2.jpg differ diff --git a/res/drawable-hdpi/ic_3.jpg b/res/drawable-hdpi/ic_3.jpg new file mode 100644 index 0000000..c7e1ccb Binary files /dev/null and b/res/drawable-hdpi/ic_3.jpg differ diff --git a/res/drawable-hdpi/ic_4.jpg b/res/drawable-hdpi/ic_4.jpg new file mode 100644 index 0000000..951633d Binary files /dev/null and b/res/drawable-hdpi/ic_4.jpg differ diff --git a/res/drawable-hdpi/ic_5.jpg b/res/drawable-hdpi/ic_5.jpg new file mode 100644 index 0000000..26136cc Binary files /dev/null and b/res/drawable-hdpi/ic_5.jpg differ diff --git a/res/drawable-hdpi/ic_6.jpg b/res/drawable-hdpi/ic_6.jpg new file mode 100644 index 0000000..dbd547e Binary files /dev/null and b/res/drawable-hdpi/ic_6.jpg differ diff --git a/res/drawable-hdpi/ic_7.jpg b/res/drawable-hdpi/ic_7.jpg new file mode 100644 index 0000000..dcd43af Binary files /dev/null and b/res/drawable-hdpi/ic_7.jpg differ diff --git a/res/drawable-hdpi/ic_8.jpg b/res/drawable-hdpi/ic_8.jpg new file mode 100644 index 0000000..d10ad8a Binary files /dev/null and b/res/drawable-hdpi/ic_8.jpg differ diff --git a/res/drawable-hdpi/ic_9.jpg b/res/drawable-hdpi/ic_9.jpg new file mode 100644 index 0000000..f8d6e7a Binary files /dev/null and b/res/drawable-hdpi/ic_9.jpg differ diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/res/drawable-hdpi/ic_launcher.png differ diff --git a/res/drawable-ldpi/ic_launcher.png b/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/res/drawable-ldpi/ic_launcher.png differ diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/res/drawable-mdpi/ic_launcher.png differ diff --git a/res/layout/item.xml b/res/layout/item.xml new file mode 100644 index 0000000..11f822a --- /dev/null +++ b/res/layout/item.xml @@ -0,0 +1,9 @@ + + diff --git a/res/layout/items_list.xml b/res/layout/items_list.xml new file mode 100644 index 0000000..b0a432b --- /dev/null +++ b/res/layout/items_list.xml @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml new file mode 100644 index 0000000..5038561 --- /dev/null +++ b/res/values/strings.xml @@ -0,0 +1,4 @@ + + + PinterestListView + \ No newline at end of file diff --git a/src/com/vladimir/pinterestlistview/ItemsActivity.java b/src/com/vladimir/pinterestlistview/ItemsActivity.java new file mode 100644 index 0000000..036d36b --- /dev/null +++ b/src/com/vladimir/pinterestlistview/ItemsActivity.java @@ -0,0 +1,122 @@ +package com.vladimir.pinterestlistview; + +import android.app.Activity; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnTouchListener; +import android.widget.AbsListView; +import android.widget.AbsListView.OnScrollListener; +import android.widget.ListView; + +import com.vladimir.pinterestlistview.adapters.ItemsAdapter; + +public class ItemsActivity extends Activity { + + private final String TAG = "FeedActivity"; + + private ListView listViewLeft; + private ListView listViewRight; + private ItemsAdapter leftAdapter; + private ItemsAdapter rightAdapter; + + int[] leftViewsHeights; + int[] rightViewsHeights; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.items_list); + + listViewLeft = (ListView) findViewById(R.id.list_view_left); + listViewRight = (ListView) findViewById(R.id.list_view_right); + + loadItems(); + + listViewLeft.setOnTouchListener(touchListener); + listViewRight.setOnTouchListener(touchListener); + listViewLeft.setOnScrollListener(scrollListener); + listViewRight.setOnScrollListener(scrollListener); + } + + OnTouchListener touchListener = new OnTouchListener() { + boolean dispatched = false; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (v.equals(listViewLeft) && !dispatched) { + dispatched = true; + listViewRight.dispatchTouchEvent(event); + } else if (v.equals(listViewRight) && !dispatched) { + dispatched = true; + listViewLeft.dispatchTouchEvent(event); + } + + dispatched = false; + return false; + } + }; + + OnScrollListener scrollListener = new OnScrollListener() { + + @Override + public void onScrollStateChanged(AbsListView v, int scrollState) { + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, + int visibleItemCount, int totalItemCount) { + + if (view.getChildAt(0) != null) { + if (view.equals(listViewLeft) ){ + leftViewsHeights[view.getFirstVisiblePosition()] = view.getChildAt(0).getHeight(); + + int h = 0; + for (int i = 0; i < listViewRight.getFirstVisiblePosition(); i++) { + h += rightViewsHeights[i]; + } + + int hi = 0; + for (int i = 0; i < listViewLeft.getFirstVisiblePosition(); i++) { + hi += leftViewsHeights[i]; + } + + int top = h - hi + view.getChildAt(0).getTop(); + listViewRight.setSelectionFromTop(listViewRight.getFirstVisiblePosition(), top); + } else if (view.equals(listViewRight)) { + rightViewsHeights[view.getFirstVisiblePosition()] = view.getChildAt(0).getHeight(); + + int h = 0; + for (int i = 0; i < listViewLeft.getFirstVisiblePosition(); i++) { + h += leftViewsHeights[i]; + } + + int hi = 0; + for (int i = 0; i < listViewRight.getFirstVisiblePosition(); i++) { + hi += rightViewsHeights[i]; + } + + int top = h - hi + view.getChildAt(0).getTop(); + listViewLeft.setSelectionFromTop(listViewLeft.getFirstVisiblePosition(), top); + } + + } + + } + }; + + private void loadItems(){ + Integer[] leftItems = new Integer[]{R.drawable.ic_1, R.drawable.ic_2, R.drawable.ic_3, R.drawable.ic_4, R.drawable.ic_5}; + Integer[] rightItems = new Integer[]{R.drawable.ic_6, R.drawable.ic_7, R.drawable.ic_8, R.drawable.ic_9, R.drawable.ic_10}; + + leftAdapter = new ItemsAdapter(this, R.layout.item, leftItems); + rightAdapter = new ItemsAdapter(this, R.layout.item, rightItems); + listViewLeft.setAdapter(leftAdapter); + listViewRight.setAdapter(rightAdapter); + + leftViewsHeights = new int[leftItems.length]; + rightViewsHeights = new int[rightItems.length]; + } + + +} \ No newline at end of file diff --git a/src/com/vladimir/pinterestlistview/adapters/ItemsAdapter.java b/src/com/vladimir/pinterestlistview/adapters/ItemsAdapter.java new file mode 100644 index 0000000..d1fc21a --- /dev/null +++ b/src/com/vladimir/pinterestlistview/adapters/ItemsAdapter.java @@ -0,0 +1,78 @@ +package com.vladimir.pinterestlistview.adapters; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.RelativeLayout; + +public class ItemsAdapter extends ArrayAdapter{ + + Context context; + LayoutInflater inflater; + int layoutResourceId; + int imageWidth; + + public ItemsAdapter(Context context, int layoutResourceId, Integer[] items) { + super(context, layoutResourceId, items); + this.context = context; + this.layoutResourceId = layoutResourceId; + + int width = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth(); + int margin = (int)convertDpToPixel(10f, (Activity)context); + imageWidth = (width - (3 * margin)); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ImageView row = (ImageView) convertView; + ItemHolder holder; + Integer item = getItem(position); + + if (row == null) { + holder = new ItemHolder(); + inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + row = (ImageView) inflater.inflate(layoutResourceId, parent, false); + holder.itemImage = row; + } else { + holder = (ItemHolder) row.getTag(); + } + + row.setTag(holder); + setImageBitmap(item, holder.itemImage); + return row; + } + + + private void setImageBitmap(Integer item, ImageView imageView){ + Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), item); + if (imageWidth != 0){ + float i = ((float)imageWidth)/((float)bitmap.getWidth()); + float imageHeight = i * (bitmap.getHeight()); + RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) imageView.getLayoutParams(); + params.height = (int) imageHeight; + params.width = imageWidth; + imageView.setLayoutParams(params); + } + imageView.setImageBitmap(bitmap); + } + + public static float convertDpToPixel(float dp, Context context){ + Resources resources = context.getResources(); + DisplayMetrics metrics = resources.getDisplayMetrics(); + float px = dp * (metrics.densityDpi/160f); + return px; + } + + public static class ItemHolder + { + ImageView itemImage; + } +} \ No newline at end of file