Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
noties committed May 23, 2015
2 parents fd69f02 + f073e60 commit d018c65
Show file tree
Hide file tree
Showing 14 changed files with 600 additions and 47 deletions.
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ This library encapsulates scrolling logic when implementing *scrolling tabs* (ho
compile 'ru.noties:scrollable:x.x.x'
```

## What new (1.1.0)
* Improved interception of ghost touches when `ScrollableLayout.getScrollY()` > 0 && < max scroll y
* Added `Close-up logic` (turned off by default)


## Howto
Simply wrap your views in `ru.noties.scrollable.ScrollableLayout`. The final xml might be looking something like that (don't copy, it's not valid):
Expand All @@ -34,7 +38,7 @@ Simply wrap your views in `ru.noties.scrollable.ScrollableLayout`. The final xml
<TextView
android:layout_width="match_parent"
android:layout_height="@dimen/header_height" --!(2)
android:background="@color/header_background"
android:background="@color/header_background"
android:textColor="@color/white"
android:textSize="30sp"
android:text="Header"
Expand Down Expand Up @@ -127,7 +131,34 @@ public boolean canScrollVertically(int direction) {

Additionally you could provide a ScrollableLayout with a `ru.noties.scrollable.OnScrollChangedListener` and implement where your own logic. It's the place to implement parallax and all other possible stuff.

Hope this will help.
## Close-up logic
Since `1.1.0` it's possible to evaluate custom close-up logic. For a simple close-up (with only two states of ScrollableLayout - collapsed & expanded) use `ru.noties.scrollable.DefaultCloseUpAlgorithm`. For more fancy stuff create your own by implementing `ru.noties.scrollable.CloseUpAlgorithm`.

#### CloseUpAlgorithm
Might be set with `ScrollableLayout.setCloseUpAlgorithm()` or (if default implementation is desired) via xml definition `app:scrollable_defaultCloseUp="true"`

#### CloseUpIdleAnimationTime
`ru.noties.scrollable.CloseUpIdleAnimationTime` is used to compute the duration of the close-up animation. For a simple case when duration for all close-ups is constant `ru.noties.scrollable.SimpleCloseUpIdleAnimationTime` might be used via `ScrollableLayout.setCloseUpIdleAnimationTime()` or via xml definition `app:scrollable_closeUpAnimationMillis="200"`.
Default value is `200` ms.

#### CloseUpConsiderIdleMillis
Value in milliseconds after which scroll state of a ScrollableLayout is considered idle and thus close-up logic is evaluated. Might be set via `ScrollableLayout.setConsiderIdleMillis()` or via xml definition `app:scrollable_considerIdleMillis="100"`.
Default value is `100` ms.

#### CloseUpAnimatorConfigurator
`ru.noties.scrollable.CloseUpAnimatorConfigurator` is used to configure an `ObjectAnimator` of a pending close-up animation. If the only configurable value is an `Interpolator` then `ru.noties.scrollable.InterpolatorCloseUpAnimatorConfigurator` might be used via `ScrollableLayout.setCloseUpAnimatorConfigurator()` or via xml definition `app:scrollable_closeUpAnimatorInterpolator="@android:anim/bounce_interpolator"`.
Default value is `null`

## XML attributes
```xml
app:scrollable_maxScroll="@dimen/header_height"
app:scrollable_considerIdleMillis="100"
app:scrollable_friction="0.075"
app:scrollable_closeUpAnimationMillis="200"
app:scrollable_defaultCloseUp="true"
app:scrollable_scrollerFlywheel="false"
app:scrollable_closeUpAnimatorInterpolator="@android:anim/bounce_interpolator"
```


## License
Expand All @@ -147,4 +178,3 @@ Hope this will help.
See the License for the specific language governing permissions and
limitations under the License.
```

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ protected void onCreate(Bundle savedInstanceState) {

mScrollableLayout = findView(this, R.id.scrollable_layout);
mScrollableLayout.setDraggableView(tabs);

final ViewPager viewPager = findView(this, R.id.view_pager);
final ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), getResources(), getFragments());
viewPager.setAdapter(adapter);
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/scrollable_layout"
app:scrollable_maxScroll="@dimen/header_height">
app:scrollable_maxScroll="@dimen/header_height"
app:scrollable_considerIdleMillis="125"
app:scrollable_friction="0.075"
app:scrollable_closeUpAnimationMillis="250"
app:scrollable_defaultCloseUp="true"
app:scrollable_scrollerFlywheel="false"
app:scrollable_closeUpAnimatorInterpolator="@android:anim/accelerate_decelerate_interpolator">

<LinearLayout
android:layout_width="match_parent"
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/layout/fragment_dialog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/scrollable_layout"
app:scrollable_maxScroll="@dimen/header_height">
app:scrollable_maxScroll="@dimen/header_height"
app:scrollable_defaultCloseUp="true">

<View
android:layout_width="match_parent"
Expand Down
9 changes: 7 additions & 2 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
versionCode 2
versionName "1.1.0"
}

