ksoichiro / Android-ObservableScrollView

Android library to observe scroll events on scrollable views.
http://ksoichiro.github.io/Android-ObservableScrollView/
Apache License 2.0
9.65k stars 2.06k forks source link

FlexibleSpaceWithImageGridViewFragment scroll error #216

Open fansmc opened 8 years ago

fansmc commented 8 years ago

android os is 5.0.1 library version is 2446ff2 when i set ObservableGridView's android:numColumns="3" , and scroll down it can't stop . you can reappear it to set android:numColumns="3"

fansmc commented 8 years ago

grid_scroll_problem grid_scroll_problem2

FelisManulus commented 8 years ago

Same here, this bug renders observable gridview unusable :(

FelisManulus commented 8 years ago

Ok I think I've found a workaround to this bug, based on this answer on StackOverflow. The main idea is to use ObservableScrollView with a nested custom GridView with overridden onMeasure method, instead of ObservableGridView. Although it's not a best practice to do so, everything seems to work.

FlexibleSpaceWithImageScrollViewFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
        // Populate our custom GridView with data
        String[] data = getResources().getString(R.string.lipsum).split(" ");
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.my_gridview_item, R.id.my_gridview_item_text, data);
        MyGridView myGridView = (MyGridView) view.findViewById(R.id.my_grid_view);
        myGridView.setAdapter(adapter);
...
}

@Override
protected void updateFlexibleSpace(int scrollY, View view) {
        int flexibleSpaceImageHeight = getResources().getDimensionPixelSize(R.dimen.flexible_space_image_height);

        ObservableScrollView scrollView = (ObservableScrollView) view.findViewById(R.id.scroll);

        View listBackgroundView = view.findViewById(R.id.list_background);

        // Translate list background
        ViewHelper.setTranslationY(listBackgroundView, Math.max(0, -scrollY + flexibleSpaceImageHeight));

        // Also pass this event to parent Activity
        FlexibleSpaceWithImageWithViewPagerTabActivity parentActivity =
            (FlexibleSpaceWithImageWithViewPagerTabActivity) getActivity();
        if (parentActivity != null) {
            parentActivity.onScrollChanged(scrollY, scrollView);
        }
}

fragment_flexiblespacewithimagescrollview.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/list_background"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white" />

    <com.github.ksoichiro.android.observablescrollview.ObservableScrollView
        android:id="@+id/scroll"

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:scrollbars="none">

            <com.github.ksoichiro.android.observablescrollview.samples.my.MyGridView
                android:paddingTop="@dimen/flexible_space_image_height"
                android:id="@+id/my_grid_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:numColumns="auto_fit"
                android:columnWidth="100dp"
                android:stretchMode="columnWidth"
                android:scrollbars="none"
                />

    </com.github.ksoichiro.android.observablescrollview.ObservableScrollView>
</FrameLayout>

MyGridView.java

package com.github.ksoichiro.android.observablescrollview.samples.my;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.GridView;

public class MyGridView extends GridView {

    public MyGridView(Context context) {
        super(context);
    }

    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public MyGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // HACK! TAKE THAT ANDROID!

        // Calculate entire height by providing a very large height hint.
        // View.MEASURED_SIZE_MASK represents the largest height possible.
        int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
            MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);

        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();

    }
}

my_gridview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@android:color/transparent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/my_gridview_item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:width="100dp"
        android:minHeight="40dp"
        android:textSize="12sp">
    </TextView>
</LinearLayout>