Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config component for layout animations #5045

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3f61542
Add `LayoutConfig`
bartlomiejbloniarz Aug 28, 2023
8b83d6d
Change `LayoutConfig` implementation to use refs
bartlomiejbloniarz Aug 29, 2023
c22ae4e
Reorganize examples
bartlomiejbloniarz Aug 29, 2023
9e3dd8d
Merge branch 'main' into @bartlomiejbloniarz/add-entering-config
bartlomiejbloniarz Aug 29, 2023
d385494
Rename ehh
bartlomiejbloniarz Aug 31, 2023
381c8fe
Minor fixes
bartlomiejbloniarz Aug 31, 2023
fae6c31
Fix `Animated.ts` formatting
bartlomiejbloniarz Aug 31, 2023
6ad11b7
Remove undefined
bartlomiejbloniarz Aug 31, 2023
893d853
Add `LayoutAnimationConfig`
bartlomiejbloniarz Sep 5, 2023
bbca933
Add fabric mock
bartlomiejbloniarz Sep 5, 2023
0ba76ce
Merge branch 'main' into @bartlomiejbloniarz/add-layout-animation-config
bartlomiejbloniarz Sep 8, 2023
906f077
Merge branch 'main' into @bartlomiejbloniarz/add-layout-animation-config
bartlomiejbloniarz Sep 12, 2023
3f7242d
Cleanup
bartlomiejbloniarz Sep 12, 2023
0eed12a
Move `skipEntering`
bartlomiejbloniarz Sep 12, 2023
157f00c
Change `skipExiting` logic
bartlomiejbloniarz Sep 19, 2023
7b0a076
Improve example
bartlomiejbloniarz Sep 20, 2023
2f558d2
Account for nested `skipExiting`
bartlomiejbloniarz Sep 20, 2023
62def34
Minor fixes
bartlomiejbloniarz Sep 20, 2023
da3a690
Minor fix
bartlomiejbloniarz Sep 20, 2023
7ff3f18
Rename `current` to `shouldAnimate`
bartlomiejbloniarz Sep 25, 2023
e51f5f4
Merge branch 'main' into @bartlomiejbloniarz/add-layout-animation-config
bartlomiejbloniarz Sep 25, 2023
077ff8e
Rename 2
bartlomiejbloniarz Sep 25, 2023
af9b2e6
Fix rename :(
bartlomiejbloniarz Sep 26, 2023
ace7af4
Add comment to `LayoutAnimationConfig`
bartlomiejbloniarz Sep 26, 2023
29685a6
Minor fix
bartlomiejbloniarz Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Common/cpp/LayoutAnimations/LayoutAnimationsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ void LayoutAnimationsManager::configureAnimation(
}
}

void LayoutAnimationsManager::setShouldAnimateExiting(int tag, bool value) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
tjzel marked this conversation as resolved.
Show resolved Hide resolved
shouldAnimateExitingForTag_[tag] = value;
}

bool LayoutAnimationsManager::shouldAnimateExiting(
int tag,
bool shouldAnimate) {
auto lock = std::unique_lock<std::mutex>(animationsMutex_);
return collection::contains(shouldAnimateExitingForTag_, tag)
? shouldAnimateExitingForTag_[tag]
: shouldAnimate;
}

