TWL
TWL

Reputation: 6646

Android: setTranslationX glitches after view's anchor changed

Using setTranslationX, I'm trying to animate a view as I swipe it across the screen. Then after it passes a threshold-X, I assign the view a new RelativeLayout.RIGHT_OF.

I want it to stop animating (whether or not I continue swiping) at that point and basically lock to that new anchor.

This is where the problem is: suddenly the view jumps X position to the right of its new anchor.

I've tried, when it's >= threshold, to set setTranslationX(0), but then I see the view twitch/flash twice, once to its original 0, then to the new 0.

I would love to get rid of that double twitch/flash, but don't know how at this point.

@Override
public void onChildDraw(Canvas c ... float dX) {
    threshold = anchorView.getRight();

    if (animate) {
        if (dX >= 0) {
            translationX = Math.min(dX, threshold);

            if (dX >= threshold) {
                translationX = 0;  // (A) if I do this, then mainView flashs twice: original 0, then new 0
                setToRightOf(mainView, anchorView);
                mainView.invalidate();  // has no effect
            }
        } else {
            translationX = 0;
        }

        // if I don't do (A), then mainView will suddenly jump to 2*threshold
        mainView.setTranslationX(translationX);
        return;
    }

    super.onChildDraw(c ... dX);
}

Upvotes: 1

Views: 384

Answers (1)

TWL
TWL

Reputation: 6646

Okay, instead of assigning RelativeLayout.RIGHT_OF during onDraw to set the threshold boundary, I took it out and assigned it when my touch left the screen.

But to insure I wouldn't swipe back behind that threshold while swiping, I had to add another case to check translationX and instead of previously trying to rely on the RelativeLayout anchor.

Now, I'm using setTag() and getTag() to help confirm the threshold during the swipe:

if (dX >= 0) {
    if ((Object) past != tag)
        translationX = Math.min(dX, threshold);
    else
        translationX = threshold;

    if (dX >= threshold) {
        if ((Object) past != tag) {
            anchorView.setTag(past);
        }
    }
} else {
    ...
}

Plus a couple other places to make sure I reset anchorView's tag and the translationX when needed, then it's all good.

It works for now!

(doesn't directly solve the double flash/twitch issue, but a different approach to the same goal)

(any other recommendations besides using setTag()?)

P.S. In my earlier attempts, instead of invalidate(), I later tried mainView.requestLayout() with no success either, thinking requestLayout() also factors in position.

Upvotes: 1

Related Questions