mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-12-04 05:10:06 +08:00
itemanimator can working with some bugs
This commit is contained in:
parent
3318715899
commit
ff09f2829b
@ -25,8 +25,8 @@ public:
|
||||
TextView* view = new TextView("",200,64);
|
||||
view->setBackgroundColor(0xff234567);
|
||||
view->setGravity(Gravity::CENTER);
|
||||
//view->setLayoutParams(new LayoutParams(LayoutParams::MATCH_PARENT,80));//LayoutParams::WRAP_CONTENT));
|
||||
view->setLayoutParams(new LayoutParams(120,LayoutParams::MATCH_PARENT));//LayoutParams::WRAP_CONTENT));
|
||||
view->setLayoutParams(new LayoutParams(LayoutParams::MATCH_PARENT,80));//LayoutParams::WRAP_CONTENT));
|
||||
//view->setLayoutParams(new LayoutParams(120,LayoutParams::MATCH_PARENT));//LayoutParams::WRAP_CONTENT));
|
||||
//view->setLayoutParams(new LayoutParams(640,LayoutParams::MATCH_PARENT));
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
@ -44,6 +44,9 @@ public:
|
||||
LOGD("click item positon=%d holder lp",position,lp);
|
||||
});
|
||||
}
|
||||
void remove(int idx){
|
||||
items.erase(items.begin()+idx);
|
||||
}
|
||||
void add(const std::string&str){
|
||||
items.push_back(str);
|
||||
}
|
||||
@ -65,32 +68,6 @@ int main(int argc,const char*argv[]){
|
||||
RecyclerView*rv=new RecyclerView(800,480);
|
||||
auto ps = new LinearSnapHelper();//PagerSnapHelper();
|
||||
ps->attachToRecyclerView(rv);
|
||||
CarouselLayoutManager*carousel=new CarouselLayoutManager(CarouselLayoutManager::HORIZONTAL);//VERTICAL);//HORIZONTAL);
|
||||
//rv->setLayoutManager(carousel);
|
||||
((LinearLayoutManager*)rv->getLayoutManager())->setOrientation(LinearLayoutManager::HORIZONTAL);
|
||||
carousel->setPostLayoutListener([carousel](View& child,CarouselLayoutManager::ItemTransformation&ti,float itemPositionToCenterDiff,int orientation,int itemPositionInAdapter)->bool{
|
||||
const float mScaleMultiplier =0.1f;
|
||||
const float scale = 1.f - mScaleMultiplier*std::abs(itemPositionToCenterDiff);
|
||||
|
||||
// because scaling will make view smaller in its center, then we should move this item to the top or bottom to make it visible
|
||||
float translateY,translateX,translateGeneral;
|
||||
float sig = itemPositionToCenterDiff>0.f?1.f:-1.f;
|
||||
if (CarouselLayoutManager::VERTICAL == orientation) {
|
||||
translateGeneral = child.getMeasuredHeight() * (1.f - scale) / 2.f;
|
||||
translateY = sig * translateGeneral;
|
||||
translateX = 0;
|
||||
} else {
|
||||
translateGeneral = child.getMeasuredHeight()*itemPositionToCenterDiff* (1.f-scale);
|
||||
translateX = translateGeneral;
|
||||
translateY = 0;//(child.getMeasuredHeight()*(1.f-scale))/2.f;
|
||||
}
|
||||
ti.mScaleX = ti.mScaleY = scale;
|
||||
ti.mTranslationX = translateX;
|
||||
ti.mTranslationY = translateY;
|
||||
//LOGD("orientation=%d centeritem=%d itemdiff=%.f translateGeneral=%.f scale=%f X=%d transX/Y=%.f,%.f",
|
||||
// orientation,carousel->getCenterItemPosition(),itemPositionToCenterDiff,translateGeneral,scale,child.getLeft(),translateX,translateY);
|
||||
return true;
|
||||
});
|
||||
MyAdapter*adapter=new MyAdapter();
|
||||
rv->setHasFixedSize(true);
|
||||
rv->getRecycledViewPool().setMaxRecycledViews(0,64);
|
||||
@ -98,20 +75,20 @@ int main(int argc,const char*argv[]){
|
||||
rv->setOverScrollMode(View::OVER_SCROLL_ALWAYS);
|
||||
rv->setAdapter(adapter);
|
||||
DividerItemDecoration* decoration = new DividerItemDecoration(&app, LinearLayout::VERTICAL);
|
||||
|
||||
auto anim=rv->getItemAnimator();
|
||||
anim->setRemoveDuration(200);
|
||||
anim->setAddDuration(200);
|
||||
anim->setMoveDuration(200);
|
||||
anim->setChangeDuration(200);
|
||||
rv->getLayoutManager()->requestSimpleAnimationsInNextLayout();
|
||||
for(int i=0;i<100;i++){
|
||||
adapter->add(std::string("string ")+std::to_string(i));
|
||||
//adapter->notifyItemInserted(i);//Notice:call notifyItemInserted before layout will cause memleak.
|
||||
}
|
||||
|
||||
decoration->setDrawable(new ColorDrawable(0xFFFF0000));
|
||||
rv->addItemDecoration(decoration);
|
||||
w->addView(rv);
|
||||
w->requestLayout();
|
||||
Runnable r;
|
||||
r=[&](){
|
||||
adapter->remove(4);
|
||||
adapter->notifyItemRemoved(4);
|
||||
};
|
||||
w->postDelayed(r,8000);
|
||||
app.exec();
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ void DefaultItemAnimator::runPendingAnimations() {
|
||||
// Next, move stuff
|
||||
if (movesPending) {
|
||||
mMovesList.push_back(mPendingMoves);
|
||||
std::vector<MoveInfo*>&moves=mMovesList.back();
|
||||
std::vector<MoveInfo*>&moves = mMovesList.back();
|
||||
mPendingMoves.clear();
|
||||
Runnable mover;
|
||||
mover=[this,&moves]() {
|
||||
@ -84,7 +84,7 @@ void DefaultItemAnimator::runPendingAnimations() {
|
||||
// Next, add stuff
|
||||
if (additionsPending) {
|
||||
mAdditionsList.push_back(mPendingAdditions);
|
||||
std::vector<RecyclerView::ViewHolder*>& additions=mAdditionsList.back();
|
||||
std::vector<RecyclerView::ViewHolder*>& additions = mAdditionsList.back();
|
||||
mPendingAdditions.clear();
|
||||
Runnable adder;
|
||||
adder = [this,&additions]() {
|
||||
@ -114,6 +114,22 @@ bool DefaultItemAnimator::animateRemove(RecyclerView::ViewHolder& holder) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DefaultItemAnimator::onRemoveAnimationStart(RecyclerView::ViewHolder*holder,Animator& animator,bool isReverse){
|
||||
dispatchRemoveStarting(*holder);
|
||||
}
|
||||
|
||||
void DefaultItemAnimator::onRemoveAnimationEnd(RecyclerView::ViewHolder*holder,Animator& animator,bool isReverse){
|
||||
|
||||
ViewPropertyAnimator& animation = holder->itemView->animate();
|
||||
animation.setListener({});
|
||||
holder->itemView->setAlpha(1);
|
||||
dispatchRemoveFinished(*holder);
|
||||
auto it = std::find(mRemoveAnimations.begin(),mRemoveAnimations.end(),holder);
|
||||
if(it!=mRemoveAnimations.end())mRemoveAnimations.erase(it);//mRemoveAnimations.remove(holder);
|
||||
else LOGE("not found.....");
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
|
||||
void DefaultItemAnimator::animateRemoveImpl(RecyclerView::ViewHolder& holder) {
|
||||
|
||||
View* view = holder.itemView;
|
||||
@ -121,18 +137,8 @@ void DefaultItemAnimator::animateRemoveImpl(RecyclerView::ViewHolder& holder) {
|
||||
mRemoveAnimations.push_back(&holder);//add(holder);
|
||||
//AnimatorListenerAdapter
|
||||
Animator::AnimatorListener al;
|
||||
al.onAnimationStart=[this,&holder](Animator&animator,bool isReverse){
|
||||
dispatchRemoveStarting(holder);
|
||||
};
|
||||
al.onAnimationEnd=[this,&animation,&holder](Animator& animator,bool isReverse){
|
||||
animation.setListener({});
|
||||
holder.itemView->setAlpha(1);
|
||||
dispatchRemoveFinished(holder);
|
||||
auto it = std::find(mRemoveAnimations.begin(),mRemoveAnimations.end(),&holder);
|
||||
if(it!=mRemoveAnimations.end())mRemoveAnimations.erase(it);//mRemoveAnimations.remove(holder);
|
||||
else LOGE("not found.....");
|
||||
dispatchFinishedWhenDone();
|
||||
};
|
||||
al.onAnimationStart=std::bind(&DefaultItemAnimator::onRemoveAnimationStart,this,&holder,std::placeholders::_1,std::placeholders::_2);
|
||||
al.onAnimationEnd = std::bind(&DefaultItemAnimator::onRemoveAnimationEnd,this,&holder,std::placeholders::_1,std::placeholders::_2);
|
||||
animation.setDuration(getRemoveDuration()).alpha(0).setListener(al).start();
|
||||
}
|
||||
|
||||
@ -185,10 +191,30 @@ bool DefaultItemAnimator::animateMove(RecyclerView::ViewHolder& holder, int from
|
||||
return true;
|
||||
}
|
||||
|
||||
void DefaultItemAnimator::onMoveAnimationStart(RecyclerView::ViewHolder*holder,Animator& animator,bool isReverse){
|
||||
dispatchMoveStarting(*holder);
|
||||
}
|
||||
void DefaultItemAnimator::onMoveAnimationCancel(int deltaX,int deltaY,RecyclerView::ViewHolder*holder,Animator& animator,bool isReverse){
|
||||
if (deltaX != 0) {
|
||||
holder->itemView->setTranslationX(0);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
holder->itemView->setTranslationY(0);
|
||||
}
|
||||
}
|
||||
void DefaultItemAnimator::onMoveAnimationEnd(RecyclerView::ViewHolder*holder,Animator& animator,bool isReverse){
|
||||
ViewPropertyAnimator& animation = holder->itemView->animate();
|
||||
animation.setListener({});
|
||||
dispatchMoveFinished(*holder);
|
||||
auto it =std::find(mMoveAnimations.begin(),mMoveAnimations.end(),holder);
|
||||
mMoveAnimations.erase(it);//mMoveAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
|
||||
void DefaultItemAnimator::animateMoveImpl(RecyclerView::ViewHolder& holder, int fromX, int fromY, int toX, int toY) {
|
||||
View* view = holder.itemView;
|
||||
int deltaX = toX - fromX;
|
||||
int deltaY = toY - fromY;
|
||||
const int deltaX = toX - fromX;
|
||||
const int deltaY = toY - fromY;
|
||||
if (deltaX != 0) {
|
||||
view->animate().translationX(0);
|
||||
}
|
||||
@ -202,24 +228,9 @@ void DefaultItemAnimator::animateMoveImpl(RecyclerView::ViewHolder& holder, int
|
||||
mMoveAnimations.push_back(&holder);//add(holder);
|
||||
Animator::AnimatorListener al;
|
||||
|
||||
al.onAnimationStart = [this,&holder](Animator& animator,bool isReverse) {
|
||||
dispatchMoveStarting(holder);
|
||||
};
|
||||
al.onAnimationCancel = [this,view,deltaX,deltaY](Animator& animator) {
|
||||
if (deltaX != 0) {
|
||||
view->setTranslationX(0);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
view->setTranslationY(0);
|
||||
}
|
||||
};
|
||||
al.onAnimationEnd = [this,&animation,&holder](Animator& animator,bool isReverse) {
|
||||
animation.setListener({});
|
||||
dispatchMoveFinished(holder);
|
||||
auto it =std::find(mMoveAnimations.begin(),mMoveAnimations.end(),&holder);
|
||||
mMoveAnimations.erase(it);//mMoveAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
};
|
||||
al.onAnimationStart = std::bind(&DefaultItemAnimator::onMoveAnimationStart,this,&holder,std::placeholders::_1,std::placeholders::_2);
|
||||
//al.onAnimationCancel = std::bind(&DefaultItemAnimator::onMoveAnimationCancel,this,deltaX,deltaY,&holder,std::placeholders::_1,std::placeholders::_2);
|
||||
al.onAnimationEnd = std::bind(&DefaultItemAnimator::onMoveAnimationEnd,this,&holder,std::placeholders::_1,std::placeholders::_2);
|
||||
animation.setDuration(getMoveDuration()).setListener(al).start();
|
||||
}
|
||||
|
||||
@ -251,6 +262,10 @@ bool DefaultItemAnimator::animateChange(RecyclerView::ViewHolder& oldHolder, Rec
|
||||
return true;
|
||||
}
|
||||
|
||||
void DefaultItemAnimator::onChangeAnimationStart(RecyclerView::ViewHolder*,Animator& animator,bool isReverse){
|
||||
}
|
||||
void DefaultItemAnimator::onChangeAnimationEnd(RecyclerView::ViewHolder*,Animator& animator,bool isReverse){
|
||||
}
|
||||
void DefaultItemAnimator::animateChangeImpl(ChangeInfo& changeInfo) {
|
||||
RecyclerView::ViewHolder* holder = changeInfo.oldHolder;
|
||||
View* view = holder == nullptr ? nullptr : holder->itemView;
|
||||
|
@ -42,6 +42,14 @@ protected:
|
||||
ChangeInfo(RecyclerView::ViewHolder& oldHolder, RecyclerView::ViewHolder& newHolder,
|
||||
int fromX, int fromY, int toX, int toY);
|
||||
};
|
||||
protected:
|
||||
void onRemoveAnimationStart(RecyclerView::ViewHolder*,Animator& animator,bool isReverse);
|
||||
void onRemoveAnimationEnd(RecyclerView::ViewHolder*,Animator& animator,bool isReverse);
|
||||
void onMoveAnimationStart(RecyclerView::ViewHolder*,Animator& animator,bool isReverse);
|
||||
void onMoveAnimationCancel(int deltaX,int deltaY,RecyclerView::ViewHolder*,Animator& animator,bool isReverse);
|
||||
void onMoveAnimationEnd(RecyclerView::ViewHolder*,Animator& animator,bool isReverse);
|
||||
void onChangeAnimationStart(RecyclerView::ViewHolder*,Animator& animator,bool isReverse);
|
||||
void onChangeAnimationEnd(RecyclerView::ViewHolder*,Animator& animator,bool isReverse);
|
||||
protected:
|
||||
void animateRemoveImpl(RecyclerView::ViewHolder& holder);
|
||||
void endChangeAnimation(std::vector<ChangeInfo*>& infoList, RecyclerView::ViewHolder& item);
|
||||
|
Loading…
Reference in New Issue
Block a user