2

For my requirement I have written a custom NestedScrollingChild to use in AppBarLayout.

Requirement was I need a custom view which will be partially displayed could be scrolled up to its full visibility. And another Layout which will be above the partially displayed view and and will scroll up when we scroll up the custom view. The Layout will stop when toolbar is slide up, after that custom view could be further scrolled up to its full display

It is the code which I am working on now when I try to move up the custom view it is shaking and the Toolbar is also shaking.

import android.content.Context;
import android.graphics.RectF;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;



public class MyCustomView extends LinearLayout
        implements NestedScrollingChild,
        GestureDetector.OnGestureListener {


    private static final String TAG = "MyCustomView";
    LinearLayout mainView;
    private GestureDetectorCompat mDetector;
    NestedScrollingChildHelper nestedScrollingChildHelper;


    public MyCustomView(Context context) {
        super(context);
        LayoutInflater mInflater = LayoutInflater.from(context);
        mInflater.inflate(R.layout.fragment_footer  , this);
        mDetector = new GestureDetectorCompat(context,this);
        nestedScrollingChildHelper = new NestedScrollingChildHelper(this);
        nestedScrollingChildHelper.setNestedScrollingEnabled(true);
    }


    public MyCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater mInflater = LayoutInflater.from(context);
        mInflater.inflate(R.layout.fragment_footer  , this);

        mDetector = new GestureDetectorCompat(context,this);
        nestedScrollingChildHelper = new NestedScrollingChildHelper(this);
        nestedScrollingChildHelper.setNestedScrollingEnabled(true);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final boolean handled = mDetector.onTouchEvent(event);
        if (!handled && event.getAction() == MotionEvent.ACTION_UP) {
            nestedScrollingChildHelper.stopNestedScroll();
        }
        return true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d(TAG,"widthMeasureSpec"+widthMeasureSpec+", heightMeasureSpec"+heightMeasureSpec );
    }

    public int dpToPx(int dp) {
        DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        nestedScrollingChildHelper.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        nestedScrollingChildHelper.dispatchNestedPreScroll(0, (int) distanceY, null, null);
        nestedScrollingChildHelper.dispatchNestedScroll(0, 0, 0, 0, null);
        Log.d(TAG, "DistanceX " + distanceX + ", DistanceY" + distanceY);
        Log.d(TAG, "e1X " + e1.getX() + ", e1Y" + e1.getY());
        Log.d(TAG, "e2X " + e2.getX() + ", e2Y" + e2.getY());

        if(Math.abs(e1.getY() - e2.getY()) > 10) {
            setTop(getTop() - (int) (e1.getY() - e2.getY()));
        }

        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return false;
    }
}

Layout code

    <android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
             <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
                <ImageView
                    android:id="@+id/imageView1"
                    android:layout_width="100dp"
                    android:layout_height="65dp"
                    android:layout_alignParentLeft="true"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="5dp"
                    android:src="@drawable/logo" />
            </android.support.v7.widget.Toolbar>
    </android.support.design.widget.AppBarLayout>
    <include layout="@layout/content_main" />
    <com.sample.custom.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        />
</android.support.design.widget.CoordinatorLayout>

If I comment setTop(getTop() - (int) (e1.getY() - e2.getY())); the the scroll on custome view will hide/show the toolbar properly

Sarath Babu
  • 923
  • 3
  • 10
  • 27

0 Answers0