Delete unused
This commit is contained in:
parent
ea7e5e4b00
commit
7ce9196da3
119 changed files with 0 additions and 7306 deletions
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="src" path="java"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
2
eclipse-compile/fab/.gitignore
vendored
2
eclipse-compile/fab/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
bin
|
||||
gen
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ShellFab</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:10:53
|
||||
-->
|
||||
<manifest
|
||||
package="com.software.shell.fab"
|
||||
/>
|
File diff suppressed because it is too large
Load diff
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 Shell Software Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* File created: 2015-02-25 19:54:28
|
||||
*/
|
||||
|
||||
package com.software.shell.fab;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Outline;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link android.view.ViewOutlineProvider}
|
||||
* for <b>Action Button</b>
|
||||
*
|
||||
* Used for drawing the elevation shadow for {@code API 21 Lollipop} and higher
|
||||
*
|
||||
* @author Vladislav
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
class ActionButtonOutlineProvider extends ViewOutlineProvider {
|
||||
|
||||
/**
|
||||
* Outline provider width
|
||||
*/
|
||||
private int width;
|
||||
|
||||
/**
|
||||
* Outline provider height
|
||||
*/
|
||||
private int height;
|
||||
|
||||
/**
|
||||
* Creates an instance of the {@link com.software.shell.fab.ActionButtonOutlineProvider}
|
||||
*
|
||||
* @param width initial outline provider width
|
||||
* @param height initial outline provider height
|
||||
*/
|
||||
ActionButtonOutlineProvider(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to get the provider to populate the Outline. This method will be called by a View
|
||||
* when its owned Drawables are invalidated, when the View's size changes, or if invalidateOutline()
|
||||
* is called explicitly. The input outline is empty and has an alpha of 1.0f
|
||||
*
|
||||
* @param view a view, which builds the outline
|
||||
* @param outline an empty outline, which is to be populated
|
||||
*/
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
outline.setOval(0, 0, width, height);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 Shell Software Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* File created: 2015-02-16 10:56:57
|
||||
*/
|
||||
|
||||
package com.software.shell.fab;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.animation.Animation;
|
||||
|
||||
/**
|
||||
* Deprecated since version <b>1.0.2</b>. Use {@link com.software.shell.fab.ActionButton}
|
||||
* class instead.
|
||||
* The reason is the rename of base class name from <b>FloatingActionButton</b> to
|
||||
* <b>ActionButton</b> and some of the methods, which are present in this class.
|
||||
* <p>
|
||||
* Will be removed in version 2.0.0. Please use {@link com.software.shell.fab.ActionButton} and
|
||||
* methods declared there instead
|
||||
*
|
||||
* @author Vladislav
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class FloatingActionButton extends ActionButton{
|
||||
|
||||
private static final String LOG_TAG = "FAB";
|
||||
|
||||
public FloatingActionButton(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public FloatingActionButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initActionButton(context, attrs, 0, 0);
|
||||
}
|
||||
|
||||
public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initActionButton(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
initActionButton(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an animation, which is used while showing <b>Floating Action Button</b>
|
||||
* @deprecated since version <b>1.0.2</b>. Please use {@link #getShowAnimation()} instead
|
||||
*
|
||||
* @return animation, which is used while showing <b>Floating Action Button</b>
|
||||
*/
|
||||
@Deprecated
|
||||
public Animation getAnimationOnShow() {
|
||||
return getShowAnimation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the animation, which is used while showing <b>Floating Action Button</b>
|
||||
* @deprecated since version <b>1.0.2</b>. Please use
|
||||
* {@link #setShowAnimation(android.view.animation.Animation)} instead
|
||||
*
|
||||
* @param animation animation, which is to be used while showing
|
||||
* <b>Floating Action Button</b>
|
||||
*/
|
||||
@Deprecated
|
||||
public void setAnimationOnShow(Animation animation) {
|
||||
setShowAnimation(animation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets one of the {@link Animations} as animation, which is used while showing
|
||||
* <b>Floating Action Button</b>
|
||||
* @deprecated since version <b>1.0.2</b>. Please use
|
||||
* {@link #setShowAnimation(com.software.shell.fab.ActionButton.Animations)} instead
|
||||
*
|
||||
* @param animation one of the {@link Animations}, which is to be used while
|
||||
* showing <b>Floating Action Button</b>
|
||||
*/
|
||||
@Deprecated
|
||||
public void setAnimationOnShow(Animations animation) {
|
||||
setShowAnimation(animation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an animation, which is used while hiding <b>Floating Action Button</b>
|
||||
* @deprecated since version <b>1.0.2</b>. Please use {@link #getHideAnimation()}
|
||||
* instead
|
||||
*
|
||||
* @return animation, which is used while hiding <b>Floating Action Button</b>
|
||||
*/
|
||||
@Deprecated
|
||||
public Animation getAnimationOnHide() {
|
||||
return getHideAnimation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the animation, which is used while hiding <b>Floating Action Button</b>
|
||||
* @deprecated since version <b>1.0.2</b>. Please use
|
||||
* {@link #setHideAnimation(android.view.animation.Animation)} instead
|
||||
*
|
||||
* @param animation animation, which is to be used while hiding
|
||||
* <b>Floating Action Button</b>
|
||||
*/
|
||||
@Deprecated
|
||||
public void setAnimationOnHide(Animation animation) {
|
||||
setHideAnimation(animation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets one of the {@link Animations} as animation, which is used while hiding
|
||||
* <b>Floating Action Button</b>
|
||||
* @deprecated since version <b>1.0.2</b>. Please use
|
||||
* {@link #setHideAnimation(com.software.shell.fab.ActionButton.Animations)} )} instead
|
||||
*
|
||||
* @param animation one of the {@link Animations}, which is to be used while
|
||||
* hiding <b>Floating Action Button</b>
|
||||
*/
|
||||
@Deprecated
|
||||
public void setAnimationOnHide(Animations animation) {
|
||||
setHideAnimation(animation);
|
||||
}
|
||||
|
||||
private void initActionButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ActionButton,
|
||||
defStyleAttr, defStyleRes);
|
||||
try {
|
||||
initType(attributes);
|
||||
initShowAnimation(attributes);
|
||||
initHideAnimation(attributes);
|
||||
} catch (Exception e) {
|
||||
Log.e(LOG_TAG, "Unable to read attr", e);
|
||||
} finally {
|
||||
attributes.recycle();
|
||||
}
|
||||
Log.v(LOG_TAG, "Floating Action Button initialized");
|
||||
}
|
||||
|
||||
private void initType(TypedArray attrs) {
|
||||
if (attrs.hasValue(R.styleable.ActionButton_type)) {
|
||||
final int id = attrs.getInteger(R.styleable.ActionButton_type, 0);
|
||||
setType(Type.forId(id));
|
||||
Log.v(LOG_TAG, "Initialized type: " + getType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the animation, which is used while showing
|
||||
* <b>Action Button</b>
|
||||
* @deprecated since 1.0.2 and will be removed in version 2.0.0.
|
||||
* Use <b>show_animation</b> and <b>hide_animation</b> in XML instead
|
||||
*
|
||||
* @param attrs attributes of the XML tag that is inflating the view
|
||||
*/
|
||||
@Deprecated
|
||||
private void initShowAnimation(TypedArray attrs) {
|
||||
if (attrs.hasValue(R.styleable.ActionButton_animation_onShow)) {
|
||||
final int animResId = attrs.getResourceId(R.styleable.ActionButton_animation_onShow,
|
||||
Animations.NONE.animResId);
|
||||
setShowAnimation(Animations.load(getContext(), animResId));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the animation, which is used while hiding or dismissing
|
||||
* <b>Action Button</b>
|
||||
* @deprecated since 1.0.2 and will be removed in version 2.0.0
|
||||
* Use <b>show_animation</b> and <b>hide_animation</b> in XML instead
|
||||
*
|
||||
* @param attrs attributes of the XML tag that is inflating the view
|
||||
*/
|
||||
@Deprecated
|
||||
private void initHideAnimation(TypedArray attrs) {
|
||||
if (attrs.hasValue(R.styleable.ActionButton_animation_onHide)) {
|
||||
final int animResId = attrs.getResourceId(R.styleable.ActionButton_animation_onHide,
|
||||
Animations.NONE.animResId);
|
||||
setHideAnimation(Animations.load(getContext(), animResId));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 Shell Software Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* File created: 2015-01-30 22:55:44
|
||||
*/
|
||||
|
||||
package com.software.shell.fab;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Contains utility methods for metrics conversion
|
||||
*
|
||||
* @author Vladislav
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class MetricsConverter {
|
||||
|
||||
/**
|
||||
* Prevents from creating {@link com.software.shell.fab.MetricsConverter} instances
|
||||
*/
|
||||
private MetricsConverter() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the density-independent value into real pixel value based on display metrics
|
||||
*
|
||||
* @param context application context
|
||||
* @param dp density-independent value
|
||||
* @return converted real pixel value
|
||||
*/
|
||||
public static float dpToPx(Context context, float dp) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return dp * scale;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
# 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.
|
||||
|
||||
# Indicates whether an apk should be generated for each density.
|
||||
split.density=false
|
||||
# Project target.
|
||||
target=android-21
|
||||
dex.force.jumbo=true
|
||||
android.library=true
|
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:12
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/decelerate_cubic">
|
||||
<scale
|
||||
android:fromXScale="0.0"
|
||||
android:toXScale="1.0"
|
||||
android:fromYScale="0.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="500"
|
||||
/>
|
||||
<translate
|
||||
android:fromYDelta="30%p"
|
||||
android:toYDelta="0"
|
||||
android:duration="500"
|
||||
/>
|
||||
</set>
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:38
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/decelerate_cubic">
|
||||
<scale
|
||||
android:fromXScale="0.0"
|
||||
android:toXScale="1.0"
|
||||
android:fromYScale="0.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="500"
|
||||
/>
|
||||
<translate
|
||||
android:fromXDelta="30%p"
|
||||
android:toXDelta="0"
|
||||
android:duration="500"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:42
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/accelerate_cubic">
|
||||
<scale
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale="0.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="0.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"
|
||||
/>
|
||||
<translate
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="30%p"
|
||||
android:duration="300"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:45
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/accelerate_cubic">
|
||||
<scale
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale="0.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="0.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"
|
||||
/>
|
||||
<translate
|
||||
android:fromXDelta="0"
|
||||
android:toXDelta="30%p"
|
||||
android:duration="300"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:49
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/overshoot">
|
||||
<rotate
|
||||
android:duration="500"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fromDegrees="360"
|
||||
android:toDegrees="0"
|
||||
/>
|
||||
<translate
|
||||
android:fromYDelta="30%p"
|
||||
android:toYDelta="0"
|
||||
android:duration="500"
|
||||
/>
|
||||
</set>
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:53
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/overshoot">
|
||||
<rotate
|
||||
android:duration="500"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fromDegrees="360"
|
||||
android:toDegrees="0"
|
||||
/>
|
||||
<translate
|
||||
android:fromXDelta="30%p"
|
||||
android:toXDelta="0"
|
||||
android:duration="500"
|
||||
/>
|
||||
</set>
|
|
@ -1,36 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:56
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/anticipate">
|
||||
<rotate
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="360"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"
|
||||
/>
|
||||
<translate
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="30%p"
|
||||
android:duration="300"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,36 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:26:00
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/anticipate">
|
||||
<rotate
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="360"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"
|
||||
/>
|
||||
<translate
|
||||
android:fromXDelta="0"
|
||||
android:toXDelta="30%p"
|
||||
android:duration="300"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:26:04
|
||||
-->
|
||||
|
||||
<scale
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/anticipate"
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale="0.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="0.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"
|
||||
/>
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:26:09
|
||||
-->
|
||||
<scale
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/overshoot"
|
||||
android:fromXScale="0.0"
|
||||
android:toXScale="1.0"
|
||||
android:fromYScale="0.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="500"
|
||||
/>
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:24:57
|
||||
-->
|
||||
|
||||
<alpha
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:fromAlpha="0.0"
|
||||
android:toAlpha="1.0"
|
||||
android:duration="500"
|
||||
/>
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:06
|
||||
-->
|
||||
|
||||
<alpha
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:fromAlpha="1.0"
|
||||
android:toAlpha="0.0"
|
||||
android:duration="300"
|
||||
/>
|
|
@ -1,36 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:12
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale
|
||||
android:fromXScale="0.0"
|
||||
android:toXScale="1.0"
|
||||
android:fromYScale="0.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="500"
|
||||
/>
|
||||
<translate
|
||||
android:fromYDelta="30%p"
|
||||
android:toYDelta="0"
|
||||
android:duration="500"
|
||||
/>
|
||||
</set>
|
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:38
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale
|
||||
android:fromXScale="0.0"
|
||||
android:toXScale="1.0"
|
||||
android:fromYScale="0.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="500"
|
||||
/>
|
||||
<translate
|
||||
android:fromXDelta="30%p"
|
||||
android:toXDelta="0"
|
||||
android:duration="500"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:42
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale="0.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="0.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"
|
||||
/>
|
||||
<translate
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="30%p"
|
||||
android:duration="300"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:45
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale="0.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="0.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="300"
|
||||
/>
|
||||
<translate
|
||||
android:fromXDelta="0"
|
||||
android:toXDelta="30%p"
|
||||
android:duration="300"
|
||||
/>
|
||||
|
||||
</set>
|
|
@ -1,48 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:49
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<rotate
|
||||
android:duration="400"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fromDegrees="360"
|
||||
android:toDegrees="-30"
|
||||
/>
|
||||
<rotate
|
||||
android:duration="100"
|
||||
android:startOffset="400"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="30"
|
||||
/>
|
||||
<translate
|
||||
android:duration="400"
|
||||
android:fromYDelta="30%p"
|
||||
android:toYDelta="-20"
|
||||
/>
|
||||
<translate
|
||||
android:duration="100"
|
||||
android:startOffset="400"
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="20"
|
||||
/>
|
||||
</set>
|
|
@ -1,48 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:53
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<rotate
|
||||
android:duration="400"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fromDegrees="360"
|
||||
android:toDegrees="-30"
|
||||
/>
|
||||
<rotate
|
||||
android:duration="100"
|
||||
android:startOffset="400"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="30"
|
||||
/>
|
||||
<translate
|
||||
android:duration="400"
|
||||
android:fromXDelta="30%p"
|
||||
android:toXDelta="-20"
|
||||
/>
|
||||
<translate
|
||||
android:duration="100"
|
||||
android:startOffset="400"
|
||||
android:fromXDelta="0"
|
||||
android:toXDelta="20"
|
||||
/>
|
||||
</set>
|
|
@ -1,48 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:25:56
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<rotate
|
||||
android:duration="100"
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="-30"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
/>
|
||||
<rotate
|
||||
android:duration="200"
|
||||
android:startOffset="100"
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="390"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
/>
|
||||
<translate
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="-20"
|
||||
android:duration="100"
|
||||
/>
|
||||
<translate
|
||||
android:duration="200"
|
||||
android:startOffset="100"
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="30%p"
|
||||
/>
|
||||
</set>
|
|
@ -1,48 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:26:00
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<rotate
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="-30"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:duration="100"
|
||||
/>
|
||||
<rotate
|
||||
android:duration="200"
|
||||
android:startOffset="100"
|
||||
android:fromDegrees="0"
|
||||
android:toDegrees="390"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
/>
|
||||
<translate
|
||||
android:fromXDelta="0"
|
||||
android:toXDelta="-20"
|
||||
android:duration="100"
|
||||
/>
|
||||
<translate
|
||||
android:duration="200"
|
||||
android:startOffset="100"
|
||||
android:fromXDelta="0"
|
||||
android:toXDelta="30%p"
|
||||
/>
|
||||
</set>
|
|
@ -1,41 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:26:04
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale
|
||||
android:duration="200"
|
||||
android:fromXScale="1.0"
|
||||
android:toXScale="1.1"
|
||||
android:fromYScale="1.0"
|
||||
android:toYScale="1.1"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
/>
|
||||
<scale
|
||||
android:duration="100"
|
||||
android:startOffset="200"
|
||||
android:fromXScale="1.1"
|
||||
android:toXScale="0.9"
|
||||
android:fromYScale="1.1"
|
||||
android:toYScale="0.9"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
/>
|
||||
</set>
|
|
@ -1,42 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:26:09
|
||||
-->
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<scale
|
||||
android:duration="400"
|
||||
android:fromXScale="0.0"
|
||||
android:toXScale="1.1"
|
||||
android:fromYScale="0.0"
|
||||
android:toYScale="1.1"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
/>
|
||||
<scale
|
||||
android:duration="100"
|
||||
android:startOffset="400"
|
||||
android:fromXScale="1.1"
|
||||
android:toXScale="0.9"
|
||||
android:fromYScale="1.1"
|
||||
android:toYScale="0.9"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
/>
|
||||
|
||||
</set>
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:17:21
|
||||
-->
|
||||
|
||||
<!--Used for tablet devices-->
|
||||
<resources>
|
||||
<dimen name="fab_margin">24dp</dimen>
|
||||
</resources>
|
|
@ -1,47 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:10:53
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<declare-styleable name="ActionButton">
|
||||
<attr name="type" format="enum">
|
||||
<enum name="DEFAULT" value="0" />
|
||||
<enum name="MINI" value="1" />
|
||||
|
||||
<!--Deprecated and will be removed in version 2.0.0. Use DEFAULT and MINI instead-->
|
||||
<enum name="normal" value="0" />
|
||||
<enum name="mini" value="1" />
|
||||
</attr>
|
||||
<attr name="button_color" format="color" />
|
||||
<attr name="button_colorPressed" format="color" />
|
||||
<attr name="shadow_radius" format="dimension" />
|
||||
<attr name="shadow_xOffset" format="dimension" />
|
||||
<attr name="shadow_yOffset" format="dimension" />
|
||||
<attr name="shadow_color" format="color" />
|
||||
<attr name="stroke_width" format="dimension" />
|
||||
<attr name="stroke_color" format="color" />
|
||||
<attr name="show_animation" format="reference" />
|
||||
<attr name="hide_animation" format="reference" />
|
||||
<attr name="image" format="reference" />
|
||||
<attr name="image_size" format="dimension" />
|
||||
|
||||
<!--Deprecated and will be removed in version 2.0.0. Use show_animation and hide_animation instead-->
|
||||
<attr name="animation_onShow" format="reference" />
|
||||
<attr name="animation_onHide" format="reference" />
|
||||
</declare-styleable>
|
||||
</resources>
|
|
@ -1,86 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-18 14:16:05
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!--
|
||||
Material 500 colors are for normal button state
|
||||
Material 900 colors are for pressed button state
|
||||
-->
|
||||
<!--Material Red-->
|
||||
<color name="fab_material_red_500">#f44336</color>
|
||||
<color name="fab_material_red_900">#b71c1c</color>
|
||||
<!--Material Pink-->
|
||||
<color name="fab_material_pink_500">#e91e63</color>
|
||||
<color name="fab_material_pink_900">#880e4f</color>
|
||||
<!--Material Purple-->
|
||||
<color name="fab_material_purple_500">#9c27b0</color>
|
||||
<color name="fab_material_purple_900">#4a148c</color>
|
||||
<!--Material Deep Purple-->
|
||||
<color name="fab_material_deep_purple_500">#673ab7</color>
|
||||
<color name="fab_material_deep_purple_900">#311b92</color>
|
||||
<!--Material Indigo-->
|
||||
<color name="fab_material_indigo_500">#3f51b5</color>
|
||||
<color name="fab_material_indigo_900">#1a237e</color>
|
||||
<!--Material Blue-->
|
||||
<color name="fab_material_blue_500">#2196f3</color>
|
||||
<color name="fab_material_blue_900">#0d47a1</color>
|
||||
<!--Material Light Blue-->
|
||||
<color name="fab_material_light_blue_500">#03a9f4</color>
|
||||
<color name="fab_material_light_blue_900">#01579b</color>
|
||||
<!--Material Cyan-->
|
||||
<color name="fab_material_cyan_500">#00bcd4</color>
|
||||
<color name="fab_material_cyan_900">#006064</color>
|
||||
<!--Material Teal-->
|
||||
<color name="fab_material_teal_500">#009688</color>
|
||||
<color name="fab_material_teal_900">#004d40</color>
|
||||
<!--Material Green-->
|
||||
<color name="fab_material_green_500">#4caf50</color>
|
||||
<color name="fab_material_green_900">#1b5e20</color>
|
||||
<!--Material Light Green-->
|
||||
<color name="fab_material_light_green_500">#8bc34a</color>
|
||||
<color name="fab_material_light_green_900">#33691e</color>
|
||||
<!--Material Lime-->
|
||||
<color name="fab_material_lime_500">#cddc39</color>
|
||||
<color name="fab_material_lime_900">#827717</color>
|
||||
<!--Material Yellow-->
|
||||
<color name="fab_material_yellow_500">#ffeb3b</color>
|
||||
<color name="fab_material_yellow_900">#f57f17</color>
|
||||
<!--Material Amber-->
|
||||
<color name="fab_material_amber_500">#ffc107</color>
|
||||
<color name="fab_material_amber_900">#ff6f00</color>
|
||||
<!--Material Orange-->
|
||||
<color name="fab_material_orange_500">#ff9800</color>
|
||||
<color name="fab_material_orange_900">#e65100</color>
|
||||
<!--Material Deep Orange-->
|
||||
<color name="fab_material_deep_orange_500">#ff5722</color>
|
||||
<color name="fab_material_deep_orange_900">#bf360c</color>
|
||||
<!--Material Brown-->
|
||||
<color name="fab_material_brown_500">#795548</color>
|
||||
<color name="fab_material_brown_900">#3e2723</color>
|
||||
<!--Material Grey-->
|
||||
<color name="fab_material_grey_500">#9e9e9e</color>
|
||||
<color name="fab_material_grey_900">#212121</color>
|
||||
<!--Material Blue Grey-->
|
||||
<color name="fab_material_blue_grey_500">#607d8b</color>
|
||||
<color name="fab_material_blue_grey_900">#263238</color>
|
||||
<!--Material Black-->
|
||||
<color name="fab_material_black">#000000</color>
|
||||
<!--Material White-->
|
||||
<color name="fab_material_white">#ffffff</color>
|
||||
</resources>
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 Shell Software Inc.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ File created: 2015-01-17 10:15:16
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<!-- Used for mobile (non-tablet) devices -->
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
|
||||
</resources>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="src" path="java"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
4
eclipse-compile/observable/.gitignore
vendored
4
eclipse-compile/observable/.gitignore
vendored
|
@ -1,4 +0,0 @@
|
|||
/build
|
||||
/bin
|
||||
/gen
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ListObservable</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest package="com.github.ksoichiro.android.observablescrollview">
|
||||
</manifest>
|
|
@ -1,62 +0,0 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.1.0'
|
||||
classpath 'com.android.tools.build:gradle:1.0.0'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:recyclerview-v7:21.0.0'
|
||||
androidTestCompile ('com.android.support:appcompat-v7:21.0.2') {
|
||||
exclude module: 'support-v4'
|
||||
}
|
||||
androidTestCompile ('com.nineoldandroids:library:2.4.0') {
|
||||
exclude module: 'support-v4'
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.1"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 9
|
||||
}
|
||||
|
||||
jacoco {
|
||||
version = '0.7.2.201409121644'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
testCoverageEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
res.srcDirs = ['res']
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.kt3k.coveralls'
|
||||
|
||||
coveralls.jacocoReportPath = 'build/outputs/reports/coverage/debug/report.xml'
|
||||
|
||||
// This is from 'https://github.com/chrisbanes/gradle-mvn-push'
|
||||
apply from: 'gradle-mvn-push.gradle'
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 Chris Banes
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'signing'
|
||||
|
||||
def isReleaseBuild() {
|
||||
return VERSION_NAME.contains("SNAPSHOT") == false
|
||||
}
|
||||
|
||||
def getReleaseRepositoryUrl() {
|
||||
return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
|
||||
: "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
||||
}
|
||||
|
||||
def getSnapshotRepositoryUrl() {
|
||||
return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
|
||||
: "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
}
|
||||
|
||||
def getRepositoryUsername() {
|
||||
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
|
||||
}
|
||||
|
||||
def getRepositoryPassword() {
|
||||
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
|
||||
}
|
||||
|
||||
afterEvaluate { project ->
|
||||
uploadArchives {
|
||||
repositories {
|
||||
mavenDeployer {
|
||||
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
|
||||
|
||||
pom.groupId = GROUP
|
||||
pom.artifactId = POM_ARTIFACT_ID
|
||||
pom.version = VERSION_NAME
|
||||
|
||||
repository(url: getReleaseRepositoryUrl()) {
|
||||
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
|
||||
}
|
||||
snapshotRepository(url: getSnapshotRepositoryUrl()) {
|
||||
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
|
||||
}
|
||||
|
||||
pom.project {
|
||||
name POM_NAME
|
||||
packaging POM_PACKAGING
|
||||
description POM_DESCRIPTION
|
||||
url POM_URL
|
||||
|
||||
scm {
|
||||
url POM_SCM_URL
|
||||
connection POM_SCM_CONNECTION
|
||||
developerConnection POM_SCM_DEV_CONNECTION
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name POM_LICENCE_NAME
|
||||
url POM_LICENCE_URL
|
||||
distribution POM_LICENCE_DIST
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
id POM_DEVELOPER_ID
|
||||
name POM_DEVELOPER_NAME
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
|
||||
sign configurations.archives
|
||||
}
|
||||
|
||||
task androidJavadocs(type: Javadoc) {
|
||||
source = android.sourceSets.main.java.srcDirs
|
||||
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
|
||||
}
|
||||
|
||||
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
|
||||
classifier = 'javadoc'
|
||||
from androidJavadocs.destinationDir
|
||||
}
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.sourceFiles
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives androidSourcesJar
|
||||
archives androidJavadocsJar
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
POM_NAME=Android-ObservableScrollView
|
||||
POM_ARTIFACT_ID=android-observablescrollview
|
||||
POM_PACKAGING=aar
|
|
@ -1,38 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.github.ksoichiro.android.observablescrollview.test">
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
<activity android:name=".GridViewActivity" />
|
||||
<activity android:name=".ListViewActivity" />
|
||||
<activity android:name=".ListViewScrollFromBottomActivity" />
|
||||
<activity android:name=".RecyclerViewActivity" />
|
||||
<activity android:name=".RecyclerViewScrollFromBottomActivity" />
|
||||
<activity android:name=".ScrollViewActivity" />
|
||||
<activity android:name=".TouchInterceptionGridViewActivity" android:theme="@style/AppTheme.Toolbar" />
|
||||
<activity android:name=".TouchInterceptionListViewActivity" android:theme="@style/AppTheme.Toolbar" />
|
||||
<activity android:name=".TouchInterceptionRecyclerViewActivity" android:theme="@style/AppTheme.Toolbar" />
|
||||
<activity android:name=".TouchInterceptionScrollViewActivity" android:theme="@style/AppTheme.Toolbar" />
|
||||
<activity android:name=".TouchInterceptionWebViewActivity" android:theme="@style/AppTheme.Toolbar" />
|
||||
<activity android:name=".ViewPagerTabActivity" android:theme="@style/AppTheme.Toolbar" />
|
||||
<activity android:name=".ViewPagerTab2Activity" android:theme="@style/AppTheme.Toolbar" />
|
||||
<activity android:name=".WebViewActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,17 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
#container {
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<p>Lorem ipsum dolor sit amet, ut duis lorem provident sed felis blandit, condimentum donec lectus ipsum et mauris, morbi porttitor interdum feugiat nulla donec sodales, vestibulum nisl primis a molestie vestibulum quam, sapien mauris metus risus suspendisse magnis. Augue viverra nulla faucibus egestas eu, a etiam id congue rutrum ante, arcu tincidunt donec quam felis at ornare, iaculis ligula sodales venenatis commodo volutpat neque, suspendisse elit praesent tellus felis mi amet. Inceptos amet tempor lectus lorem est non, ac donec ac libero neque mauris, tellus ante metus eget leo consequat. Scelerisque dolor curabitur pretium blandit ut feugiat, amet lacus pulvinar justo convallis ut, sed natoque ipsum urna posuere nibh eu. Sed at sed vulputate sit orci, facilisis a aliquam tellus quam aliquam, eu aliquam donec at molestie ante, pellentesque mauris lorem ultrices libero faucibus porta, imperdiet adipiscing sit hac diam ut nulla. Lacus enim elit pulvinar donec vehicula dapibus, accumsan purus officia cursus dolor sapien, eu amet dis mauris mi nulla ut. Non accusamus etiam pede non urna tempus, vestibulum aliquam tortor eget pharetra sodales, in vestibulum ut justo orci nulla, lobortis purus sem semper consectetuer magni purus. Dolor a leo vestibulum amet ut sit, arcu ut eaque urna fusce aliquet turpis, sed fermentum sed vestibulum nisl pede, tristique enim lorem posuere in laborum ut. Vestibulum id id justo leo nulla, magna lobortis ullamcorper et dignissim pellentesque, duis suspendisse quis id lorem ante. Vivamus a nullam ante adipiscing amet, mi vel consectetuer nunc aenean pede quisque, eget rhoncus dis porttitor habitant nunc vivamus, duis cubilia blandit non donec justo dictumst, praesent vitae nulla nam pulvinar urna. Adipiscing adipiscing justo urna pulvinar imperdiet nullam, vitae fusce rhoncus proin nonummy suscipit, ullamcorper amet et non potenti platea ultrices, mauris nullam sapien nunc justo vel, eu semper pellentesque arcu fusce augue. Malesuada mauris nibh sit a a scelerisque, velit sem lectus tellus convallis consectetuer, ultricies auctor a ante eros amet sed.</p>
|
||||
<p>Risus lacus duis leo platea wisi, felis maecenas rutrum in id in donec, non id a potenti libero eget, posuere elit ea sed pellentesque quis. Sunt lacus urna lorem elit duis, nibh donec purus quisque consectetuer dolor, neque vestibulum proin ornare eros nonummy phasellus. Iaculis cras eu at egestas dolor montes, viverra quisque malesuada consectetuer semper maecenas, a sed vitae donec tempor aliqua metus, ornare mollis suscipit et erat fusce, sit orci aut auctor elementum fames aliquam. Platea dui integer magnis non metus, minus dignissimos ante massa nostra et, rutrum sapien egestas quis sapien donec donec. Erat sit a eros aenean natoque, quam libero id lorem enim proin, lorem ipsum fermentum mattis metus et. Aliquam aliquet suscipit purus conubia at neque, platea vivamus vestibulum nulla quibusdam senectus, et morbi lectus malesuada gravida donec, elementum sit convallis pellentesque velit amet. Et eveniet viverra vehicula consectetuer justo, provident sed commodo non lacinia velit, tempor phasellus vel leo nisl cras, vivamus et arcu interdum dui eu amet. Volutpat wisi rhoncus vel turpis diam quibusdam, dapibus elit est quisque cubilia mauris, nulla elit magna tempor accumsan bibendum, lorem varius sed interdum eget mattis, scelerisque egestas feugiat donec dui molestie. Leo facilisis nisl sit montes ligula sed, enim commodo consectetuer nunc est et, ut sed vehicula dolor luctus elit. Fermentum cras donec eget nibh est vel, sed justo risus et pharetra diam, eu vivamus egestas ligula risus diam, sed justo eget hac ut mauris. Vestibulum diam nec vitae mi eget suspendisse, aenean arcu purus facilisis purus class in, id aliquam sit id scelerisque sapien etiam. Ut nullam sit sed at mauris lobortis, consequat dolor autem ipsum euismod nulla, elit quis proin eget conubia varius, erat arcu massa mus in mauris, scelerisque ut eu sollicitudin libero leo urna.</p>
|
||||
<p>Consectetuer luctus tempor elit ut dolor ligula, quis dui per dui hendrerit ante sagittis, in quisque pretium in eleifend enim. Condimentum iaculis vitae feugiat dis tellus vel, lectus dolor nec dui nulla nascetur, et pellentesque curabitur lorem leo velit eget. Id nascetur arcu lobortis suspendisse imperdiet urna, natoque nascetur ante in porta a, interdum hendrerit mi bibendum platea tellus, urna in enim ornare vestibulum faucibus enim. Leo fusce egestas ante nec volutpat, in tempor vel facilisis potenti ut, pede at non lorem a commodo, nulla dolor orci interdum vestibulum nulla. Dui nulla vestibulum quisque a pharetra porta, integer nec ipsum nec sed dui pharetra, magna et dignissim ipsum sed dictum, litora eros vivamus scelerisque libero ipsum. Sed ac ac lorem molestie adipiscing morbi, pellentesque imperdiet nunc quis morbi amet ante, libero dui ligula nec risus neque et, velit nonummy phasellus et facilisi amet, ligula in elementum non sapien pulvinar faucibus. Eu leo ut posuere sed aliquet, tincidunt vel urna volutpat tempus sem, sit felis aliquet vestibulum condimentum sit, amet nibh vel tellus purus ullamcorper libero, nulla vestibulum pede ut vestibulum pretium. Eu nulla vestibulum a neque in metus, quisquam nam sed cursus eget luctus, pede ultrices nec sed dignissim pellentesque, sit class cursus metus nulla placerat mauris, consequat mollis neque vivamus amet pede. Mauris dolor nulla diam eros bibendum, quam ante vestibulum morbi non ligula vel, molestie curabitur rhoncus nulla euismod interdum non. Nulla fringilla lorem mollis ad massa, sit molestie nibh lorem arcu volutpat, accumsan commodo lectus eu et donec, sit tempor tempus rutrum in curabitur amet. Nec urna euismod a tincidunt commodo, eu pede turpis libero vitae viverra, ante vestibulum nam non habitasse potenti, mauris imperdiet in in nunc convallis. Et nostra wisi in est accumsan vehicula, quisque vitae felis mauris sed vulputate nec, ante imperdiet sollicitudin massa iaculis massa sit.</p>
|
||||
<p>Quam libero nulla netus eu porta curae, ut nulla bibendum facilisis et urna sed, quis congue vestibulum aliquam interdum etiam. Nulla vel lobortis ullamcorper vitae excepturi, neque urna feugiat lectus vel lacinia, massa pretium orci eu metus neque vulputate. Imperdiet ac velit rhoncus nulla malesuada nullam, nec pulvinar justo gravida lorem rutrum magna, habitasse repudiandae mi eros vestibulum ante, nec euismod dui iaculis in turpis pretium, ac id metus egestas proin lacus lectus. Laoreet lorem nec vitae risus erat arcu, vitae quam ut in ante tristique, porta dolor pede quam et odio nam, arcu lacus sem congue ante cursus massa. Et mattis sagittis erat accumsan fusce quam, vehicula ligula beatae natoque fusce sodales conubia, habitasse metus cum magnis viverra nam cursus, egestas urna wisi primis blandit eu magna, eget libero elit lacus lorem dis aliquam. Ut mauris ante natoque lacus massa, justo a lectus sodales enim adipiscing id, accumsan ut ipsum vestibulum sed enim auctor, vitae congue tincidunt id phasellus lacinia scelerisque, tincidunt sapien nulla euismod volutpat iaculis. Platea sociis nec aliquet nec molestie, in mi et augue sapien in vivamus, integer fames proin vitae in ullamcorper et. Fringilla etiam sapiente rhoncus suspendisse nec id, lobortis cras eget egestas dui ac nec, justo lacus ut lorem bibendum quia eros, eget a gravida id donec nunc suscipit, porta sed in sodales non rutrum. Lectus vel dui elementum pellentesque magna aliquam, vitae non sit pede et fusce nibh, id id deserunt ornare dui sit condimentum, in adipiscing imperdiet turpis nam aliquet, facilisis metus magna lacus wisi facilisis tortor. Vulputate elit accumsan quam amet ligula, suspendisse lacus mi nonummy integer urna, libero nulla nunc varius in odio, laoreet nulla amet placerat amet nec. Consectetuer vel massa hendrerit vitae iaculis id, sed ut ut laudantium odio in, elit vestibulum duis ante maecenas interdum in, neque vehicula ultrices varius in quam, pede tellus pellentesque sed nullam quis.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,129 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.AbsSavedState;
|
||||
|
||||
public class SavedStateTest extends InstrumentationTestCase {
|
||||
|
||||
public void testGridViewSavedState() throws Throwable {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
ObservableGridView.SavedState state1 = new ObservableGridView.SavedState(AbsSavedState.EMPTY_STATE);
|
||||
state1.prevFirstVisiblePosition = 1;
|
||||
state1.prevFirstVisibleChildHeight = 2;
|
||||
state1.prevScrolledChildrenHeight = 3;
|
||||
state1.prevScrollY = 4;
|
||||
state1.scrollY = 5;
|
||||
state1.childrenHeights = new SparseIntArray();
|
||||
state1.childrenHeights.put(0, 10);
|
||||
state1.childrenHeights.put(1, 20);
|
||||
state1.childrenHeights.put(2, 30);
|
||||
state1.writeToParcel(parcel, 0);
|
||||
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
ObservableGridView.SavedState state2 = ObservableGridView.SavedState.CREATOR.createFromParcel(parcel);
|
||||
assertNotNull(state2);
|
||||
assertEquals(state1.prevFirstVisiblePosition, state2.prevFirstVisiblePosition);
|
||||
assertEquals(state1.prevFirstVisibleChildHeight, state2.prevFirstVisibleChildHeight);
|
||||
assertEquals(state1.prevScrolledChildrenHeight, state2.prevScrolledChildrenHeight);
|
||||
assertEquals(state1.prevScrollY, state2.prevScrollY);
|
||||
assertEquals(state1.scrollY, state2.scrollY);
|
||||
assertNotNull(state1.childrenHeights);
|
||||
assertEquals(3, state1.childrenHeights.size());
|
||||
assertEquals(10, state1.childrenHeights.get(0));
|
||||
assertEquals(20, state1.childrenHeights.get(1));
|
||||
assertEquals(30, state1.childrenHeights.get(2));
|
||||
}
|
||||
|
||||
public void testListViewSavedState() throws Throwable {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
ObservableListView.SavedState state1 = new ObservableListView.SavedState(AbsSavedState.EMPTY_STATE);
|
||||
state1.prevFirstVisiblePosition = 1;
|
||||
state1.prevFirstVisibleChildHeight = 2;
|
||||
state1.prevScrolledChildrenHeight = 3;
|
||||
state1.prevScrollY = 4;
|
||||
state1.scrollY = 5;
|
||||
state1.childrenHeights = new SparseIntArray();
|
||||
state1.childrenHeights.put(0, 10);
|
||||
state1.childrenHeights.put(1, 20);
|
||||
state1.childrenHeights.put(2, 30);
|
||||
state1.writeToParcel(parcel, 0);
|
||||
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
ObservableListView.SavedState state2 = ObservableListView.SavedState.CREATOR.createFromParcel(parcel);
|
||||
assertNotNull(state2);
|
||||
assertEquals(state1.prevFirstVisiblePosition, state2.prevFirstVisiblePosition);
|
||||
assertEquals(state1.prevFirstVisibleChildHeight, state2.prevFirstVisibleChildHeight);
|
||||
assertEquals(state1.prevScrolledChildrenHeight, state2.prevScrolledChildrenHeight);
|
||||
assertEquals(state1.prevScrollY, state2.prevScrollY);
|
||||
assertEquals(state1.scrollY, state2.scrollY);
|
||||
assertNotNull(state1.childrenHeights);
|
||||
assertEquals(3, state1.childrenHeights.size());
|
||||
assertEquals(10, state1.childrenHeights.get(0));
|
||||
assertEquals(20, state1.childrenHeights.get(1));
|
||||
assertEquals(30, state1.childrenHeights.get(2));
|
||||
}
|
||||
|
||||
public void testRecyclerViewSavedState() throws Throwable {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
ObservableRecyclerView.SavedState state1 = new ObservableRecyclerView.SavedState(AbsSavedState.EMPTY_STATE);
|
||||
state1.prevFirstVisiblePosition = 1;
|
||||
state1.prevFirstVisibleChildHeight = 2;
|
||||
state1.prevScrolledChildrenHeight = 3;
|
||||
state1.prevScrollY = 4;
|
||||
state1.scrollY = 5;
|
||||
state1.childrenHeights = new SparseIntArray();
|
||||
state1.childrenHeights.put(0, 10);
|
||||
state1.childrenHeights.put(1, 20);
|
||||
state1.childrenHeights.put(2, 30);
|
||||
state1.writeToParcel(parcel, 0);
|
||||
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
ObservableRecyclerView.SavedState state2 = ObservableRecyclerView.SavedState.CREATOR.createFromParcel(parcel);
|
||||
assertNotNull(state2);
|
||||
assertEquals(state1.prevFirstVisiblePosition, state2.prevFirstVisiblePosition);
|
||||
assertEquals(state1.prevFirstVisibleChildHeight, state2.prevFirstVisibleChildHeight);
|
||||
assertEquals(state1.prevScrolledChildrenHeight, state2.prevScrolledChildrenHeight);
|
||||
assertEquals(state1.prevScrollY, state2.prevScrollY);
|
||||
assertEquals(state1.scrollY, state2.scrollY);
|
||||
assertNotNull(state1.childrenHeights);
|
||||
assertEquals(3, state1.childrenHeights.size());
|
||||
assertEquals(10, state1.childrenHeights.get(0));
|
||||
assertEquals(20, state1.childrenHeights.get(1));
|
||||
assertEquals(30, state1.childrenHeights.get(2));
|
||||
}
|
||||
|
||||
public void testScrollViewSavedState() throws Throwable {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
ObservableScrollView.SavedState state1 = new ObservableScrollView.SavedState(AbsSavedState.EMPTY_STATE);
|
||||
state1.prevScrollY = 1;
|
||||
state1.scrollY = 2;
|
||||
state1.writeToParcel(parcel, 0);
|
||||
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
ObservableScrollView.SavedState state2 = ObservableScrollView.SavedState.CREATOR.createFromParcel(parcel);
|
||||
assertNotNull(state2);
|
||||
assertEquals(state1.prevScrollY, state2.prevScrollY);
|
||||
assertEquals(state1.scrollY, state2.scrollY);
|
||||
}
|
||||
|
||||
public void testWebViewSavedState() throws Throwable {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
ObservableWebView.SavedState state1 = new ObservableWebView.SavedState(AbsSavedState.EMPTY_STATE);
|
||||
state1.prevScrollY = 1;
|
||||
state1.scrollY = 2;
|
||||
state1.writeToParcel(parcel, 0);
|
||||
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
ObservableWebView.SavedState state2 = ObservableWebView.SavedState.CREATOR.createFromParcel(parcel);
|
||||
assertNotNull(state2);
|
||||
assertEquals(state1.prevScrollY, state2.prevScrollY);
|
||||
assertEquals(state1.scrollY, state2.scrollY);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.widget.AbsListView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableGridView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
|
||||
public class GridViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_gridview);
|
||||
ObservableGridView scrollable = (ObservableGridView) findViewById(R.id.scrollable);
|
||||
scrollable.setScrollViewCallbacks(this);
|
||||
UiTestUtils.setDummyData(this, scrollable);
|
||||
scrollable.setOnScrollListener(new AbsListView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableGridView;
|
||||
|
||||
public class GridViewActivityTest extends ActivityInstrumentationTestCase2<GridViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableGridView scrollable;
|
||||
|
||||
public GridViewActivityTest() {
|
||||
super(GridViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableGridView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
|
||||
public void testScrollVerticallyTo() throws Throwable {
|
||||
final DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, metrics));
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo(0);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.widget.AbsListView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
|
||||
public class ListViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_listview);
|
||||
ObservableListView scrollable = (ObservableListView) findViewById(R.id.scrollable);
|
||||
scrollable.setScrollViewCallbacks(this);
|
||||
UiTestUtils.setDummyData(this, scrollable);
|
||||
scrollable.setOnScrollListener(new AbsListView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
|
||||
public class ListViewActivityTest extends ActivityInstrumentationTestCase2<ListViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableListView scrollable;
|
||||
|
||||
public ListViewActivityTest() {
|
||||
super(ListViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableListView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
|
||||
public void testScrollVerticallyTo() throws Throwable {
|
||||
final DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, metrics));
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo(0);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
|
||||
public class ListViewScrollFromBottomActivity extends ListViewActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final ObservableListView scrollable = (ObservableListView) findViewById(R.id.scrollable);
|
||||
ScrollUtils.addOnGlobalLayoutListener(scrollable, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int count = scrollable.getAdapter().getCount() - 1;
|
||||
int position = count == 0 ? 1 : count > 0 ? count : 0;
|
||||
scrollable.smoothScrollToPosition(position);
|
||||
scrollable.setSelection(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
|
||||
public class ListViewScrollFromBottomActivityTest extends ActivityInstrumentationTestCase2<ListViewScrollFromBottomActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableListView scrollable;
|
||||
|
||||
public ListViewScrollFromBottomActivityTest() {
|
||||
super(ListViewScrollFromBottomActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableListView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
|
||||
public class RecyclerViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_recyclerview);
|
||||
|
||||
ObservableRecyclerView recyclerView = (ObservableRecyclerView) findViewById(R.id.scrollable);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setScrollViewCallbacks(this);
|
||||
UiTestUtils.setDummyData(this, recyclerView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
|
||||
public class RecyclerViewActivityTest extends ActivityInstrumentationTestCase2<RecyclerViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableRecyclerView scrollable;
|
||||
|
||||
public RecyclerViewActivityTest() {
|
||||
super(RecyclerViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableRecyclerView) activity.findViewById(R.id.scrollable);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
|
||||
public void testScrollVerticallyTo() throws Throwable {
|
||||
final DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, metrics));
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo(0);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
|
||||
public class RecyclerViewScrollFromBottomActivity extends RecyclerViewActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final ObservableRecyclerView scrollable = (ObservableRecyclerView) findViewById(R.id.scrollable);
|
||||
ScrollUtils.addOnGlobalLayoutListener(scrollable, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int count = scrollable.getAdapter().getItemCount() - 1;
|
||||
int position = count == 0 ? 1 : count > 0 ? count : 0;
|
||||
scrollable.scrollToPosition(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
|
||||
public class RecyclerViewScrollFromBottomActivityTest extends ActivityInstrumentationTestCase2<RecyclerViewScrollFromBottomActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableRecyclerView scrollable;
|
||||
|
||||
public RecyclerViewScrollFromBottomActivityTest() {
|
||||
super(RecyclerViewScrollFromBottomActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableRecyclerView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.test.InstrumentationTestCase;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class ScrollUtilsTest extends InstrumentationTestCase {
|
||||
|
||||
public void testGetFloat() {
|
||||
Assert.assertEquals(1.0f, ScrollUtils.getFloat(1, 0, 2));
|
||||
assertEquals(0.0f, ScrollUtils.getFloat(-1, 0, 2));
|
||||
assertEquals(2.0f, ScrollUtils.getFloat(3, 0, 2));
|
||||
}
|
||||
|
||||
public void testGetColorWithAlpha() {
|
||||
assertEquals(Color.parseColor("#00123456"), ScrollUtils.getColorWithAlpha(0, Color.parseColor("#FF123456")));
|
||||
assertEquals(Color.parseColor("#FF123456"), ScrollUtils.getColorWithAlpha(1, Color.parseColor("#FF123456")));
|
||||
}
|
||||
|
||||
public void testMixColors() {
|
||||
assertEquals(Color.parseColor("#000000"), ScrollUtils.mixColors(Color.parseColor("#000000"), Color.parseColor("#FFFFFF"), 0));
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
|
||||
public class ScrollViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_scrollview);
|
||||
((Scrollable) findViewById(R.id.scrollable)).setScrollViewCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
|
||||
public class ScrollViewActivityTest extends ActivityInstrumentationTestCase2<ScrollViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableScrollView scrollable;
|
||||
|
||||
public ScrollViewActivityTest() {
|
||||
super(ScrollViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableScrollView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SimpleHeaderRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private static final int VIEW_TYPE_HEADER = 0;
|
||||
private static final int VIEW_TYPE_ITEM = 1;
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
private ArrayList<String> mItems;
|
||||
private View mHeaderView;
|
||||
|
||||
public SimpleHeaderRecyclerAdapter(Context context, ArrayList<String> items, View headerView) {
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mItems = items;
|
||||
mHeaderView = headerView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mHeaderView == null) {
|
||||
return mItems.size();
|
||||
} else {
|
||||
return mItems.size() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return (position == 0) ? VIEW_TYPE_HEADER : VIEW_TYPE_ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (viewType == VIEW_TYPE_HEADER) {
|
||||
return new HeaderViewHolder(mHeaderView);
|
||||
} else {
|
||||
return new ItemViewHolder(mInflater.inflate(android.R.layout.simple_list_item_1, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
|
||||
if (viewHolder instanceof ItemViewHolder) {
|
||||
((ItemViewHolder) viewHolder).textView.setText(mItems.get(position - 1));
|
||||
}
|
||||
}
|
||||
|
||||
static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
public HeaderViewHolder(View view) {
|
||||
super(view);
|
||||
}
|
||||
}
|
||||
|
||||
static class ItemViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textView;
|
||||
|
||||
public ItemViewHolder(View view) {
|
||||
super(view);
|
||||
textView = (TextView) view.findViewById(android.R.id.text1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SimpleRecyclerAdapter extends RecyclerView.Adapter<SimpleRecyclerAdapter.ViewHolder> {
|
||||
private LayoutInflater mInflater;
|
||||
private ArrayList<String> mItems;
|
||||
|
||||
public SimpleRecyclerAdapter(Context context, ArrayList<String> items) {
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mItems = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(mInflater.inflate(android.R.layout.simple_list_item_1, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder viewHolder, int position) {
|
||||
viewHolder.textView.setText(mItems.get(position));
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textView;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
textView = (TextView) view.findViewById(android.R.id.text1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableGridView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
import com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
|
||||
public class TouchInterceptionGridViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
private TouchInterceptionFrameLayout mInterceptionLayout;
|
||||
private Scrollable mScrollable;
|
||||
|
||||
private int mIntersectionHeight;
|
||||
private int mHeaderBarHeight;
|
||||
|
||||
private float mScrollYOnDownMotion;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_touchinterception_gridview);
|
||||
((TextView) findViewById(R.id.title)).setText(getClass().getSimpleName());
|
||||
mScrollable = (Scrollable) findViewById(R.id.scrollable);
|
||||
mScrollable.setScrollViewCallbacks(this);
|
||||
UiTestUtils.setDummyData(this, (ObservableGridView) mScrollable);
|
||||
|
||||
mIntersectionHeight = getResources().getDimensionPixelSize(R.dimen.intersection_height);
|
||||
mHeaderBarHeight = getResources().getDimensionPixelSize(R.dimen.header_bar_height);
|
||||
|
||||
mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.scroll_wrapper);
|
||||
mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
|
||||
private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() {
|
||||
@Override
|
||||
public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) {
|
||||
final int minInterceptionLayoutY = -mIntersectionHeight;
|
||||
return minInterceptionLayoutY < (int) ViewHelper.getY(mInterceptionLayout)
|
||||
|| (moving && mScrollable.getCurrentScrollY() - diffY < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent(MotionEvent ev) {
|
||||
mScrollYOnDownMotion = mScrollable.getCurrentScrollY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) {
|
||||
float translationY = ViewHelper.getTranslationY(mInterceptionLayout) - mScrollYOnDownMotion + diffY;
|
||||
if (translationY < -mIntersectionHeight) {
|
||||
translationY = -mIntersectionHeight;
|
||||
} else if (getScreenHeight() - mHeaderBarHeight < translationY) {
|
||||
translationY = getScreenHeight() - mHeaderBarHeight;
|
||||
}
|
||||
|
||||
slideTo(translationY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(MotionEvent ev) {
|
||||
}
|
||||
};
|
||||
|
||||
private void slideTo(float translationY, final boolean animated) {
|
||||
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
|
||||
|
||||
if (translationY < 0) {
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
|
||||
lp.height = (int) -translationY + getScreenHeight();
|
||||
mInterceptionLayout.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
return findViewById(android.R.id.content).getHeight();
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.test.TouchUtils;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableGridView;
|
||||
|
||||
public class TouchInterceptionGridViewActivityTest extends ActivityInstrumentationTestCase2<TouchInterceptionGridViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableGridView scrollable;
|
||||
|
||||
public TouchInterceptionGridViewActivityTest() {
|
||||
super(TouchInterceptionGridViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableGridView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
TouchUtils.touchAndCancelView(this, scrollable);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
import com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
|
||||
public class TouchInterceptionListViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
private TouchInterceptionFrameLayout mInterceptionLayout;
|
||||
private Scrollable mScrollable;
|
||||
|
||||
private int mIntersectionHeight;
|
||||
private int mHeaderBarHeight;
|
||||
|
||||
private float mScrollYOnDownMotion;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_touchinterception_listview);
|
||||
((TextView) findViewById(R.id.title)).setText(getClass().getSimpleName());
|
||||
mScrollable = (Scrollable) findViewById(R.id.scrollable);
|
||||
mScrollable.setScrollViewCallbacks(this);
|
||||
UiTestUtils.setDummyData(this, (ObservableListView) mScrollable);
|
||||
|
||||
mIntersectionHeight = getResources().getDimensionPixelSize(R.dimen.intersection_height);
|
||||
mHeaderBarHeight = getResources().getDimensionPixelSize(R.dimen.header_bar_height);
|
||||
|
||||
mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.scroll_wrapper);
|
||||
mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
|
||||
private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() {
|
||||
@Override
|
||||
public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) {
|
||||
final int minInterceptionLayoutY = -mIntersectionHeight;
|
||||
return minInterceptionLayoutY < (int) ViewHelper.getY(mInterceptionLayout)
|
||||
|| (moving && mScrollable.getCurrentScrollY() - diffY < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent(MotionEvent ev) {
|
||||
mScrollYOnDownMotion = mScrollable.getCurrentScrollY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) {
|
||||
float translationY = ViewHelper.getTranslationY(mInterceptionLayout) - mScrollYOnDownMotion + diffY;
|
||||
if (translationY < -mIntersectionHeight) {
|
||||
translationY = -mIntersectionHeight;
|
||||
} else if (getScreenHeight() - mHeaderBarHeight < translationY) {
|
||||
translationY = getScreenHeight() - mHeaderBarHeight;
|
||||
}
|
||||
|
||||
slideTo(translationY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(MotionEvent ev) {
|
||||
}
|
||||
};
|
||||
|
||||
private void slideTo(float translationY, final boolean animated) {
|
||||
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
|
||||
|
||||
if (translationY < 0) {
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
|
||||
lp.height = (int) -translationY + getScreenHeight();
|
||||
mInterceptionLayout.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
return findViewById(android.R.id.content).getHeight();
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.test.TouchUtils;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
|
||||
public class TouchInterceptionListViewActivityTest extends ActivityInstrumentationTestCase2<TouchInterceptionListViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableListView scrollable;
|
||||
|
||||
public TouchInterceptionListViewActivityTest() {
|
||||
super(TouchInterceptionListViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableListView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
TouchUtils.touchAndCancelView(this, scrollable);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
import com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
|
||||
public class TouchInterceptionRecyclerViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
private TouchInterceptionFrameLayout mInterceptionLayout;
|
||||
private Scrollable mScrollable;
|
||||
|
||||
private int mIntersectionHeight;
|
||||
private int mHeaderBarHeight;
|
||||
|
||||
private float mScrollYOnDownMotion;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_touchinterception_recyclerview);
|
||||
((TextView) findViewById(R.id.title)).setText(getClass().getSimpleName());
|
||||
mScrollable = (Scrollable) findViewById(R.id.scrollable);
|
||||
mScrollable.setScrollViewCallbacks(this);
|
||||
ObservableRecyclerView recyclerView = (ObservableRecyclerView) mScrollable;
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setScrollViewCallbacks(this);
|
||||
UiTestUtils.setDummyData(this, recyclerView);
|
||||
|
||||
mIntersectionHeight = getResources().getDimensionPixelSize(R.dimen.intersection_height);
|
||||
mHeaderBarHeight = getResources().getDimensionPixelSize(R.dimen.header_bar_height);
|
||||
|
||||
mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.scroll_wrapper);
|
||||
mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
|
||||
private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() {
|
||||
@Override
|
||||
public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) {
|
||||
final int minInterceptionLayoutY = -mIntersectionHeight;
|
||||
return minInterceptionLayoutY < (int) ViewHelper.getY(mInterceptionLayout)
|
||||
|| (moving && mScrollable.getCurrentScrollY() - diffY < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent(MotionEvent ev) {
|
||||
mScrollYOnDownMotion = mScrollable.getCurrentScrollY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) {
|
||||
float translationY = ViewHelper.getTranslationY(mInterceptionLayout) - mScrollYOnDownMotion + diffY;
|
||||
if (translationY < -mIntersectionHeight) {
|
||||
translationY = -mIntersectionHeight;
|
||||
} else if (getScreenHeight() - mHeaderBarHeight < translationY) {
|
||||
translationY = getScreenHeight() - mHeaderBarHeight;
|
||||
}
|
||||
|
||||
slideTo(translationY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(MotionEvent ev) {
|
||||
}
|
||||
};
|
||||
|
||||
private void slideTo(float translationY, final boolean animated) {
|
||||
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
|
||||
|
||||
if (translationY < 0) {
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
|
||||
lp.height = (int) -translationY + getScreenHeight();
|
||||
mInterceptionLayout.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
return findViewById(android.R.id.content).getHeight();
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.test.TouchUtils;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
|
||||
public class TouchInterceptionRecyclerViewActivityTest extends ActivityInstrumentationTestCase2<TouchInterceptionRecyclerViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableRecyclerView scrollable;
|
||||
|
||||
public TouchInterceptionRecyclerViewActivityTest() {
|
||||
super(TouchInterceptionRecyclerViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableRecyclerView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
TouchUtils.touchAndCancelView(this, scrollable);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
import com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
|
||||
public class TouchInterceptionScrollViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
private TouchInterceptionFrameLayout mInterceptionLayout;
|
||||
private Scrollable mScrollable;
|
||||
|
||||
private int mIntersectionHeight;
|
||||
private int mHeaderBarHeight;
|
||||
|
||||
private float mScrollYOnDownMotion;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_touchinterception_scrollview);
|
||||
((TextView) findViewById(R.id.title)).setText(getClass().getSimpleName());
|
||||
mScrollable = (Scrollable) findViewById(R.id.scrollable);
|
||||
mScrollable.setScrollViewCallbacks(this);
|
||||
|
||||
mIntersectionHeight = getResources().getDimensionPixelSize(R.dimen.intersection_height);
|
||||
mHeaderBarHeight = getResources().getDimensionPixelSize(R.dimen.header_bar_height);
|
||||
|
||||
mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.scroll_wrapper);
|
||||
mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
|
||||
private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() {
|
||||
@Override
|
||||
public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) {
|
||||
final int minInterceptionLayoutY = -mIntersectionHeight;
|
||||
return minInterceptionLayoutY < (int) ViewHelper.getY(mInterceptionLayout)
|
||||
|| (moving && mScrollable.getCurrentScrollY() - diffY < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent(MotionEvent ev) {
|
||||
mScrollYOnDownMotion = mScrollable.getCurrentScrollY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) {
|
||||
float translationY = ViewHelper.getTranslationY(mInterceptionLayout) - mScrollYOnDownMotion + diffY;
|
||||
if (translationY < -mIntersectionHeight) {
|
||||
translationY = -mIntersectionHeight;
|
||||
} else if (getScreenHeight() - mHeaderBarHeight < translationY) {
|
||||
translationY = getScreenHeight() - mHeaderBarHeight;
|
||||
}
|
||||
|
||||
slideTo(translationY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(MotionEvent ev) {
|
||||
}
|
||||
};
|
||||
|
||||
private void slideTo(float translationY, final boolean animated) {
|
||||
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
|
||||
|
||||
if (translationY < 0) {
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
|
||||
lp.height = (int) -translationY + getScreenHeight();
|
||||
mInterceptionLayout.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
return findViewById(android.R.id.content).getHeight();
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.test.TouchUtils;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
|
||||
public class TouchInterceptionScrollViewActivityTest extends ActivityInstrumentationTestCase2<TouchInterceptionScrollViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableScrollView scrollable;
|
||||
|
||||
public TouchInterceptionScrollViewActivityTest() {
|
||||
super(TouchInterceptionScrollViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableScrollView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
TouchUtils.touchAndCancelView(this, scrollable);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
import com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
|
||||
public class TouchInterceptionWebViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
private TouchInterceptionFrameLayout mInterceptionLayout;
|
||||
private Scrollable mScrollable;
|
||||
|
||||
private int mIntersectionHeight;
|
||||
private int mHeaderBarHeight;
|
||||
|
||||
private float mScrollYOnDownMotion;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_touchinterception_webview);
|
||||
((TextView) findViewById(R.id.title)).setText(getClass().getSimpleName());
|
||||
mScrollable = (Scrollable) findViewById(R.id.scrollable);
|
||||
mScrollable.setScrollViewCallbacks(this);
|
||||
((WebView) mScrollable).loadUrl("file:///android_asset/lipsum.html");
|
||||
|
||||
mIntersectionHeight = getResources().getDimensionPixelSize(R.dimen.intersection_height);
|
||||
mHeaderBarHeight = getResources().getDimensionPixelSize(R.dimen.header_bar_height);
|
||||
|
||||
mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.scroll_wrapper);
|
||||
mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
|
||||
private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() {
|
||||
@Override
|
||||
public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) {
|
||||
final int minInterceptionLayoutY = -mIntersectionHeight;
|
||||
return minInterceptionLayoutY < (int) ViewHelper.getY(mInterceptionLayout)
|
||||
|| (moving && mScrollable.getCurrentScrollY() - diffY < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent(MotionEvent ev) {
|
||||
mScrollYOnDownMotion = mScrollable.getCurrentScrollY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) {
|
||||
float translationY = ViewHelper.getTranslationY(mInterceptionLayout) - mScrollYOnDownMotion + diffY;
|
||||
if (translationY < -mIntersectionHeight) {
|
||||
translationY = -mIntersectionHeight;
|
||||
} else if (getScreenHeight() - mHeaderBarHeight < translationY) {
|
||||
translationY = getScreenHeight() - mHeaderBarHeight;
|
||||
}
|
||||
|
||||
slideTo(translationY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(MotionEvent ev) {
|
||||
}
|
||||
};
|
||||
|
||||
private void slideTo(float translationY, final boolean animated) {
|
||||
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
|
||||
|
||||
if (translationY < 0) {
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
|
||||
lp.height = (int) -translationY + getScreenHeight();
|
||||
mInterceptionLayout.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
return findViewById(android.R.id.content).getHeight();
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.test.TouchUtils;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableWebView;
|
||||
|
||||
public class TouchInterceptionWebViewActivityTest extends ActivityInstrumentationTestCase2<TouchInterceptionWebViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableWebView scrollable;
|
||||
|
||||
public TouchInterceptionWebViewActivityTest() {
|
||||
super(TouchInterceptionWebViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableWebView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
TouchUtils.touchAndCancelView(this, scrollable);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.TouchUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UiTestUtils {
|
||||
|
||||
private static final int NUM_OF_ITEMS = 100;
|
||||
private static final int NUM_OF_ITEMS_FEW = 3;
|
||||
private static final int DRAG_STEP_COUNT = 50;
|
||||
|
||||
public enum Direction {
|
||||
LEFT, RIGHT, UP, DOWN
|
||||
}
|
||||
|
||||
private UiTestUtils() {
|
||||
}
|
||||
|
||||
public static void saveAndRestoreInstanceState(final InstrumentationTestCase test, final Activity activity) throws Throwable {
|
||||
test.runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Bundle outState = new Bundle();
|
||||
test.getInstrumentation().callActivityOnSaveInstanceState(activity, outState);
|
||||
test.getInstrumentation().callActivityOnPause(activity);
|
||||
test.getInstrumentation().callActivityOnResume(activity);
|
||||
test.getInstrumentation().callActivityOnRestoreInstanceState(activity, outState);
|
||||
}
|
||||
});
|
||||
test.getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public static void swipeHorizontally(InstrumentationTestCase test, View v, Direction direction) {
|
||||
int[] xy = new int[2];
|
||||
v.getLocationOnScreen(xy);
|
||||
|
||||
final int viewWidth = v.getWidth();
|
||||
final int viewHeight = v.getHeight();
|
||||
|
||||
float distanceFromEdge = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
|
||||
v.getResources().getDisplayMetrics());
|
||||
float xStart = xy[0] + ((direction == Direction.LEFT) ? (viewWidth - distanceFromEdge) : distanceFromEdge);
|
||||
float xEnd = xy[0] + ((direction == Direction.LEFT) ? distanceFromEdge : (viewWidth - distanceFromEdge));
|
||||
float y = xy[1] + (viewHeight / 2.0f);
|
||||
|
||||
TouchUtils.drag(test, xStart, xEnd, y, y, DRAG_STEP_COUNT);
|
||||
}
|
||||
|
||||
public static void swipeVertically(InstrumentationTestCase test, View v, Direction direction) {
|
||||
int[] xy = new int[2];
|
||||
v.getLocationOnScreen(xy);
|
||||
|
||||
final int viewWidth = v.getWidth();
|
||||
final int viewHeight = v.getHeight();
|
||||
|
||||
float distanceFromEdge = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
|
||||
v.getResources().getDisplayMetrics());
|
||||
float x = xy[0] + (viewWidth / 2.0f);
|
||||
float yStart = xy[1] + ((direction == Direction.UP) ? (viewHeight - distanceFromEdge) : distanceFromEdge);
|
||||
float yEnd = xy[1] + ((direction == Direction.UP) ? distanceFromEdge : (viewHeight - distanceFromEdge));
|
||||
|
||||
TouchUtils.drag(test, x, x, yStart, yEnd, DRAG_STEP_COUNT);
|
||||
}
|
||||
|
||||
public static ArrayList<String> getDummyData() {
|
||||
return getDummyData(NUM_OF_ITEMS);
|
||||
}
|
||||
|
||||
public static ArrayList<String> getDummyData(int num) {
|
||||
ArrayList<String> items = new ArrayList<String>();
|
||||
for (int i = 1; i <= num; i++) {
|
||||
items.add("Item " + i);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public static void setDummyData(Context context, GridView gridView) {
|
||||
gridView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, getDummyData()));
|
||||
}
|
||||
|
||||
public static void setDummyData(Context context, ListView listView) {
|
||||
setDummyData(context, listView, NUM_OF_ITEMS);
|
||||
}
|
||||
|
||||
public static void setDummyDataFew(Context context, ListView listView) {
|
||||
setDummyData(context, listView, NUM_OF_ITEMS_FEW);
|
||||
}
|
||||
|
||||
public static void setDummyData(Context context, ListView listView, int num) {
|
||||
listView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, getDummyData(num)));
|
||||
}
|
||||
|
||||
public static void setDummyDataWithHeader(Context context, ListView listView, View headerView) {
|
||||
listView.addHeaderView(headerView);
|
||||
setDummyData(context, listView);
|
||||
}
|
||||
|
||||
public static void setDummyData(Context context, RecyclerView recyclerView) {
|
||||
setDummyData(context, recyclerView, NUM_OF_ITEMS);
|
||||
}
|
||||
|
||||
public static void setDummyDataFew(Context context, RecyclerView recyclerView) {
|
||||
setDummyData(context, recyclerView, NUM_OF_ITEMS_FEW);
|
||||
}
|
||||
|
||||
public static void setDummyData(Context context, RecyclerView recyclerView, int num) {
|
||||
recyclerView.setAdapter(new SimpleRecyclerAdapter(context, getDummyData(num)));
|
||||
}
|
||||
|
||||
public static void setDummyDataWithHeader(Context context, RecyclerView recyclerView, View headerView) {
|
||||
recyclerView.setAdapter(new SimpleHeaderRecyclerAdapter(context, getDummyData(), headerView));
|
||||
}
|
||||
}
|
|
@ -1,291 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.TypedValue;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.CacheFragmentStatePagerAdapter;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
import com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout;
|
||||
import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
|
||||
import com.nineoldandroids.animation.ValueAnimator;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
|
||||
public class ViewPagerTab2Activity extends ActionBarActivity implements ObservableScrollViewCallbacks {
|
||||
|
||||
private View mToolbarView;
|
||||
private TouchInterceptionFrameLayout mInterceptionLayout;
|
||||
private ViewPager mPager;
|
||||
private NavigationAdapter mPagerAdapter;
|
||||
private int mSlop;
|
||||
private boolean mScrolled;
|
||||
private ScrollState mLastScrollState;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_viewpagertab2);
|
||||
|
||||
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
||||
|
||||
mToolbarView = findViewById(R.id.toolbar);
|
||||
mPagerAdapter = new NavigationAdapter(getSupportFragmentManager());
|
||||
mPager = (ViewPager) findViewById(R.id.pager);
|
||||
mPager.setAdapter(mPagerAdapter);
|
||||
// Padding for ViewPager must be set outside the ViewPager itself
|
||||
// because with padding, EdgeEffect of ViewPager become strange.
|
||||
final int tabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height);
|
||||
findViewById(R.id.pager_wrapper).setPadding(0, getActionBarSize() + tabHeight, 0, 0);
|
||||
|
||||
SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
|
||||
slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
|
||||
slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent));
|
||||
slidingTabLayout.setDistributeEvenly(true);
|
||||
slidingTabLayout.setViewPager(mPager);
|
||||
|
||||
ViewConfiguration vc = ViewConfiguration.get(this);
|
||||
mSlop = vc.getScaledTouchSlop();
|
||||
mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.container);
|
||||
mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
if (!mScrolled) {
|
||||
// This event can be used only when TouchInterceptionFrameLayout
|
||||
// doesn't handle the consecutive events.
|
||||
adjustToolbar(scrollState);
|
||||
}
|
||||
}
|
||||
|
||||
private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() {
|
||||
@Override
|
||||
public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) {
|
||||
if (!mScrolled && mSlop < Math.abs(diffX) && Math.abs(diffY) < Math.abs(diffX)) {
|
||||
// Horizontal scroll is maybe handled by ViewPager
|
||||
return false;
|
||||
}
|
||||
|
||||
Scrollable scrollable = getCurrentScrollable();
|
||||
if (scrollable == null) {
|
||||
mScrolled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If interceptionLayout can move, it should intercept.
|
||||
// And once it begins to move, horizontal scroll shouldn't work any longer.
|
||||
int toolbarHeight = mToolbarView.getHeight();
|
||||
int translationY = (int) ViewHelper.getTranslationY(mInterceptionLayout);
|
||||
boolean scrollingUp = 0 < diffY;
|
||||
boolean scrollingDown = diffY < 0;
|
||||
if (scrollingUp) {
|
||||
if (translationY < 0) {
|
||||
mScrolled = true;
|
||||
mLastScrollState = ScrollState.UP;
|
||||
return true;
|
||||
}
|
||||
} else if (scrollingDown) {
|
||||
if (-toolbarHeight < translationY) {
|
||||
mScrolled = true;
|
||||
mLastScrollState = ScrollState.DOWN;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mScrolled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent(MotionEvent ev) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) {
|
||||
float translationY = ScrollUtils.getFloat(ViewHelper.getTranslationY(mInterceptionLayout) + diffY, -mToolbarView.getHeight(), 0);
|
||||
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
|
||||
if (translationY < 0) {
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
|
||||
lp.height = (int) (-translationY + getScreenHeight());
|
||||
mInterceptionLayout.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(MotionEvent ev) {
|
||||
mScrolled = false;
|
||||
adjustToolbar(mLastScrollState);
|
||||
}
|
||||
};
|
||||
|
||||
public Scrollable getCurrentScrollable() {
|
||||
Fragment fragment = getCurrentFragment();
|
||||
if (fragment == null) {
|
||||
return null;
|
||||
}
|
||||
View view = fragment.getView();
|
||||
if (view == null) {
|
||||
return null;
|
||||
}
|
||||
return (Scrollable) view.findViewById(R.id.scroll);
|
||||
}
|
||||
|
||||
private void adjustToolbar(ScrollState scrollState) {
|
||||
int toolbarHeight = mToolbarView.getHeight();
|
||||
final Scrollable scrollable = getCurrentScrollable();
|
||||
if (scrollable == null) {
|
||||
return;
|
||||
}
|
||||
int scrollY = scrollable.getCurrentScrollY();
|
||||
if (scrollState == ScrollState.DOWN) {
|
||||
showToolbar();
|
||||
} else if (scrollState == ScrollState.UP) {
|
||||
if (toolbarHeight <= scrollY) {
|
||||
hideToolbar();
|
||||
} else {
|
||||
showToolbar();
|
||||
}
|
||||
} else if (!toolbarIsShown() && !toolbarIsHidden()) {
|
||||
// Toolbar is moving but doesn't know which to move:
|
||||
// you can change this to hideToolbar()
|
||||
showToolbar();
|
||||
}
|
||||
}
|
||||
|
||||
private Fragment getCurrentFragment() {
|
||||
return mPagerAdapter.getItemAt(mPager.getCurrentItem());
|
||||
}
|
||||
|
||||
private boolean toolbarIsShown() {
|
||||
return ViewHelper.getTranslationY(mInterceptionLayout) == 0;
|
||||
}
|
||||
|
||||
private boolean toolbarIsHidden() {
|
||||
return ViewHelper.getTranslationY(mInterceptionLayout) == -mToolbarView.getHeight();
|
||||
}
|
||||
|
||||
private void showToolbar() {
|
||||
animateToolbar(0);
|
||||
}
|
||||
|
||||
private void hideToolbar() {
|
||||
animateToolbar(-mToolbarView.getHeight());
|
||||
}
|
||||
|
||||
private void animateToolbar(final float toY) {
|
||||
float layoutTranslationY = ViewHelper.getTranslationY(mInterceptionLayout);
|
||||
if (layoutTranslationY != toY) {
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(ViewHelper.getTranslationY(mInterceptionLayout), toY).setDuration(200);
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
float translationY = (float) animation.getAnimatedValue();
|
||||
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
|
||||
if (translationY < 0) {
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
|
||||
lp.height = (int) (-translationY + getScreenHeight());
|
||||
mInterceptionLayout.requestLayout();
|
||||
}
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
private int getActionBarSize() {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
int[] textSizeAttr = new int[]{R.attr.actionBarSize};
|
||||
int indexOfAttrTextSize = 0;
|
||||
TypedArray a = obtainStyledAttributes(typedValue.data, textSizeAttr);
|
||||
int actionBarSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
|
||||
a.recycle();
|
||||
return actionBarSize;
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
return findViewById(android.R.id.content).getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* This adapter provides two types of fragments as an example.
|
||||
* {@linkplain #createItem(int)} should be modified if you use this example for your app.
|
||||
*/
|
||||
private static class NavigationAdapter extends CacheFragmentStatePagerAdapter {
|
||||
|
||||
private static final String[] TITLES = new String[]{"Applepie", "Butter Cookie", "Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean", "KitKat", "Lollipop"};
|
||||
|
||||
public NavigationAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Fragment createItem(int position) {
|
||||
Fragment f;
|
||||
final int pattern = position % 5;
|
||||
switch (pattern) {
|
||||
case 0:
|
||||
f = new ViewPagerTab2ScrollViewFragment();
|
||||
break;
|
||||
case 1:
|
||||
f = new ViewPagerTab2ListViewFragment();
|
||||
break;
|
||||
case 2:
|
||||
f = new ViewPagerTab2RecyclerViewFragment();
|
||||
break;
|
||||
case 3:
|
||||
f = new ViewPagerTab2GridViewFragment();
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
f = new ViewPagerTab2WebViewFragment();
|
||||
break;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return TITLES.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return TITLES[position];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.View;
|
||||
|
||||
public class ViewPagerTab2ActivityTest extends ActivityInstrumentationTestCase2<ViewPagerTab2Activity> {
|
||||
|
||||
private ViewPagerTab2Activity activity;
|
||||
|
||||
public ViewPagerTab2ActivityTest() {
|
||||
super(ViewPagerTab2Activity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
UiTestUtils.swipeHorizontally(this, activity.findViewById(R.id.pager), UiTestUtils.Direction.LEFT);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
scroll();
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
UiTestUtils.swipeHorizontally(this, activity.findViewById(R.id.pager), UiTestUtils.Direction.RIGHT);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
scroll();
|
||||
}
|
||||
}
|
||||
|
||||
public void scroll() throws Throwable {
|
||||
View scrollable = ((View) activity.getCurrentScrollable()).findViewById(R.id.scroll);
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
scroll();
|
||||
|
||||
UiTestUtils.swipeHorizontally(this, activity.findViewById(R.id.pager), UiTestUtils.Direction.LEFT);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableGridView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
|
||||
public class ViewPagerTab2GridViewFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_gridview, container, false);
|
||||
|
||||
Activity parentActivity = getActivity();
|
||||
final ObservableGridView gridView = (ObservableGridView) view.findViewById(R.id.scroll);
|
||||
UiTestUtils.setDummyData(getActivity(), gridView);
|
||||
gridView.setTouchInterceptionViewGroup((ViewGroup) parentActivity.findViewById(R.id.container));
|
||||
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
gridView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
|
||||
public class ViewPagerTab2ListViewFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_listview, container, false);
|
||||
|
||||
Activity parentActivity = getActivity();
|
||||
final ObservableListView listView = (ObservableListView) view.findViewById(R.id.scroll);
|
||||
UiTestUtils.setDummyData(getActivity(), listView);
|
||||
listView.setTouchInterceptionViewGroup((ViewGroup) parentActivity.findViewById(R.id.container));
|
||||
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
listView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
|
||||
public class ViewPagerTab2RecyclerViewFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_recyclerview, container, false);
|
||||
|
||||
Activity parentActivity = getActivity();
|
||||
final ObservableRecyclerView recyclerView = (ObservableRecyclerView) view.findViewById(R.id.scroll);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(parentActivity));
|
||||
recyclerView.setHasFixedSize(false);
|
||||
UiTestUtils.setDummyData(getActivity(), recyclerView);
|
||||
recyclerView.setTouchInterceptionViewGroup((ViewGroup) parentActivity.findViewById(R.id.container));
|
||||
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
recyclerView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
|
||||
public class ViewPagerTab2ScrollViewFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_scrollview_noheader, container, false);
|
||||
|
||||
final ObservableScrollView scrollView = (ObservableScrollView) view.findViewById(R.id.scroll);
|
||||
Activity parentActivity = getActivity();
|
||||
scrollView.setTouchInterceptionViewGroup((ViewGroup) parentActivity.findViewById(R.id.container));
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
scrollView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableWebView;
|
||||
|
||||
public class ViewPagerTab2WebViewFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_webview, container, false);
|
||||
|
||||
final ObservableWebView webView = (ObservableWebView) view.findViewById(R.id.scroll);
|
||||
webView.loadUrl("file:///android_asset/lipsum.html");
|
||||
Activity parentActivity = getActivity();
|
||||
webView.setTouchInterceptionViewGroup((ViewGroup) parentActivity.findViewById(R.id.container));
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
webView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,288 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.CacheFragmentStatePagerAdapter;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
import com.nineoldandroids.view.ViewPropertyAnimator;
|
||||
|
||||
public class ViewPagerTabActivity extends ActionBarActivity implements ObservableScrollViewCallbacks {
|
||||
|
||||
private View mHeaderView;
|
||||
private View mToolbarView;
|
||||
private int mBaseTranslationY;
|
||||
private ViewPager mPager;
|
||||
private NavigationAdapter mPagerAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_viewpagertab);
|
||||
|
||||
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
||||
|
||||
mHeaderView = findViewById(R.id.header);
|
||||
mToolbarView = findViewById(R.id.toolbar);
|
||||
mPagerAdapter = new NavigationAdapter(getSupportFragmentManager());
|
||||
mPager = (ViewPager) findViewById(R.id.pager);
|
||||
mPager.setAdapter(mPagerAdapter);
|
||||
|
||||
SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
|
||||
slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
|
||||
slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent));
|
||||
slidingTabLayout.setDistributeEvenly(true);
|
||||
slidingTabLayout.setViewPager(mPager);
|
||||
|
||||
// When the page is selected, other fragments' scrollY should be adjusted
|
||||
// according to the toolbar status(shown/hidden)
|
||||
slidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int i, float v, int i2) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int i) {
|
||||
propagateToolbarState(toolbarIsShown());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int i) {
|
||||
}
|
||||
});
|
||||
|
||||
propagateToolbarState(toolbarIsShown());
|
||||
}
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
if (dragging) {
|
||||
int toolbarHeight = mToolbarView.getHeight();
|
||||
float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView);
|
||||
if (firstScroll) {
|
||||
if (-toolbarHeight < currentHeaderTranslationY) {
|
||||
mBaseTranslationY = scrollY;
|
||||
}
|
||||
}
|
||||
float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0);
|
||||
ViewPropertyAnimator.animate(mHeaderView).cancel();
|
||||
ViewHelper.setTranslationY(mHeaderView, headerTranslationY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
mBaseTranslationY = 0;
|
||||
|
||||
Fragment fragment = getCurrentFragment();
|
||||
if (fragment == null) {
|
||||
return;
|
||||
}
|
||||
View view = fragment.getView();
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ObservableXxxViews have same API
|
||||
// but currently they don't have any common interfaces.
|
||||
adjustToolbar(scrollState, view);
|
||||
}
|
||||
|
||||
public Scrollable getCurrentScrollable() {
|
||||
Fragment fragment = getCurrentFragment();
|
||||
if (fragment == null) {
|
||||
return null;
|
||||
}
|
||||
View view = fragment.getView();
|
||||
if (view == null) {
|
||||
return null;
|
||||
}
|
||||
return (Scrollable) view.findViewById(R.id.scroll);
|
||||
}
|
||||
|
||||
private void adjustToolbar(ScrollState scrollState, View view) {
|
||||
int toolbarHeight = mToolbarView.getHeight();
|
||||
final Scrollable scrollView = (Scrollable) view.findViewById(R.id.scroll);
|
||||
if (scrollView == null) {
|
||||
return;
|
||||
}
|
||||
int scrollY = scrollView.getCurrentScrollY();
|
||||
if (scrollState == ScrollState.DOWN) {
|
||||
showToolbar();
|
||||
} else if (scrollState == ScrollState.UP) {
|
||||
if (toolbarHeight <= scrollY) {
|
||||
hideToolbar();
|
||||
} else {
|
||||
showToolbar();
|
||||
}
|
||||
} else {
|
||||
// Even if onScrollChanged occurs without scrollY changing, toolbar should be adjusted
|
||||
if (toolbarIsShown() || toolbarIsHidden()) {
|
||||
// Toolbar is completely moved, so just keep its state
|
||||
// and propagate it to other pages
|
||||
propagateToolbarState(toolbarIsShown());
|
||||
} else {
|
||||
// Toolbar is moving but doesn't know which to move:
|
||||
// you can change this to hideToolbar()
|
||||
showToolbar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Fragment getCurrentFragment() {
|
||||
return mPagerAdapter.getItemAt(mPager.getCurrentItem());
|
||||
}
|
||||
|
||||
private void propagateToolbarState(boolean isShown) {
|
||||
int toolbarHeight = mToolbarView.getHeight();
|
||||
|
||||
// Set scrollY for the fragments that are not created yet
|
||||
mPagerAdapter.setScrollY(isShown ? 0 : toolbarHeight);
|
||||
|
||||
// Set scrollY for the active fragments
|
||||
for (int i = 0; i < mPagerAdapter.getCount(); i++) {
|
||||
// Skip current item
|
||||
if (i == mPager.getCurrentItem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip destroyed or not created item
|
||||
Fragment f = mPagerAdapter.getItemAt(i);
|
||||
if (f == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
View view = f.getView();
|
||||
if (view == null) {
|
||||
continue;
|
||||
}
|
||||
propagateToolbarState(isShown, view, toolbarHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private void propagateToolbarState(boolean isShown, View view, int toolbarHeight) {
|
||||
Scrollable scrollView = (Scrollable) view.findViewById(R.id.scroll);
|
||||
if (scrollView == null) {
|
||||
return;
|
||||
}
|
||||
if (isShown) {
|
||||
// Scroll up
|
||||
if (0 < scrollView.getCurrentScrollY()) {
|
||||
scrollView.scrollVerticallyTo(0);
|
||||
}
|
||||
} else {
|
||||
// Scroll down (to hide padding)
|
||||
if (scrollView.getCurrentScrollY() < toolbarHeight) {
|
||||
scrollView.scrollVerticallyTo(toolbarHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean toolbarIsShown() {
|
||||
return ViewHelper.getTranslationY(mHeaderView) == 0;
|
||||
}
|
||||
|
||||
private boolean toolbarIsHidden() {
|
||||
return ViewHelper.getTranslationY(mHeaderView) == -mToolbarView.getHeight();
|
||||
}
|
||||
|
||||
private void showToolbar() {
|
||||
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
|
||||
if (headerTranslationY != 0) {
|
||||
ViewPropertyAnimator.animate(mHeaderView).cancel();
|
||||
ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start();
|
||||
}
|
||||
propagateToolbarState(true);
|
||||
}
|
||||
|
||||
private void hideToolbar() {
|
||||
float headerTranslationY = ViewHelper.getTranslationY(mHeaderView);
|
||||
int toolbarHeight = mToolbarView.getHeight();
|
||||
if (headerTranslationY != -toolbarHeight) {
|
||||
ViewPropertyAnimator.animate(mHeaderView).cancel();
|
||||
ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start();
|
||||
}
|
||||
propagateToolbarState(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This adapter provides two types of fragments as an example.
|
||||
* {@linkplain #createItem(int)} should be modified if you use this example for your app.
|
||||
*/
|
||||
private static class NavigationAdapter extends CacheFragmentStatePagerAdapter {
|
||||
|
||||
private static final String[] TITLES = new String[]{"Applepie", "Butter Cookie", "Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean", "KitKat", "Lollipop"};
|
||||
|
||||
private int mScrollY;
|
||||
|
||||
public NavigationAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
public void setScrollY(int scrollY) {
|
||||
mScrollY = scrollY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Fragment createItem(int position) {
|
||||
// Initialize fragments.
|
||||
// Please be sure to pass scroll position to each fragments using setArguments.
|
||||
Fragment f;
|
||||
final int pattern = position % 3;
|
||||
switch (pattern) {
|
||||
case 0: {
|
||||
f = new ViewPagerTabScrollViewFragment();
|
||||
if (0 <= mScrollY) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ViewPagerTabScrollViewFragment.ARG_SCROLL_Y, mScrollY);
|
||||
f.setArguments(args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
f = new ViewPagerTabListViewFragment();
|
||||
if (0 < mScrollY) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ViewPagerTabListViewFragment.ARG_INITIAL_POSITION, 1);
|
||||
f.setArguments(args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
default: {
|
||||
f = new ViewPagerTabRecyclerViewFragment();
|
||||
if (0 < mScrollY) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ViewPagerTabRecyclerViewFragment.ARG_INITIAL_POSITION, 1);
|
||||
f.setArguments(args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return TITLES.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return TITLES[position];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.View;
|
||||
|
||||
public class ViewPagerTabActivityTest extends ActivityInstrumentationTestCase2<ViewPagerTabActivity> {
|
||||
|
||||
private ViewPagerTabActivity activity;
|
||||
|
||||
public ViewPagerTabActivityTest() {
|
||||
super(ViewPagerTabActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UiTestUtils.swipeHorizontally(this, activity.findViewById(R.id.pager), UiTestUtils.Direction.LEFT);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
scroll();
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UiTestUtils.swipeHorizontally(this, activity.findViewById(R.id.pager), UiTestUtils.Direction.RIGHT);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
scroll();
|
||||
}
|
||||
}
|
||||
|
||||
public void scroll() throws Throwable {
|
||||
View scrollable = ((View) activity.getCurrentScrollable()).findViewById(R.id.scroll);
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
scroll();
|
||||
|
||||
UiTestUtils.swipeHorizontally(this, activity.findViewById(R.id.pager), UiTestUtils.Direction.LEFT);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
|
||||
public class ViewPagerTabListViewFragment extends Fragment {
|
||||
|
||||
public static final String ARG_INITIAL_POSITION = "ARG_INITIAL_POSITION";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_listview, container, false);
|
||||
|
||||
Activity parentActivity = getActivity();
|
||||
final ObservableListView listView = (ObservableListView) view.findViewById(R.id.scroll);
|
||||
UiTestUtils.setDummyDataWithHeader(getActivity(), listView, inflater.inflate(R.layout.padding, null));
|
||||
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
// Scroll to the specified position after layout
|
||||
Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(ARG_INITIAL_POSITION)) {
|
||||
final int initialPosition = args.getInt(ARG_INITIAL_POSITION, 0);
|
||||
ScrollUtils.addOnGlobalLayoutListener(listView, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// scrollTo() doesn't work, should use setSelection()
|
||||
listView.setSelection(initialPosition);
|
||||
}
|
||||
});
|
||||
}
|
||||
listView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
|
||||
public class ViewPagerTabRecyclerViewFragment extends Fragment {
|
||||
|
||||
public static final String ARG_INITIAL_POSITION = "ARG_INITIAL_POSITION";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_recyclerview, container, false);
|
||||
|
||||
Activity parentActivity = getActivity();
|
||||
final ObservableRecyclerView recyclerView = (ObservableRecyclerView) view.findViewById(R.id.scroll);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(parentActivity));
|
||||
recyclerView.setHasFixedSize(false);
|
||||
View headerView = LayoutInflater.from(parentActivity).inflate(R.layout.padding, null);
|
||||
UiTestUtils.setDummyDataWithHeader(getActivity(), recyclerView, headerView);
|
||||
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
// Scroll to the specified offset after layout
|
||||
Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(ARG_INITIAL_POSITION)) {
|
||||
final int initialPosition = args.getInt(ARG_INITIAL_POSITION, 0);
|
||||
ScrollUtils.addOnGlobalLayoutListener(recyclerView, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
recyclerView.scrollVerticallyToPosition(initialPosition);
|
||||
}
|
||||
});
|
||||
}
|
||||
recyclerView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Soichiro Kashima
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
|
||||
|
||||
public class ViewPagerTabScrollViewFragment extends Fragment {
|
||||
|
||||
public static final String ARG_SCROLL_Y = "ARG_SCROLL_Y";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_scrollview, container, false);
|
||||
|
||||
final ObservableScrollView scrollView = (ObservableScrollView) view.findViewById(R.id.scroll);
|
||||
Activity parentActivity = getActivity();
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
// Scroll to the specified offset after layout
|
||||
Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(ARG_SCROLL_Y)) {
|
||||
final int scrollY = args.getInt(ARG_SCROLL_Y, 0);
|
||||
ScrollUtils.addOnGlobalLayoutListener(scrollView, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollView.scrollTo(0, scrollY);
|
||||
}
|
||||
});
|
||||
}
|
||||
scrollView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableWebView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.github.ksoichiro.android.observablescrollview.Scrollable;
|
||||
|
||||
public class WebViewActivity extends Activity implements ObservableScrollViewCallbacks {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_webview);
|
||||
ObservableWebView scrollable = (ObservableWebView) findViewById(R.id.scrollable);
|
||||
scrollable.setScrollViewCallbacks(this);
|
||||
scrollable.loadUrl("file:///android_asset/lipsum.html");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package com.github.ksoichiro.android.observablescrollview.test;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableWebView;
|
||||
|
||||
public class WebViewActivityTest extends ActivityInstrumentationTestCase2<WebViewActivity> {
|
||||
|
||||
private Activity activity;
|
||||
private ObservableWebView scrollable;
|
||||
|
||||
public WebViewActivityTest() {
|
||||
super(WebViewActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(true);
|
||||
activity = getActivity();
|
||||
scrollable = (ObservableWebView) activity.findViewById(R.id.scrollable);
|
||||
}
|
||||
|
||||
public void testScroll() throws Throwable {
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.UP);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
UiTestUtils.swipeVertically(this, scrollable, UiTestUtils.Direction.DOWN);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testSaveAndRestoreInstanceState() throws Throwable {
|
||||
UiTestUtils.saveAndRestoreInstanceState(this, activity);
|
||||
testScroll();
|
||||
}
|
||||
|
||||
public void testScrollVerticallyTo() throws Throwable {
|
||||
final DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, metrics));
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
runTestOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollable.scrollVerticallyTo(0);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
|
@ -1,321 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.iosched.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseArray;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* To be used with ViewPager to provide a tab indicator component which give constant feedback as to
|
||||
* the user's scroll progress.
|
||||
* <p>
|
||||
* To use the component, simply add it to your view hierarchy. Then in your
|
||||
* {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
|
||||
* {@link #setViewPager(android.support.v4.view.ViewPager)} providing it the ViewPager this layout is being used for.
|
||||
* <p>
|
||||
* The colors can be customized in two ways. The first and simplest is to provide an array of colors
|
||||
* via {@link #setSelectedIndicatorColors(int...)}. The
|
||||
* alternative is via the {@link com.google.samples.apps.iosched.ui.widget.SlidingTabLayout.TabColorizer} interface which provides you complete control over
|
||||
* which color is used for any individual position.
|
||||
* <p>
|
||||
* The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
|
||||
* providing the layout ID of your custom layout.
|
||||
*/
|
||||
public class SlidingTabLayout extends HorizontalScrollView {
|
||||
/**
|
||||
* Allows complete control over the colors drawn in the tab layout. Set with
|
||||
* {@link #setCustomTabColorizer(com.google.samples.apps.iosched.ui.widget.SlidingTabLayout.TabColorizer)}.
|
||||
*/
|
||||
public interface TabColorizer {
|
||||
|
||||
/**
|
||||
* @return return the color of the indicator used when {@code position} is selected.
|
||||
*/
|
||||
int getIndicatorColor(int position);
|
||||
|
||||
}
|
||||
|
||||
private static final int TITLE_OFFSET_DIPS = 24;
|
||||
private static final int TAB_VIEW_PADDING_DIPS = 16;
|
||||
private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
|
||||
|
||||
private int mTitleOffset;
|
||||
|
||||
private int mTabViewLayoutId;
|
||||
private int mTabViewTextViewId;
|
||||
private boolean mDistributeEvenly;
|
||||
|
||||
private ViewPager mViewPager;
|
||||
private SparseArray<String> mContentDescriptions = new SparseArray<String>();
|
||||
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
|
||||
|
||||
private final SlidingTabStrip mTabStrip;
|
||||
|
||||
public SlidingTabLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SlidingTabLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
// Disable the Scroll Bar
|
||||
setHorizontalScrollBarEnabled(false);
|
||||
// Make sure that the Tab Strips fills this View
|
||||
setFillViewport(true);
|
||||
|
||||
mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
|
||||
|
||||
mTabStrip = new SlidingTabStrip(context);
|
||||
addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the custom {@link com.google.samples.apps.iosched.ui.widget.SlidingTabLayout.TabColorizer} to be used.
|
||||
*
|
||||
* If you only require simple custmisation then you can use
|
||||
* {@link #setSelectedIndicatorColors(int...)} to achieve
|
||||
* similar effects.
|
||||
*/
|
||||
public void setCustomTabColorizer(TabColorizer tabColorizer) {
|
||||
mTabStrip.setCustomTabColorizer(tabColorizer);
|
||||
}
|
||||
|
||||
public void setDistributeEvenly(boolean distributeEvenly) {
|
||||
mDistributeEvenly = distributeEvenly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the colors to be used for indicating the selected tab. These colors are treated as a
|
||||
* circular array. Providing one color will mean that all tabs are indicated with the same color.
|
||||
*/
|
||||
public void setSelectedIndicatorColors(int... colors) {
|
||||
mTabStrip.setSelectedIndicatorColors(colors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link android.support.v4.view.ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
|
||||
* required to set any {@link android.support.v4.view.ViewPager.OnPageChangeListener} through this method. This is so
|
||||
* that the layout can update it's scroll position correctly.
|
||||
*
|
||||
* @see android.support.v4.view.ViewPager#setOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener)
|
||||
*/
|
||||
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
|
||||
mViewPagerPageChangeListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the custom layout to be inflated for the tab views.
|
||||
*
|
||||
* @param layoutResId Layout id to be inflated
|
||||
* @param textViewId id of the {@link android.widget.TextView} in the inflated view
|
||||
*/
|
||||
public void setCustomTabView(int layoutResId, int textViewId) {
|
||||
mTabViewLayoutId = layoutResId;
|
||||
mTabViewTextViewId = textViewId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the associated view pager. Note that the assumption here is that the pager content
|
||||
* (number of tabs and tab titles) does not change after this call has been made.
|
||||
*/
|
||||
public void setViewPager(ViewPager viewPager) {
|
||||
mTabStrip.removeAllViews();
|
||||
|
||||
mViewPager = viewPager;
|
||||
if (viewPager != null) {
|
||||
viewPager.setOnPageChangeListener(new InternalViewPagerListener());
|
||||
populateTabStrip();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default view to be used for tabs. This is called if a custom tab view is not set via
|
||||
* {@link #setCustomTabView(int, int)}.
|
||||
*/
|
||||
protected TextView createDefaultTabView(Context context) {
|
||||
TextView textView = new TextView(context);
|
||||
textView.setGravity(Gravity.CENTER);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
|
||||
textView.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
textView.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
TypedValue outValue = new TypedValue();
|
||||
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
|
||||
outValue, true);
|
||||
textView.setBackgroundResource(outValue.resourceId);
|
||||
textView.setAllCaps(true);
|
||||
|
||||
int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
|
||||
textView.setPadding(padding, padding, padding, padding);
|
||||
|
||||
return textView;
|
||||
}
|
||||
|
||||
private void populateTabStrip() {
|
||||
final PagerAdapter adapter = mViewPager.getAdapter();
|
||||
final OnClickListener tabClickListener = new TabClickListener();
|
||||
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
View tabView = null;
|
||||
TextView tabTitleView = null;
|
||||
|
||||
if (mTabViewLayoutId != 0) {
|
||||
// If there is a custom tab view layout id set, try and inflate it
|
||||
tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
|
||||
false);
|
||||
tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
|
||||
}
|
||||
|
||||
if (tabView == null) {
|
||||
tabView = createDefaultTabView(getContext());
|
||||
}
|
||||
|
||||
if (tabTitleView == null && TextView.class.isInstance(tabView)) {
|
||||
tabTitleView = (TextView) tabView;
|
||||
}
|
||||
|
||||
if (mDistributeEvenly) {
|
||||
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
|
||||
lp.width = 0;
|
||||
lp.weight = 1;
|
||||
}
|
||||
|
||||
tabTitleView.setText(adapter.getPageTitle(i));
|
||||
tabView.setOnClickListener(tabClickListener);
|
||||
String desc = mContentDescriptions.get(i, null);
|
||||
if (desc != null) {
|
||||
tabView.setContentDescription(desc);
|
||||
}
|
||||
|
||||
mTabStrip.addView(tabView);
|
||||
if (i == mViewPager.getCurrentItem()) {
|
||||
tabView.setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setContentDescription(int i, String desc) {
|
||||
mContentDescriptions.put(i, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
if (mViewPager != null) {
|
||||
scrollToTab(mViewPager.getCurrentItem(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void scrollToTab(int tabIndex, int positionOffset) {
|
||||
final int tabStripChildCount = mTabStrip.getChildCount();
|
||||
if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
View selectedChild = mTabStrip.getChildAt(tabIndex);
|
||||
if (selectedChild != null) {
|
||||
int targetScrollX = selectedChild.getLeft() + positionOffset;
|
||||
|
||||
if (tabIndex > 0 || positionOffset > 0) {
|
||||
// If we're not at the first child and are mid-scroll, make sure we obey the offset
|
||||
targetScrollX -= mTitleOffset;
|
||||
}
|
||||
|
||||
scrollTo(targetScrollX, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
|
||||
private int mScrollState;
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
int tabStripChildCount = mTabStrip.getChildCount();
|
||||
if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTabStrip.onViewPagerPageChanged(position, positionOffset);
|
||||
|
||||
View selectedTitle = mTabStrip.getChildAt(position);
|
||||
int extraOffset = (selectedTitle != null)
|
||||
? (int) (positionOffset * selectedTitle.getWidth())
|
||||
: 0;
|
||||
scrollToTab(position, extraOffset);
|
||||
|
||||
if (mViewPagerPageChangeListener != null) {
|
||||
mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
|
||||
positionOffsetPixels);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
mScrollState = state;
|
||||
|
||||
if (mViewPagerPageChangeListener != null) {
|
||||
mViewPagerPageChangeListener.onPageScrollStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
|
||||
mTabStrip.onViewPagerPageChanged(position, 0f);
|
||||
scrollToTab(position, 0);
|
||||
}
|
||||
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
|
||||
mTabStrip.getChildAt(i).setSelected(position == i);
|
||||
}
|
||||
if (mViewPagerPageChangeListener != null) {
|
||||
mViewPagerPageChangeListener.onPageSelected(position);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class TabClickListener implements OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
|
||||
if (v == mTabStrip.getChildAt(i)) {
|
||||
mViewPager.setCurrentItem(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.iosched.ui.widget;
|
||||
|
||||
import android.R;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
class SlidingTabStrip extends LinearLayout {
|
||||
|
||||
private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 0;
|
||||
private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
|
||||
private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 3;
|
||||
private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
|
||||
|
||||
private final int mBottomBorderThickness;
|
||||
private final Paint mBottomBorderPaint;
|
||||
|
||||
private final int mSelectedIndicatorThickness;
|
||||
private final Paint mSelectedIndicatorPaint;
|
||||
|
||||
private final int mDefaultBottomBorderColor;
|
||||
|
||||
private int mSelectedPosition;
|
||||
private float mSelectionOffset;
|
||||
|
||||
private SlidingTabLayout.TabColorizer mCustomTabColorizer;
|
||||
private final SimpleTabColorizer mDefaultTabColorizer;
|
||||
|
||||
SlidingTabStrip(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
SlidingTabStrip(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setWillNotDraw(false);
|
||||
|
||||
final float density = getResources().getDisplayMetrics().density;
|
||||
|
||||
TypedValue outValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
|
||||
final int themeForegroundColor = outValue.data;
|
||||
|
||||
mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
|
||||
DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
|
||||
|
||||
mDefaultTabColorizer = new SimpleTabColorizer();
|
||||
mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
|
||||
|
||||
mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
|
||||
mBottomBorderPaint = new Paint();
|
||||
mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
|
||||
|
||||
mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
|
||||
mSelectedIndicatorPaint = new Paint();
|
||||
}
|
||||
|
||||
void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
|
||||
mCustomTabColorizer = customTabColorizer;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void setSelectedIndicatorColors(int... colors) {
|
||||
// Make sure that the custom colorizer is removed
|
||||
mCustomTabColorizer = null;
|
||||
mDefaultTabColorizer.setIndicatorColors(colors);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void onViewPagerPageChanged(int position, float positionOffset) {
|
||||
mSelectedPosition = position;
|
||||
mSelectionOffset = positionOffset;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
final int height = getHeight();
|
||||
final int childCount = getChildCount();
|
||||
final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
|
||||
? mCustomTabColorizer
|
||||
: mDefaultTabColorizer;
|
||||
|
||||
// Thick colored underline below the current selection
|
||||
if (childCount > 0) {
|
||||
View selectedTitle = getChildAt(mSelectedPosition);
|
||||
int left = selectedTitle.getLeft();
|
||||
int right = selectedTitle.getRight();
|
||||
int color = tabColorizer.getIndicatorColor(mSelectedPosition);
|
||||
|
||||
if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
|
||||
int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
|
||||
if (color != nextColor) {
|
||||
color = blendColors(nextColor, color, mSelectionOffset);
|
||||
}
|
||||
|
||||
// Draw the selection partway between the tabs
|
||||
View nextTitle = getChildAt(mSelectedPosition + 1);
|
||||
left = (int) (mSelectionOffset * nextTitle.getLeft() +
|
||||
(1.0f - mSelectionOffset) * left);
|
||||
right = (int) (mSelectionOffset * nextTitle.getRight() +
|
||||
(1.0f - mSelectionOffset) * right);
|
||||
}
|
||||
|
||||
mSelectedIndicatorPaint.setColor(color);
|
||||
|
||||
canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
|
||||
height, mSelectedIndicatorPaint);
|
||||
}
|
||||
|
||||
// Thin underline along the entire bottom edge
|
||||
canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha value of the {@code color} to be the given {@code alpha} value.
|
||||
*/
|
||||
private static int setColorAlpha(int color, byte alpha) {
|
||||
return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
|
||||
}
|
||||
|
||||
/**
|
||||
* Blend {@code color1} and {@code color2} using the given ratio.
|
||||
*
|
||||
* @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
|
||||
* 0.0 will return {@code color2}.
|
||||
*/
|
||||
private static int blendColors(int color1, int color2, float ratio) {
|
||||
final float inverseRation = 1f - ratio;
|
||||
float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
|
||||
float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
|
||||
float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
|
||||
return Color.rgb((int) r, (int) g, (int) b);
|
||||
}
|
||||
|
||||
private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
|
||||
private int[] mIndicatorColors;
|
||||
|
||||
@Override
|
||||
public final int getIndicatorColor(int position) {
|
||||
return mIndicatorColors[position % mIndicatorColors.length];
|
||||
}
|
||||
|
||||
void setIndicatorColors(int... colors) {
|
||||
mIndicatorColors = colors;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:color="#fff" android:state_selected="true" />
|
||||
<item android:color="#9fff" />
|
||||
|
||||
</selector>
|
|
@ -1,20 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.github.ksoichiro.android.observablescrollview.ObservableGridView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:numColumns="2" />
|
|
@ -1,19 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.github.ksoichiro.android.observablescrollview.ObservableListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
|
@ -1,19 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
|
@ -1,27 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.github.ksoichiro.android.observablescrollview.ObservableScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/lipsum" />
|
||||
|
||||
</com.github.ksoichiro.android.observablescrollview.ObservableScrollView>
|
|
@ -1,66 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout
|
||||
android:id="@+id/scroll_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.github.ksoichiro.android.observablescrollview.ObservableGridView
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/header_bar_height"
|
||||
android:numColumns="2" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false">
|
||||
|
||||
<View
|
||||
android:id="@+id/header_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_bar_height"
|
||||
android:background="@color/primary"
|
||||
android:minHeight="@dimen/header_bar_height" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_bar_height"
|
||||
android:minHeight="@dimen/header_bar_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_bar_size"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
</com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout>
|
||||
</FrameLayout>
|
|
@ -1,66 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout
|
||||
android:id="@+id/scroll_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.github.ksoichiro.android.observablescrollview.ObservableListView
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/header_bar_height"
|
||||
android:overScrollMode="never" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false">
|
||||
|
||||
<View
|
||||
android:id="@+id/header_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_bar_height"
|
||||
android:background="@color/primary"
|
||||
android:minHeight="@dimen/header_bar_height" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_bar_height"
|
||||
android:minHeight="@dimen/header_bar_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_bar_size"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
</com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout>
|
||||
</FrameLayout>
|
|
@ -1,65 +0,0 @@
|
|||
<!--
|
||||
Copyright 2014 Soichiro Kashima
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout
|
||||
android:id="@+id/scroll_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView
|
||||
android:id="@+id/scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/header_bar_height" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false">
|
||||
|
||||
<View
|
||||
android:id="@+id/header_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_bar_height"
|
||||
android:background="@color/primary"
|
||||
android:minHeight="@dimen/header_bar_height" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_bar_height"
|
||||
android:minHeight="@dimen/header_bar_height"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_bar_size"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
</com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout>
|
||||
</FrameLayout>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue