Search code examples
androidmonoparallax

Android parallax header effect


I want to recreate UI features such as the new G+ app, or the airbnb interface where the parallax effect is invoked solemnly on the header picture. My app uses (both) ListView and Gridview under different constraints, I was going over @CFlex tutorial for recreating it but couldn't achieve the effect.

Main.axml:

namespace ParallaxTest
{
[Activity(Label = "ParallaxTest", MainLauncher = true, Icon = "@drawable/icon")]
public class ParallaxTest : Activity, AbsListView.IOnScrollListener
{
    int count = 1;

    public GridView _gridView;
    public CustomImageView _imageView;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        _gridView = new GridView(this)
        {
            VerticalFadingEdgeEnabled = false,
            LayoutParameters =
                new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent,
                    LinearLayout.LayoutParams.MatchParent),
            CacheColorHint = Color.Transparent,
        };
        _gridView.SetOnScrollListener(this);
        _gridView.Adapter = new GridViewAdapter();
        _gridView.VerticalFadingEdgeEnabled = false;
        _gridView.SetColumnWidth(Resources.DisplayMetrics.WidthPixels / 2);
        _gridView.SetNumColumns(2);
        _gridView.SetVerticalSpacing(2);
        _gridView.SetHorizontalSpacing(2);
        _gridView.StretchMode = StretchMode.NoStretch;
        _gridView.SetGravity(GravityFlags.Center);
        _gridView.SetBackgroundColor(Color.Pink);
        _gridView.SetOnScrollListener(this);
        _imageView = new CustomImageView(this)
        {
            LayoutParameters = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MatchParent, 400, GravityFlags.Center)
        };
        _imageView.SetBackgroundColor(Color.White);
        FindViewById<FrameLayout>(Resource.Id.top_picture).AddView(_imageView);
        FindViewById<LinearLayout>(Resource.Id.items).AddView(_gridView);


    }

    public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
    {
        if (visibleItemCount == 0) return;
        if (firstVisibleItem != 0) return;
        _imageView.SetCurrentTranslation(_gridView.GetChildAt(0).Top);
    }

    public void OnScrollStateChanged(AbsListView view, ScrollState scrollState)
    {
        //throw new NotImplementedException();
    }
}

public class CustomImageView : ImageView
{
    protected CustomImageView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
    }

    public CustomImageView(Context context) : base(context)
    {
    }

    public CustomImageView(Context context, IAttributeSet attrs) : base(context, attrs)
    {
    }

    public CustomImageView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
    {
    }

    public int mCurrentTranslation;

    public void SetCurrentTranslation(int currentTranslation) {
        mCurrentTranslation = currentTranslation;
        Invalidate();
    }

    public override void Draw(Canvas canvas)
    {
        canvas.Save();
        canvas.Translate(0, -mCurrentTranslation/2);
        base.Draw(canvas);
        canvas.Restore();
    }

}

}

Main.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:background="#000000"
          android:id="@+id/items">
<FrameLayout
android:id="@+id/top_picture"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#ffffff"/>

The app is running on mono powered by Xamarin's framework. Any help's appreciated!


Solution

  • I made an open source library that dose just what you need - https://github.com/nirhart/ParallaxScroll you can see the example here - https://play.google.com/store/apps/details?id=com.nirhart.parallaxscrollexample