buildTypes {
Expand Down Expand Up @@ -36,4 +36,9 @@ android.libraryVariants.all { variant ->

}

// used for debugging
//dependencies {
// compile 'ru.noties:debug:1.1.3'
//}

apply from: 'https://raw.githubusercontent.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'
32 changes: 32 additions & 0 deletions library/src/main/java/ru/noties/scrollable/CloseUpAlgorithm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ru.noties.scrollable;

/**
* Use this interface to handle specific *close-up* logic for {@link ScrollableLayout},
* use with {@link ScrollableLayout#setCloseUpAlgorithm(CloseUpAlgorithm)}
* @see DefaultCloseUpAlgorithm
* Created by Dimitry Ivanov on 22.05.2015.
*/
public interface CloseUpAlgorithm {

/**
* This method computes end scroll y after fling event was detected
* @param layout {@link ScrollableLayout}
* @param isScrollingBottom whether {@link ScrollableLayout} would scroll to top or bottom
* @param nowY current scroll y of the *layout*
* @param suggestedY scroll y that is suggested
* @param maxY current max scroll y of the *layout*
* @return end scroll y value for the *layout* to animate to
*/
int getFlingFinalY(ScrollableLayout layout, boolean isScrollingBottom, int nowY, int suggestedY, int maxY);

/**
* This method will be fired after scroll state of a {@link ScrollableLayout} would be considered idle
* @param layout {@link ScrollableLayout}
* @param nowY current scroll y of the *layout*
* @param maxY current max scroll y of the *layout*
* @see ScrollableLayout#getConsiderIdleMillis()
* @see ScrollableLayout#setConsiderIdleMillis(long)
* @return end scroll y value for the *layout* to animate to
*/
int getIdleFinalY(ScrollableLayout layout, int nowY, int maxY);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ru.noties.scrollable;

import android.animation.ObjectAnimator;

/**
* This interface might be used to customize {@link android.animation.ObjectAnimator} behavior during close-up animation
* @see android.animation.ObjectAnimator
* @see InterpolatorCloseUpAnimatorConfigurator
* Created by Dimitry Ivanov on 22.05.2015.
*/
public interface CloseUpAnimatorConfigurator {

/**
* Note that {@link android.animation.ObjectAnimator#setDuration(long)} would erase current value set by {@link CloseUpIdleAnimationTime} if any present
* @param animator current {@link android.animation.ObjectAnimator} object to animate close-up animation of a {@link ScrollableLayout}
*/
void configure(ObjectAnimator animator);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.noties.scrollable;

/**
* This interface might be used to dynamically compute close-up animation time of a {@link ScrollableLayout}
* @see ScrollableLayout#setCloseUpIdleAnimationTime(CloseUpIdleAnimationTime)
* @see SimpleCloseUpIdleAnimationTime
* Created by Dimitry Ivanov on 22.05.2015.
*/
public interface CloseUpIdleAnimationTime {

/**
* @param layout {@link ScrollableLayout}
* @param nowY current scroll y of the *layout*
* @param endY scroll y value to which *layout* would scroll to
* @param maxY current max scroll y value of the *layout*
* @return animation duration for a close-up animation
*/
long compute(ScrollableLayout layout, int nowY, int endY, int maxY);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.noties.scrollable;

/**
* Default implementation of the {@link CloseUpAlgorithm}
* With this implementation {@link ScrollableLayout} would have only two states - collapsed &amp; expanded
* @see ScrollableLayout#setCloseUpAlgorithm(CloseUpAlgorithm)
* Created by Dimitry Ivanov on 23.05.2015.
*/
public class DefaultCloseUpAlgorithm implements CloseUpAlgorithm {

/**
* {@inheritDoc}
*/
@Override
public int getFlingFinalY(ScrollableLayout layout, boolean isScrollingBottom, int nowY, int suggestedY, int maxY) {
return isScrollingBottom ? 0 : maxY;
}

/**
* {@inheritDoc}
*/
@Override
public int getIdleFinalY(ScrollableLayout layout, int nowY, int maxY) {
final boolean shouldScrollToTop = nowY < (maxY / 2);
return shouldScrollToTop ? 0 : maxY;
}
}
18 changes: 18 additions & 0 deletions library/src/main/java/ru/noties/scrollable/DipUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ru.noties.scrollable;

import android.content.Context;
import android.content.res.Resources;

/**
* Created by Dimitry Ivanov on 23.05.2015.
*/
class DipUtils {

private DipUtils() {}

static int dipToPx(Context context, int dip) {
final Resources r = context.getResources();
final float scale = r.getDisplayMetrics().density;
return (int) (dip * scale + .5F);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.noties.scrollable;

import android.animation.ObjectAnimator;
import android.view.animation.Interpolator;

/**
* Created by Dimitry Ivanov on 23.05.2015.
*/
public class InterpolatorCloseUpAnimatorConfigurator implements CloseUpAnimatorConfigurator {

private final Interpolator mInterpolator;

public InterpolatorCloseUpAnimatorConfigurator(Interpolator interpolator) {
this.mInterpolator = interpolator;
}

/**
* {@inheritDoc}
*/
@Override
public void configure(ObjectAnimator animator) {
animator.setInterpolator(mInterpolator);
}
}
Loading

0 comments on commit d018c65

Please sign in to comment.