add layoutanimationcontroller's loading support,add getInt for enumeration type

This commit is contained in:
侯歌 2021-09-29 11:19:04 +08:00
parent 9ddb180fd9
commit 0316f29719
13 changed files with 143 additions and 60 deletions

View File

@ -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)

View File

@ -1,10 +1,17 @@
#include <stdlib.h>
#include <widget/viewgroup.h>
#include <animation/animationutils.h>
#include <animation/layoutanimationcontroller.h>
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);
}

View File

@ -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);

View File

@ -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

View File

@ -2,16 +2,16 @@
#define __LAYOUT_TRANSITION_H__
#include <map>
#include <functional>
#include <widget/viewgroup.h>
#include <widget/view.h>
#include <animation/animator.h>
namespace cdroid{
class ViewGroup;
class LayoutTransition{
public:
struct TransitionListener{
std::function<void(LayoutTransition& transition, ViewGroup* container,View* view, int transitionType)>startTransition;
std::function<void(LayoutTransition& transition, ViewGroup* container,View* view, int transitionType)>endTransition;
CallbackBase<void,LayoutTransition&, ViewGroup*/*container*/,View* /*view*/, int/*transitionType*/> startTransition;
CallbackBase<void,LayoutTransition&, ViewGroup*/*container*/,View* /*view*/, int/*transitionType*/> 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::vector<TransitionListener>mListeners;
@ -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);
};
}

View File

@ -9,4 +9,8 @@
#include <animation/animator.h>
#include <animation/objectanimator.h>
#include <animation/animationutils.h>
#include <animation/layouttransition.h>
#include <animation/layoutanimationcontroller.h>
#include <animation/gridlayoutanimationcontroller.h>

View File

@ -8,28 +8,6 @@
namespace cdroid{
std::map<const std::string,int>AttributeSet::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<std::string> split(const std::string & path) {
std::vector<std::string> 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<const std::string,int>&kvs,int def)const{
const std::string vstr=getAttributeValue(key);
if(vstr.size()&&vstr.find('|')!=std::string::npos){
std::vector<std::string>gs=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::map<const std::string,int>gravitykvs={
{"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::vector<std::string>gs=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;
}
}

View File

@ -7,7 +7,6 @@ class AttributeSet{
private:
std::string basePath;//only for path file
std::map<const std::string,const std::string>mAttrs;
static std::map<const std::string,int>mIntAttrs;
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<const std::string,int>&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;

View File

@ -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;

View File

@ -66,12 +66,17 @@ void LinearLayout::initView(){
mAllowInconsistentMeasurement=false;
}
static std::map<const std::string,int>orientationkvs={
{"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);
}

View File

@ -428,7 +428,6 @@ protected:
void destroyDrawingCache();
RefPtr<ImageSurface>getDrawingCache(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;

View File

@ -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);

View File

@ -19,7 +19,7 @@
#include <widget/view.h>
#include <core/scroller.h>
#include <animations.h>
namespace cdroid {
#define ATTR_ANIMATE_FOCUS (0x2000) /*flag to open animate focus*/
@ -85,7 +85,9 @@ private:
std::vector<View*>mTransientViews;
std::vector<int>mTransientIndices;
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);