Merge "Fix ScrollView and HorizontalScrollView overscroll retraction" into udc-qpr-dev

This commit is contained in:
Treehugger Robot
2023-08-14 12:48:41 +00:00
committed by Android (Google) Code Review
9 changed files with 478 additions and 0 deletions

View File

@@ -1498,6 +1498,11 @@ public class HorizontalScrollView extends FrameLayout {
* @return The unconsumed delta after the EdgeEffects have had an opportunity to consume.
*/
private int consumeFlingInStretch(int unconsumed) {
int scrollX = getScrollX();
if (scrollX < 0 || scrollX > getScrollRange()) {
// We've overscrolled, so don't stretch
return unconsumed;
}
if (unconsumed > 0 && mEdgeGlowLeft != null && mEdgeGlowLeft.getDistance() != 0f) {
int size = getWidth();
float deltaDistance = -unconsumed * FLING_DESTRETCH_FACTOR / size;

View File

@@ -1545,6 +1545,11 @@ public class ScrollView extends FrameLayout {
* @return The unconsumed delta after the EdgeEffects have had an opportunity to consume.
*/
private int consumeFlingInStretch(int unconsumed) {
int scrollY = getScrollY();
if (scrollY < 0 || scrollY > getScrollRange()) {
// We've overscrolled, so don't stretch
return unconsumed;
}
if (unconsumed > 0 && mEdgeGlowTop != null && mEdgeGlowTop.getDistance() != 0f) {
int size = getHeight();
float deltaDistance = -unconsumed * FLING_DESTRETCH_FACTOR / size;

View File

@@ -231,6 +231,28 @@
</intent-filter>
</activity>
<activity android:name="android.widget.HorizontalScrollViewActivity"
android:label="HorizontalScrollViewActivity"
android:screenOrientation="portrait"
android:exported="true"
android:theme="@android:style/Theme.Material.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
</intent-filter>
</activity>
<activity android:name="android.widget.ScrollViewActivity"
android:label="ScrollViewActivity"
android:screenOrientation="portrait"
android:exported="true"
android:theme="@android:style/Theme.Material.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
</intent-filter>
</activity>
<activity android:name="android.widget.DatePickerActivity"
android:label="DatePickerActivity"
android:screenOrientation="portrait"

View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2015 The Android Open Source Project
~
~ 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
-->
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/horizontal_scroll_view">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:background="#F00"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#880"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#0F0"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#088"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#00F"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#808"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#F00"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#880"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#0F0"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#088"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#00F"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#808"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#F00"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#880"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#0F0"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#088"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#00F"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#808"
android:layout_width="100dp"
android:layout_height="100dp" />
</LinearLayout>
</HorizontalScrollView>

View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2015 The Android Open Source Project
~
~ 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
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/scroll_view">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:background="#F00"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#880"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#0F0"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#088"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#00F"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#808"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#F00"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#880"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#0F0"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#088"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#00F"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#808"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#F00"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#880"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#0F0"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#088"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#00F"
android:layout_width="100dp"
android:layout_height="100dp" />
<View
android:background="#808"
android:layout_width="100dp"
android:layout_height="100dp" />
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* 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 android.widget;
import android.app.Activity;
import android.os.Bundle;
import com.android.frameworks.coretests.R;
/**
* An activity for testing the TextView widget.
*/
public class HorizontalScrollViewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_horizontal_scroll_view);
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* 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 android.widget;
import static org.junit.Assert.assertEquals;
import android.platform.test.annotations.Presubmit;
import android.util.PollingCheck;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.coretests.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@MediumTest
@Presubmit
public class HorizontalScrollViewFunctionalTest {
private HorizontalScrollViewActivity mActivity;
private HorizontalScrollView mHorizontalScrollView;
@Rule
public ActivityTestRule<HorizontalScrollViewActivity> mActivityRule = new ActivityTestRule<>(
HorizontalScrollViewActivity.class);
@Before
public void setUp() throws Exception {
mActivity = mActivityRule.getActivity();
mHorizontalScrollView = mActivity.findViewById(R.id.horizontal_scroll_view);
}
@Test
public void testScrollAfterFlingTop() {
mHorizontalScrollView.scrollTo(100, 0);
mHorizontalScrollView.fling(-10000);
PollingCheck.waitFor(() -> mHorizontalScrollView.mEdgeGlowLeft.getDistance() > 0);
PollingCheck.waitFor(() -> mHorizontalScrollView.mEdgeGlowLeft.getDistance() == 0f);
assertEquals(0, mHorizontalScrollView.getScrollX());
}
@Test
public void testScrollAfterFlingBottom() {
int childWidth = mHorizontalScrollView.getChildAt(0).getWidth();
int maxScroll = childWidth - mHorizontalScrollView.getWidth();
mHorizontalScrollView.scrollTo(maxScroll - 100, 0);
mHorizontalScrollView.fling(10000);
PollingCheck.waitFor(() -> mHorizontalScrollView.mEdgeGlowRight.getDistance() > 0);
PollingCheck.waitFor(() -> mHorizontalScrollView.mEdgeGlowRight.getDistance() == 0f);
assertEquals(maxScroll, mHorizontalScrollView.getScrollX());
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* 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 android.widget;
import android.app.Activity;
import android.os.Bundle;
import com.android.frameworks.coretests.R;
/**
* An activity for testing the TextView widget.
*/
public class ScrollViewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroll_view);
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* 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 android.widget;
import static org.junit.Assert.assertEquals;
import android.platform.test.annotations.Presubmit;
import android.util.PollingCheck;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.coretests.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@MediumTest
@Presubmit
public class ScrollViewFunctionalTest {
private ScrollViewActivity mActivity;
private ScrollView mScrollView;
@Rule
public ActivityTestRule<ScrollViewActivity> mActivityRule = new ActivityTestRule<>(
ScrollViewActivity.class);
@Before
public void setUp() throws Exception {
mActivity = mActivityRule.getActivity();
mScrollView = mActivity.findViewById(R.id.scroll_view);
}
@Test
public void testScrollAfterFlingTop() {
mScrollView.scrollTo(0, 100);
mScrollView.fling(-10000);
PollingCheck.waitFor(() -> mScrollView.mEdgeGlowTop.getDistance() > 0);
PollingCheck.waitFor(() -> mScrollView.mEdgeGlowTop.getDistance() == 0f);
assertEquals(0, mScrollView.getScrollY());
}
@Test
public void testScrollAfterFlingBottom() {
int childHeight = mScrollView.getChildAt(0).getHeight();
int maxScroll = childHeight - mScrollView.getHeight();
mScrollView.scrollTo(0, maxScroll - 100);
mScrollView.fling(10000);
PollingCheck.waitFor(() -> mScrollView.mEdgeGlowBottom.getDistance() > 0);
PollingCheck.waitFor(() -> mScrollView.mEdgeGlowBottom.getDistance() == 0f);
assertEquals(maxScroll, mScrollView.getScrollY());
}
}