From 0316f29719f0528027bd3ed62ecc1d5bd15ae288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=AF=E6=AD=8C?= Date: Wed, 29 Sep 2021 11:19:04 +0800 Subject: [PATCH] add layoutanimationcontroller's loading support,add getInt for enumeration type --- .../gridlayoutanimationcontroller.cc | 4 ++ .../animation/layoutanimationcontroller.cc | 23 ++++-- src/gui/animation/layoutanimationcontroller.h | 1 + src/gui/animation/layouttransition.cc | 17 ++++- src/gui/animation/layouttransition.h | 12 ++-- src/gui/animations.h | 4 ++ src/gui/core/attributeset.cc | 70 +++++++++++-------- src/gui/core/attributeset.h | 2 +- src/gui/widget/layoutparams.cc | 8 +-- src/gui/widget/linearlayout.cc | 7 +- src/gui/widget/view.h | 26 +++---- src/gui/widget/viewgroup.cc | 23 ++++++ src/gui/widget/viewgroup.h | 6 +- 13 files changed, 143 insertions(+), 60 deletions(-) diff --git a/src/gui/animation/gridlayoutanimationcontroller.cc b/src/gui/animation/gridlayoutanimationcontroller.cc index 0f29dd49..a7e7262f 100755 --- a/src/gui/animation/gridlayoutanimationcontroller.cc +++ b/src/gui/animation/gridlayoutanimationcontroller.cc @@ -6,6 +6,10 @@ namespace cdroid{ GridLayoutAnimationController::GridLayoutAnimationController(Context* context,const AttributeSet& attrs) :LayoutAnimationController(context,attrs){ + mColumnDelay = attrs.getFloat("columnDelay"); + mRowDelay = attrs.getFloat("rowDelay"); + mDirection = attrs.getInt("direction"); + mDirectionPriority = attrs.getInt("directionPriority"); } GridLayoutAnimationController::GridLayoutAnimationController(Animation* animation) diff --git a/src/gui/animation/layoutanimationcontroller.cc b/src/gui/animation/layoutanimationcontroller.cc index 363efce8..aa16eb78 100755 --- a/src/gui/animation/layoutanimationcontroller.cc +++ b/src/gui/animation/layoutanimationcontroller.cc @@ -1,10 +1,17 @@ #include #include +#include #include + namespace cdroid{ LayoutAnimationController::LayoutAnimationController(Context* context, const AttributeSet& attrs){ - + mDelay = attrs.getFloat("delay"); + mOrder = attrs.getInt("animationOrder",ORDER_NORMAL); + std::string resource = attrs.getString("animation"); + mAnimation = AnimationUtils::loadAnimation(context,resource); + resource = attrs.getString("interpolator"); + mInterpolator = AnimationUtils::loadInterpolator(context,resource); } LayoutAnimationController::LayoutAnimationController(Animation* animation,float delay){ @@ -17,6 +24,11 @@ LayoutAnimationController::LayoutAnimationController(Animation* animation) :LayoutAnimationController(animation,.5f){ } +LayoutAnimationController::~LayoutAnimationController(){ + delete mAnimation; + delete mInterpolator; +} + int LayoutAnimationController::getOrder()const{ return mOrder; } @@ -26,10 +38,11 @@ void LayoutAnimationController::setOrder(int order){ } void LayoutAnimationController::setAnimation(Context* context,const std::string&resourceID){ - + setAnimation(AnimationUtils::loadAnimation(context,resourceID)); } void LayoutAnimationController::setAnimation(Animation* animation){ + if(mAnimation)delete mAnimation; mAnimation = animation; mAnimation->setFillBefore(true); } @@ -39,9 +52,11 @@ Animation* LayoutAnimationController::getAnimation(){ } void LayoutAnimationController::setInterpolator(Context* context,const std::string&resourceID){ + setInterpolator(AnimationUtils::loadInterpolator(context,resourceID)); } void LayoutAnimationController::setInterpolator(Interpolator* interpolator){ + if(mInterpolator)delete mInterpolator; mInterpolator = interpolator; } @@ -87,7 +102,7 @@ long LayoutAnimationController::getDelayForView(View* view){ if (params == nullptr) return 0; - float delay = mDelay * mAnimation->getDuration(); + float delay = mDelay * (float)mAnimation->getDuration(); long viewDelay = (long) (getTransformedIndex(params) * delay); float totalDelay = delay * params->count; @@ -97,7 +112,7 @@ long LayoutAnimationController::getDelayForView(View* view){ float normalizedDelay = viewDelay / totalDelay; normalizedDelay = mInterpolator->getInterpolation(normalizedDelay); - + LOGV("%p:%d totalDelay=%.2f %d/%d mDelay=%.2f dur=%d",view,view->getId(),totalDelay,params->index,params->count,mDelay,mAnimation->getDuration()); return (long) (normalizedDelay * totalDelay); } diff --git a/src/gui/animation/layoutanimationcontroller.h b/src/gui/animation/layoutanimationcontroller.h index 8afd4e3b..5d94d337 100755 --- a/src/gui/animation/layoutanimationcontroller.h +++ b/src/gui/animation/layoutanimationcontroller.h @@ -32,6 +32,7 @@ public: LayoutAnimationController(Context* context, const AttributeSet& attrs); LayoutAnimationController(Animation* animation,float delay); LayoutAnimationController(Animation* animation); + virtual ~LayoutAnimationController(); int getOrder()const; void setOrder(int); void setAnimation(Context* context,const std::string&resourceID); diff --git a/src/gui/animation/layouttransition.cc b/src/gui/animation/layouttransition.cc index a8d97541..65d80710 100755 --- a/src/gui/animation/layouttransition.cc +++ b/src/gui/animation/layouttransition.cc @@ -363,7 +363,7 @@ bool LayoutTransition::isChangingLayout() { } void LayoutTransition::layoutChange(ViewGroup *parent){ - //if (parent.getWindowVisibility() != View::VISIBLE) return; + if (parent->getWindowVisibility() != View::VISIBLE) return; if ((mTransitionTypes & FLAG_CHANGING) == FLAG_CHANGING && !isRunning()) { // This method is called for all calls to layout() in the container, including @@ -510,7 +510,7 @@ void LayoutTransition::addChild(ViewGroup* parent, View* child, bool changesLayo } void LayoutTransition::removeChild(ViewGroup* parent, View* child, bool changesLayout){ - //if (parent->getWindowVisibility() != View::VISIBLE) return; + if (parent->getWindowVisibility() != View::VISIBLE) return; if ((mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) { // Want appearing animations to finish up before proceeding @@ -554,4 +554,17 @@ void LayoutTransition::showChild(ViewGroup* parent, View* child, int oldVisibili addChild(parent, child, oldVisibility == View::GONE); } +void LayoutTransition::addTransitionListener(TransitionListener& listener){ + mListeners.push_back(listener); } + +void LayoutTransition::removeTransitionListener(TransitionListener& listener){ + for(auto it=mListeners.begin();it!=mListeners.end();it++){ + if(it->startTransition==listener.startTransition && it->endTransition==listener.endTransition){ + mListeners.erase(it); + break; + } + } +} + +}//endof namespace diff --git a/src/gui/animation/layouttransition.h b/src/gui/animation/layouttransition.h index fd76787e..2b3f0f58 100755 --- a/src/gui/animation/layouttransition.h +++ b/src/gui/animation/layouttransition.h @@ -2,16 +2,16 @@ #define __LAYOUT_TRANSITION_H__ #include #include -#include +#include #include namespace cdroid{ - +class ViewGroup; class LayoutTransition{ public: struct TransitionListener{ - std::functionstartTransition; - std::functionendTransition; + CallbackBase startTransition; + CallbackBase endTransition; }; private: static constexpr int FLAG_APPEARING = 0x01; @@ -36,7 +36,7 @@ private: long mChangingDisappearingStagger = 0; long mChangingStagger = 0; long staggerDelay; - int mTransitionTypes = FLAG_CHANGE_APPEARING | FLAG_CHANGE_DISAPPEARING | FLAG_APPEARING | FLAG_DISAPPEARING; + int mTransitionTypes = FLAG_CHANGE_APPEARING | FLAG_CHANGE_DISAPPEARING | FLAG_APPEARING | FLAG_DISAPPEARING; bool mAnimateParentHierarchy = true; std::vectormListeners; @@ -134,6 +134,8 @@ public: void hideChild(ViewGroup* parent, View* child); void hideChild(ViewGroup* parent, View* child, int newVisibility); void showChild(ViewGroup* parent, View* child, int oldVisibility); + void addTransitionListener(TransitionListener& listener); + void removeTransitionListener(TransitionListener& listener); }; } diff --git a/src/gui/animations.h b/src/gui/animations.h index 3163da71..718fea36 100755 --- a/src/gui/animations.h +++ b/src/gui/animations.h @@ -9,4 +9,8 @@ #include #include +#include #include +#include +#include + diff --git a/src/gui/core/attributeset.cc b/src/gui/core/attributeset.cc index e6fe719b..e94097ab 100755 --- a/src/gui/core/attributeset.cc +++ b/src/gui/core/attributeset.cc @@ -8,28 +8,6 @@ namespace cdroid{ -std::mapAttributeSet::mIntAttrs={ - {"top",Gravity::TOP} , - {"bottom",Gravity::BOTTOM}, - {"left",Gravity::LEFT} , - {"right",Gravity::RIGHT}, - {"center_vertical",Gravity::CENTER_VERTICAL} , - {"fill_vertical",Gravity::FILL_VERTICAL}, - {"center_horizontal",Gravity::CENTER_HORIZONTAL} , - {"fill_horizontal",Gravity::FILL_HORIZONTAL} , - {"center",Gravity::CENTER} , - {"fill",Gravity::FILL}, - {"clip_vertical",Gravity::CLIP_VERTICAL}, - {"clip_horizontal",Gravity::CLIP_HORIZONTAL}, - - {"horizontal",LinearLayout::HORIZONTAL}, - {"vertical",LinearLayout::VERTICAL},//for Layout Orientation - - {"fill_parent",LayoutParams::MATCH_PARENT}, - {"match_parent",LayoutParams::MATCH_PARENT}, - {"wrap_content",LayoutParams::WRAP_CONTENT} -}; - static std::vector split(const std::string & path) { std::vector vec; size_t begin, end; @@ -95,12 +73,30 @@ bool AttributeSet::getBoolean(const std::string&key,bool def)const{ int AttributeSet::getInt(const std::string&key,int def)const{ const std::string v=getAttributeValue(key); - if(v.empty())return def; - if(v[0]>='a'&&v[0]<='z'){ - auto it=mIntAttrs.find(v); - return it==mIntAttrs.end()?def:it->second; + if(v.empty()||((v[0]>='a')&&(v[0]<='z'))){ + return def; + } + return std::strtol(v.c_str(),nullptr,10); +} + +int AttributeSet::getInt(const std::string&key,const std::map&kvs,int def)const{ + const std::string vstr=getAttributeValue(key); + if(vstr.size()&&vstr.find('|')!=std::string::npos){ + std::vectorgs=split(vstr); + int result=0; + int count=0; + for(std::string s:gs){ + auto it=kvs.find(s); + if(it!=kvs.end()){ + result|=it->second; + count++; + } + } + return count?result:def; + }else{ + auto it=kvs.find(vstr); + return it==kvs.end()?def:it->second; } - return std::strtol(v.c_str(),nullptr,10); } int AttributeSet::getResourceId(const std::string&key,int def)const{ @@ -133,13 +129,29 @@ const std::string AttributeSet::getString(const std::string&key,const std::strin return v; } +static std::mapgravitykvs={ + {"top" , Gravity::TOP} , + {"bottom", Gravity::BOTTOM}, + {"left" , Gravity::LEFT} , + {"right" , Gravity::RIGHT} , + {"center_vertical" , Gravity::CENTER_VERTICAL}, + {"fill_vertical" , Gravity::FILL_VERTICAL} , + {"center_horizontal", Gravity::CENTER_HORIZONTAL}, + {"fill_horizontal" , Gravity::FILL_HORIZONTAL} , + {"center", Gravity::CENTER}, + {"fill" , Gravity::FILL} , + {"clip_vertical" , Gravity::CLIP_VERTICAL}, + {"clip_horizontal", Gravity::CLIP_HORIZONTAL}, +}; + int AttributeSet::getGravity(const std::string&key,int defvalue)const{ + //return getInt(key,gravitykvs,defvalue); int gravity=0; const std::string prop=getString(key); std::vectorgs=split(prop); for(auto s:gs){ - auto it=mIntAttrs.find(s); - if(it!=mIntAttrs.end()){ + auto it=gravitykvs.find(s); + if(it!=gravitykvs.end()){ gravity|=it->second; } } diff --git a/src/gui/core/attributeset.h b/src/gui/core/attributeset.h index 147ca886..7085b29b 100755 --- a/src/gui/core/attributeset.h +++ b/src/gui/core/attributeset.h @@ -7,7 +7,6 @@ class AttributeSet{ private: std::string basePath;//only for path file std::mapmAttrs; - static std::mapmIntAttrs; public: AttributeSet(); AttributeSet(const char*atts[],int size=0); @@ -20,6 +19,7 @@ public: const std::string getAttributeValue(const std::string&key)const; bool getBoolean(const std::string&key,bool def=false)const; int getInt(const std::string&key,int def=0)const; + int getInt(const std::string&key,const std::map&keyvaluemaps,int def=0)const; int getResourceId(const std::string&key,int def=0)const; int getColor(const std::string&key,int def=0xFFFFFFFF)const; float getFloat(const std::string&key,float def=.0)const; diff --git a/src/gui/widget/layoutparams.cc b/src/gui/widget/layoutparams.cc index 30a452e7..93a31e58 100755 --- a/src/gui/widget/layoutparams.cc +++ b/src/gui/widget/layoutparams.cc @@ -168,8 +168,8 @@ int MarginLayoutParams::getMarginStart(){ doResolveMargins(); } switch(mMarginFlags & LAYOUT_DIRECTION_MASK) { - case View::LAYOUT_DIRECTION_RTL:return rightMargin; - case View::LAYOUT_DIRECTION_LTR: + case View::LAYOUT_DIRECTION_RTL:return rightMargin; + case View::LAYOUT_DIRECTION_LTR: default:return leftMargin; } } @@ -276,13 +276,13 @@ void MarginLayoutParams::doResolveMargins(){ // them and override what has been defined for left and right margins. If either start // or end margin is not defined, just set it to default "0". switch(mMarginFlags & LAYOUT_DIRECTION_MASK) { - case View::LAYOUT_DIRECTION_RTL: + case View::LAYOUT_DIRECTION_RTL: leftMargin = (endMargin > DEFAULT_MARGIN_RELATIVE) ? endMargin : DEFAULT_MARGIN_RESOLVED; rightMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ? startMargin : DEFAULT_MARGIN_RESOLVED; break; - case View::LAYOUT_DIRECTION_LTR: + case View::LAYOUT_DIRECTION_LTR: default: leftMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ? startMargin : DEFAULT_MARGIN_RESOLVED; diff --git a/src/gui/widget/linearlayout.cc b/src/gui/widget/linearlayout.cc index 6970585d..252c6d98 100755 --- a/src/gui/widget/linearlayout.cc +++ b/src/gui/widget/linearlayout.cc @@ -66,12 +66,17 @@ void LinearLayout::initView(){ mAllowInconsistentMeasurement=false; } +static std::maporientationkvs={ + {"horizontal",LinearLayout::HORIZONTAL}, + {"vertical",LinearLayout::VERTICAL}// +}; + LinearLayout::LinearLayout(Context* context,const AttributeSet& attrs) :ViewGroup(context,attrs){ initView(); mUseLargestChild=attrs.getBoolean("measureWithLargestChild",false); - mOrientation=attrs.getInt("orientation",HORIZONTAL); + mOrientation=attrs.getInt("orientation",orientationkvs,HORIZONTAL); mGravity=attrs.getGravity("gravity",Gravity::NO_GRAVITY); } diff --git a/src/gui/widget/view.h b/src/gui/widget/view.h index bc5b6264..ad3f1be7 100755 --- a/src/gui/widget/view.h +++ b/src/gui/widget/view.h @@ -428,7 +428,6 @@ protected: void destroyDrawingCache(); RefPtrgetDrawingCache(bool autoScale); bool hasWindowFocus()const; - int getWindowVisibility()const; virtual bool setFrame(int x,int y,int w,int h); virtual void resetResolvedDrawables(); @@ -737,6 +736,7 @@ public: // Enable & Visible virtual View& setVisibility(int visable); virtual int getVisibility() const; + int getWindowVisibility()const; bool isShown()const; virtual View& setEnabled(bool enable); virtual bool isEnabled() const; @@ -760,7 +760,7 @@ public: virtual bool isInTouchMode()const; bool isFocusable()const; void setFocusable(bool); - int getFocusable()const; + int getFocusable()const; virtual void unFocus(View*); bool hasFocus()const; virtual bool restoreFocusInCluster(int direction); @@ -806,7 +806,7 @@ public: bool onKeyDown(int keycode,KeyEvent& evt)override; bool onKeyLongPress(int keyCode, KeyEvent& event)override; bool onKeyMultiple(int keyCode, int count, KeyEvent& event)override; - virtual int commitText(const std::wstring&); + virtual int commitText(const std::wstring&); virtual void onWindowVisibilityChanged(int); virtual void onVisibilityAggregated(bool isVisible); virtual bool onInterceptTouchEvent(MotionEvent& evt); @@ -854,24 +854,24 @@ public: void setTranslationZ(float z); float getScaleX()const; - void setScaleX(float); + void setScaleX(float); float getScaleY()const; - void setScaleY(float); + void setScaleY(float); float getPivotX()const; - void setPivotX(float); + void setPivotX(float); float getPivotY()const; - void setPivotY(float); - bool isPivotSet()const; - void resetPivot(); + void setPivotY(float); + bool isPivotSet()const; + void resetPivot(); float getAlpha()const; - void setAlpha(float); + void setAlpha(float); float getRotation()const; - void setRotation(float rotation); + void setRotation(float rotation); float getRotationX()const; - void setRotationX(float); + void setRotationX(float); float getRotationY()const; - void setRotationY(float); + void setRotationY(float); LayoutParams*getLayoutParams(); int getRawLayoutDirection()const; diff --git a/src/gui/widget/viewgroup.cc b/src/gui/widget/viewgroup.cc index 6bc8dc90..01b5ec33 100755 --- a/src/gui/widget/viewgroup.cc +++ b/src/gui/widget/viewgroup.cc @@ -107,6 +107,18 @@ void ViewGroup::initGroup(){ mInvalidationTransformation =nullptr; mTransition = nullptr; setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS); + mLayoutTransitionListener.startTransition=[this](LayoutTransition&transition,ViewGroup*container,View*view,int transitionType){ + if(transitionType==LayoutTransition::DISAPPEARING) + startViewTransition(view); + }; + mLayoutTransitionListener.endTransition=[this](LayoutTransition&transition,ViewGroup*container,View*view,int transitionType){ + if(mLayoutCalledWhileSuppressed && !transition.isChangingLayout()){ + requestLayout(); + mLayoutCalledWhileSuppressed=false; + } + if(transitionType==LayoutTransition::DISAPPEARING && mTransitioningViews.size()) + endViewTransition(view); + }; } ViewGroup::~ViewGroup() { @@ -1880,6 +1892,17 @@ Animation::AnimationListener ViewGroup::getLayoutAnimationListener(){ return mAnimationListener; } +void ViewGroup::setLayoutTransition(LayoutTransition* transition) { + if (mTransition != nullptr) { + mTransition->cancel(); + mTransition->removeTransitionListener(mLayoutTransitionListener); + } + mTransition = transition; + if (mTransition != nullptr) { + mTransition->addTransitionListener(mLayoutTransitionListener); + } +} + void ViewGroup::bindLayoutAnimation(View* child){ Animation* a = mLayoutAnimationController->getAnimationForView(child); child->setAnimation(a); diff --git a/src/gui/widget/viewgroup.h b/src/gui/widget/viewgroup.h index e9e69c04..4479f836 100755 --- a/src/gui/widget/viewgroup.h +++ b/src/gui/widget/viewgroup.h @@ -19,7 +19,7 @@ #include #include - +#include namespace cdroid { #define ATTR_ANIMATE_FOCUS (0x2000) /*flag to open animate focus*/ @@ -85,7 +85,9 @@ private: std::vectormTransientViews; std::vectormTransientIndices; int mChildCountWithTransientState; + bool mLayoutCalledWhileSuppressed; Animation::AnimationListener mAnimationListener; + LayoutTransition::TransitionListener mLayoutTransitionListener; class LayoutAnimationController* mLayoutAnimationController; class TouchTarget* mFirstTouchTarget; POINT animateTo;//save window boundray while animating @@ -264,6 +266,8 @@ public: LayoutAnimationController* getLayoutAnimation(); void setLayoutAnimationListener(Animation::AnimationListener animationListener); Animation::AnimationListener getLayoutAnimationListener(); + void setLayoutTransition(LayoutTransition*); + LayoutTransition*getLayoutTransition()const; void clearDisappearingChildren(); void startViewTransition(View* view); void endViewTransition(View* view);