This repository has been archived by the owner on Nov 4, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #62 from zeoflow/material-viewpager
Material ViewPager
- Loading branch information
Showing
20 changed files
with
3,865 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
material-elements/java/com/zeoflow/material/elements/slidingpanel/ViewDragHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
...al-elements/java/com/zeoflow/material/elements/viewpager/AnimateLayoutChangeDetector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* Copyright 2021 ZeoFlow SRL | ||
* | ||
* 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.zeoflow.material.elements.viewpager; | ||
|
||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; | ||
|
||
import static com.zeoflow.material.elements.viewpager.MaterialViewPager.ORIENTATION_HORIZONTAL; | ||
|
||
import android.animation.LayoutTransition; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.recyclerview.widget.LinearLayoutManager; | ||
|
||
import java.util.Arrays; | ||
import java.util.Comparator; | ||
|
||
/** | ||
* Class used to detect if there are gaps between pages and if any of the pages contain a running | ||
* change-transition in case we detected an illegal state in the {@link ScrollEventAdapter}. | ||
* | ||
* This is an approximation of the detection and could potentially lead to misleading advice. If we | ||
* hit problems with it, remove the detection and replace with a suggestive error message instead, | ||
* like "Negative page offset encountered. Did you setAnimateParentHierarchy(false) to all your | ||
* LayoutTransitions?". | ||
*/ | ||
final class AnimateLayoutChangeDetector { | ||
private static final ViewGroup.MarginLayoutParams ZERO_MARGIN_LAYOUT_PARAMS; | ||
|
||
static { | ||
ZERO_MARGIN_LAYOUT_PARAMS = new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT); | ||
ZERO_MARGIN_LAYOUT_PARAMS.setMargins(0, 0, 0, 0); | ||
} | ||
|
||
private LinearLayoutManager mLayoutManager; | ||
|
||
AnimateLayoutChangeDetector(@NonNull LinearLayoutManager llm) { | ||
mLayoutManager = llm; | ||
} | ||
|
||
boolean mayHaveInterferingAnimations() { | ||
// Two conditions need to be satisfied: | ||
// 1) the pages are not laid out contiguously (i.e., there are gaps between them) | ||
// 2) there is a ViewGroup with a LayoutTransition that isChangingLayout() | ||
return (!arePagesLaidOutContiguously() || mLayoutManager.getChildCount() <= 1) | ||
&& hasRunningChangingLayoutTransition(); | ||
} | ||
|
||
private boolean arePagesLaidOutContiguously() { | ||
// Collect view positions | ||
int childCount = mLayoutManager.getChildCount(); | ||
if (childCount == 0) { | ||
return true; | ||
} | ||
|
||
boolean isHorizontal = mLayoutManager.getOrientation() == ORIENTATION_HORIZONTAL; | ||
int[][] bounds = new int[childCount][2]; | ||
for (int i = 0; i < childCount; i++) { | ||
View view = mLayoutManager.getChildAt(i); | ||
if (view == null) { | ||
throw new IllegalStateException("null view contained in the view hierarchy"); | ||
} | ||
ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); | ||
ViewGroup.MarginLayoutParams margin; | ||
if (layoutParams instanceof ViewGroup.MarginLayoutParams) { | ||
margin = (ViewGroup.MarginLayoutParams) layoutParams; | ||
} else { | ||
margin = ZERO_MARGIN_LAYOUT_PARAMS; | ||
} | ||
bounds[i][0] = isHorizontal | ||
? view.getLeft() - margin.leftMargin | ||
: view.getTop() - margin.topMargin; | ||
bounds[i][1] = isHorizontal | ||
? view.getRight() + margin.rightMargin | ||
: view.getBottom() + margin.bottomMargin; | ||
} | ||
|
||
// Sort them | ||
Arrays.sort(bounds, new Comparator<int[]>() { | ||
@Override | ||
public int compare(int[] lhs, int[] rhs) { | ||
return lhs[0] - rhs[0]; | ||
} | ||
}); | ||
|
||
// Check for inconsistencies | ||
for (int i = 1; i < childCount; i++) { | ||
if (bounds[i - 1][1] != bounds[i][0]) { | ||
return false; | ||
} | ||
} | ||
|
||
// Check that the pages fill the whole screen | ||
int pageSize = bounds[0][1] - bounds[0][0]; | ||
if (bounds[0][0] > 0 || bounds[childCount - 1][1] < pageSize) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
private boolean hasRunningChangingLayoutTransition() { | ||
int childCount = mLayoutManager.getChildCount(); | ||
for (int i = 0; i < childCount; i++) { | ||
if (hasRunningChangingLayoutTransition(mLayoutManager.getChildAt(i))) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
private static boolean hasRunningChangingLayoutTransition(View view) { | ||
if (view instanceof ViewGroup) { | ||
ViewGroup viewGroup = (ViewGroup) view; | ||
LayoutTransition layoutTransition = viewGroup.getLayoutTransition(); | ||
if (layoutTransition != null && layoutTransition.isChangingLayout()) { | ||
return true; | ||
} | ||
int childCount = viewGroup.getChildCount(); | ||
for (int i = 0; i < childCount; i++) { | ||
if (hasRunningChangingLayoutTransition(viewGroup.getChildAt(i))) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
...-elements/java/com/zeoflow/material/elements/viewpager/CompositeOnPageChangeCallback.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright 2021 ZeoFlow SRL | ||
* | ||
* 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.zeoflow.material.elements.viewpager; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Px; | ||
import com.zeoflow.material.elements.viewpager.MaterialViewPager.OnPageChangeCallback; | ||
|
||
import java.util.ArrayList; | ||
import java.util.ConcurrentModificationException; | ||
import java.util.List; | ||
|
||
/** | ||
* Dispatches {@link OnPageChangeCallback} events to subscribers. | ||
*/ | ||
final class CompositeOnPageChangeCallback extends OnPageChangeCallback { | ||
@NonNull | ||
private final List<OnPageChangeCallback> mCallbacks; | ||
|
||
CompositeOnPageChangeCallback(int initialCapacity) { | ||
mCallbacks = new ArrayList<>(initialCapacity); | ||
} | ||
|
||
/** | ||
* Adds the given callback to the list of subscribers | ||
*/ | ||
void addOnPageChangeCallback(OnPageChangeCallback callback) { | ||
mCallbacks.add(callback); | ||
} | ||
|
||
/** | ||
* Removes the given callback from the list of subscribers | ||
*/ | ||
void removeOnPageChangeCallback(OnPageChangeCallback callback) { | ||
mCallbacks.remove(callback); | ||
} | ||
|
||
/** | ||
* @see OnPageChangeCallback#onPageScrolled(int, float, int) | ||
*/ | ||
@Override | ||
public void onPageScrolled(int position, float positionOffset, @Px int positionOffsetPixels) { | ||
try { | ||
for (OnPageChangeCallback callback : mCallbacks) { | ||
callback.onPageScrolled(position, positionOffset, positionOffsetPixels); | ||
} | ||
} catch (ConcurrentModificationException ex) { | ||
throwCallbackListModifiedWhileInUse(ex); | ||
} | ||
} | ||
|
||
/** | ||
* @see OnPageChangeCallback#onPageSelected(int) | ||
*/ | ||
@Override | ||
public void onPageSelected(int position) { | ||
try { | ||
for (OnPageChangeCallback callback : mCallbacks) { | ||
callback.onPageSelected(position); | ||
} | ||
} catch (ConcurrentModificationException ex) { | ||
throwCallbackListModifiedWhileInUse(ex); | ||
} | ||
} | ||
|
||
/** | ||
* @see OnPageChangeCallback#onPageScrollStateChanged(int) | ||
*/ | ||
@Override | ||
public void onPageScrollStateChanged(@MaterialViewPager.ScrollState int state) { | ||
try { | ||
for (OnPageChangeCallback callback : mCallbacks) { | ||
callback.onPageScrollStateChanged(state); | ||
} | ||
} catch (ConcurrentModificationException ex) { | ||
throwCallbackListModifiedWhileInUse(ex); | ||
} | ||
} | ||
|
||
private void throwCallbackListModifiedWhileInUse(ConcurrentModificationException parent) { | ||
throw new IllegalStateException( | ||
"Adding and removing callbacks during dispatch to callbacks is not supported", | ||
parent | ||
); | ||
} | ||
|
||
} |
Oops, something went wrong.