bool LayoutAnimationsManager::hasLayoutAnimation(
int tag,
LayoutAnimationType type) {
Expand All @@ -44,6 +58,7 @@ void LayoutAnimationsManager::clearLayoutAnimationConfig(int tag) {
enteringAnimations_.erase(tag);
exitingAnimations_.erase(tag);
layoutAnimations_.erase(tag);
shouldAnimateExitingForTag_.erase(tag);
#ifdef DEBUG
const auto &pair = viewsScreenSharedTagMap_[tag];
screenSharedTagSet_.erase(pair);
Expand Down
5 changes: 4 additions & 1 deletion Common/cpp/LayoutAnimations/LayoutAnimationsManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class LayoutAnimationsManager {
LayoutAnimationType type,
const std::string &sharedTransitionTag,
std::shared_ptr<Shareable> config);
void setShouldAnimateExiting(int tag, bool value);
bool shouldAnimateExiting(int tag, bool shouldAnimate);
bool hasLayoutAnimation(int tag, LayoutAnimationType type);
void startLayoutAnimation(
jsi::Runtime &rt,
Expand Down Expand Up @@ -69,9 +71,10 @@ class LayoutAnimationsManager {
std::unordered_set<int> ignoreProgressAnimationForTag_;
std::unordered_map<std::string, std::vector<int>> sharedTransitionGroups_;
std::unordered_map<int, std::string> viewTagToSharedTag_;
std::unordered_map<int, bool> shouldAnimateExitingForTag_;
mutable std::mutex
animationsMutex_; // Protects `enteringAnimations_`, `exitingAnimations_`,
// `layoutAnimations_` and `viewSharedValues_`.
// `layoutAnimations_`, `viewSharedValues_` and `shouldAnimateExitingForTag_`.
};

} // namespace reanimated
8 changes: 8 additions & 0 deletions Common/cpp/NativeModules/NativeReanimatedModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,14 @@ jsi::Value NativeReanimatedModule::configureLayoutAnimation(
return jsi::Value::undefined();
}

void NativeReanimatedModule::setShouldAnimateExiting(
jsi::Runtime &rt,
const jsi::Value &viewTag,
const jsi::Value &shouldAnimate) {
layoutAnimationsManager_.setShouldAnimateExiting(
viewTag.asNumber(), shouldAnimate.asBool());
}

bool NativeReanimatedModule::isAnyHandlerWaitingForEvent(
const std::string &eventName,
const int emitterReactTag) {
Expand Down
4 changes: 4 additions & 0 deletions Common/cpp/NativeModules/NativeReanimatedModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec {
const jsi::Value &type,
const jsi::Value &sharedTransitionTag,
const jsi::Value &config) override;
void setShouldAnimateExiting(
jsi::Runtime &rt,
const jsi::Value &viewTag,
const jsi::Value &shouldAnimate) override;

void onRender(double timestampMs);

Expand Down
12 changes: 12 additions & 0 deletions Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@ static jsi::Value SPEC_PREFIX(configureLayoutAnimation)(
std::move(args[3]));
}

static jsi::Value SPEC_PREFIX(setShouldAnimateExiting)(
jsi::Runtime &rt,
TurboModule &turboModule,
const jsi::Value *args,
size_t) {
static_cast<NativeReanimatedModuleSpec *>(&turboModule)
->setShouldAnimateExiting(rt, std::move(args[0]), std::move(args[1]));
return jsi::Value::undefined();
}

NativeReanimatedModuleSpec::NativeReanimatedModuleSpec(
std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule("NativeReanimated", jsInvoker) {
Expand Down Expand Up @@ -213,5 +223,7 @@ NativeReanimatedModuleSpec::NativeReanimatedModuleSpec(

methodMap_["configureLayoutAnimation"] =
MethodMetadata{4, SPEC_PREFIX(configureLayoutAnimation)};
methodMap_["setShouldAnimateExitingForTag"] =
MethodMetadata{2, SPEC_PREFIX(setShouldAnimateExiting)};
}
} // namespace reanimated
5 changes: 5 additions & 0 deletions Common/cpp/NativeModules/NativeReanimatedModuleSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ class JSI_EXPORT NativeReanimatedModuleSpec : public TurboModule {
const jsi::Value &type,
const jsi::Value &sharedTransitionTag,
const jsi::Value &config) = 0;

virtual void setShouldAnimateExiting(
jsi::Runtime &rt,
const jsi::Value &viewTag,
const jsi::Value &shouldAnimate) = 0;
};

} // namespace reanimated
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ public int findPrecedingViewTagForTransition(int tag) {
return -1;
}

@Override
public boolean shouldAnimateExiting(int tag, boolean shouldAnimate) {
return false;
}

@Override
public boolean hasAnimation(int tag, int type) {
return false;
Expand Down
11 changes: 11 additions & 0 deletions android/src/main/cpp/LayoutAnimations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ void LayoutAnimations::setHasAnimationBlock(
this->hasAnimationBlock_ = hasAnimationBlock;
}

void LayoutAnimations::setShouldAnimateExitingBlock(
ShouldAnimateExitingBlock shouldAnimateExitingBlock) {
this->shouldAnimateExitingBlock_ = shouldAnimateExitingBlock;
}

#ifdef DEBUG
void LayoutAnimations::setCheckDuplicateSharedTag(
CheckDuplicateSharedTag checkDuplicateSharedTag) {
Expand All @@ -62,6 +67,10 @@ bool LayoutAnimations::hasAnimationForTag(int tag, int type) {
return hasAnimationBlock_(tag, type);
}

bool LayoutAnimations::shouldAnimateExiting(int tag, bool shouldAnimate) {
return shouldAnimateExitingBlock_(tag, shouldAnimate);
}

void LayoutAnimations::setClearAnimationConfigBlock(
ClearAnimationConfigBlock clearAnimationConfigBlock) {
this->clearAnimationConfigBlock_ = clearAnimationConfigBlock;
Expand Down Expand Up @@ -102,6 +111,8 @@ void LayoutAnimations::registerNatives() {
"startAnimationForTag", LayoutAnimations::startAnimationForTag),
makeNativeMethod(
"hasAnimationForTag", LayoutAnimations::hasAnimationForTag),
makeNativeMethod(
"shouldAnimateExiting", LayoutAnimations::shouldAnimateExiting),
makeNativeMethod(
"clearAnimationConfigForTag",
LayoutAnimations::clearAnimationConfigForTag),
Expand Down
5 changes: 5 additions & 0 deletions android/src/main/cpp/LayoutAnimations.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class LayoutAnimations : public jni::HybridClass<LayoutAnimations> {
using AnimationStartingBlock =
std::function<void(int, int, alias_ref<JMap<jstring, jstring>>)>;
using HasAnimationBlock = std::function<bool(int, int)>;
using ShouldAnimateExitingBlock = std::function<bool(int, bool)>;
#ifdef DEBUG
using CheckDuplicateSharedTag = std::function<void(int, int)>;
#endif
Expand All @@ -34,10 +35,13 @@ class LayoutAnimations : public jni::HybridClass<LayoutAnimations> {
int type,
alias_ref<JMap<jstring, jstring>> values);
bool hasAnimationForTag(int tag, int type);
bool shouldAnimateExiting(int tag, bool shouldAnimate);
bool isLayoutAnimationEnabled();

void setAnimationStartingBlock(AnimationStartingBlock animationStartingBlock);
void setHasAnimationBlock(HasAnimationBlock hasAnimationBlock);
void setShouldAnimateExitingBlock(
ShouldAnimateExitingBlock shouldAnimateExitingBlock);
#ifdef DEBUG
void setCheckDuplicateSharedTag(
CheckDuplicateSharedTag checkDuplicateSharedTag);
Expand All @@ -64,6 +68,7 @@ class LayoutAnimations : public jni::HybridClass<LayoutAnimations> {
jni::global_ref<LayoutAnimations::javaobject> javaPart_;
AnimationStartingBlock animationStartingBlock_;
HasAnimationBlock hasAnimationBlock_;
ShouldAnimateExitingBlock shouldAnimateExitingBlock_;
ClearAnimationConfigBlock clearAnimationConfigBlock_;
CancelAnimationBlock cancelAnimationBlock_;
FindPrecedingViewTagForTransitionBlock
Expand Down
9 changes: 9 additions & 0 deletions android/src/main/cpp/NativeProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,15 @@ void NativeProxy::setupLayoutAnimations() {
return false;
});

layoutAnimations_->cthis()->setShouldAnimateExitingBlock(
[weakNativeReanimatedModule](int tag, bool shouldAnimate) {
if (auto nativeReanimatedModule = weakNativeReanimatedModule.lock()) {
return nativeReanimatedModule->layoutAnimationsManager()
.shouldAnimateExiting(tag, shouldAnimate);
}
return false;
});

#ifdef DEBUG
layoutAnimations_->cthis()->setCheckDuplicateSharedTag(
[weakNativeReanimatedModule](int viewTag, int screenTag) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public void onViewRemoval(View view, ViewGroup parent, Runnable callback) {
Integer tag = view.getId();
mCallbacks.put(tag, callback);

if (!removeOrAnimateExitRecursive(view, true)) {
if (!removeOrAnimateExitRecursive(view, true, true)) {
removeView(view, parent);
}
}
Expand Down Expand Up @@ -489,6 +489,10 @@ public void updateLayout(
}
}

public boolean shouldAnimateExiting(int tag, boolean shouldAnimate) {
return mNativeMethodsHolder.shouldAnimateExiting(tag, shouldAnimate);
}

public boolean hasAnimationForTag(int tag, int type) {
return mNativeMethodsHolder.hasAnimation(tag, type);
}
Expand All @@ -497,7 +501,8 @@ public boolean isLayoutAnimationEnabled() {
return mNativeMethodsHolder != null && mNativeMethodsHolder.isLayoutAnimationEnabled();
}

private boolean removeOrAnimateExitRecursive(View view, boolean shouldRemove) {
private boolean removeOrAnimateExitRecursive(
tjzel marked this conversation as resolved.
Show resolved Hide resolved
View view, boolean shouldRemove, boolean shouldAnimate) {
int tag = view.getId();
ViewManager viewManager = resolveViewManager(tag);

Expand All @@ -512,8 +517,12 @@ private boolean removeOrAnimateExitRecursive(View view, boolean shouldRemove) {
}
}

shouldAnimate = shouldAnimateExiting(tag, shouldAnimate);

boolean hasExitAnimation =
hasAnimationForTag(tag, LayoutAnimations.Types.EXITING) || mExitingViews.containsKey(tag);
shouldAnimate
&& (hasAnimationForTag(tag, LayoutAnimations.Types.EXITING)
|| mExitingViews.containsKey(tag));
boolean hasAnimatedChildren = false;
shouldRemove = shouldRemove && !hasExitAnimation;

Expand All @@ -531,7 +540,7 @@ private boolean removeOrAnimateExitRecursive(View view, boolean shouldRemove) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = viewGroup.getChildCount() - 1; i >= 0; i--) {
View child = viewGroup.getChildAt(i);
if (removeOrAnimateExitRecursive(child, shouldRemove)) {
if (removeOrAnimateExitRecursive(child, shouldRemove, shouldAnimate)) {
hasAnimatedChildren = true;
} else if (shouldRemove && child.getId() != -1) {
toBeRemoved.add(child);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public LayoutAnimations(ReactApplicationContext context) {

public native boolean hasAnimationForTag(int tag, int type);

public native boolean shouldAnimateExiting(int tag, boolean shouldAnimate);

public native void checkDuplicateSharedTag(int viewTag, int screenTag);

public native void clearAnimationConfigForTag(int tag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
public interface NativeMethodsHolder {
void startAnimation(int tag, int type, HashMap<String, Object> values);

boolean shouldAnimateExiting(int tag, boolean shouldAnimate);

boolean hasAnimation(int tag, int type);

void clearAnimationConfig(int tag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ public void startAnimation(int tag, int type, HashMap<String, Object> values) {
}
}

@Override
public boolean shouldAnimateExiting(int tag, boolean shouldAnimate) {
LayoutAnimations layoutAnimations = weakLayoutAnimations.get();
if (layoutAnimations != null) {
return layoutAnimations.shouldAnimateExiting(tag, shouldAnimate);
}
return false;
}

@Override
public boolean isLayoutAnimationEnabled() {
LayoutAnimations layoutAnimations = weakLayoutAnimations.get();
Expand Down
Loading