4

I have made a PopupWindow that pops up when a user selects an item in a list. And then when he swipes left and right on the popup window, the data (in the popup) is change to the previous and next items in the list, respectively.

And I have made it so that it looks like a new popup window is sliding in from the left as the current one goes out from the right of the screen when the user slides his finger to the right ("Next" motion). And vice versa for the "Previous" motion.

But the issue is, as I have made 2 styles for the two animations (left-to-middle while middle-to-right and right-to-middle while middle-to-left), and as PopupWindows does not get updated while it is showing, when the user swipes to the right ("Next") and then to the left ("Previous"), the animation looks choppy as the 2 animations overlap. The same happens when the swipes are reversed again.

Now, if I call update() after changing the Animation, then it again slides in to the middle. That's even worse. So is there anything I can do to achieve the behavior I want?

Thanks.

EDIT: Source Code

Here is the code I used to show the popup for the first time:

popup1 = new PopupWindow(popupLayout, popup_width, popup_height, true);
popup1.setAnimationStyle(R.style.AnimationPopup);
popup1.showAtLocation(this.findViewById(R.id.main_container), Gravity.CENTER, 0, 0);

And this is the next() method's code:

if(popup2 != null) popup1 = popup2;
if(popup1 != null) {
    popup2 = new PopupWindow(popupLayout, popup_width, popup_height, true);
    popup2.setAnimationStyle(R.style.AnimationPopup);

    popup1.dismiss();
    popup2.showAtLocation(rootLayout, Gravity.CENTER, 0, 0);
}

And this is the prev() method's code:

if(popup2 != null) popup1 = popup2;
if(popup1 != null) {
    popup2 = new PopupWindow(popupLayout, popup_width, popup_height, true);
    popup2.setAnimationStyle(R.style.AnimationPopupReverse);

    popup1.setAnimationStyle(R.style.AnimationPopupReverse);
    popup1.dismiss();

    popup2.showAtLocation(rootLayout, Gravity.CENTER, 0, 0);
}

That's all for the Java code. The AnimationPopup is a XML with a simple show of slide-from-right-to-center and a hide of slide-from-center-to-left animations. And the AnimationPopupReverse is the reverse of the above animations.

I have provided my first try of the codes. Here, the changed animations take effect after one more popup has been shown.

Roshnal
  • 1,284
  • 3
  • 16
  • 39
  • if you want only slide animation then you can inflate View Pager in Pop Up Window. – ShreeshaDas Mar 19 '13 at 11:46
  • @ShreeshaS As I have stated in my question, I _have_ got the slide working, but the animation should be reversed dynamically depending on the swipe (gesture) direction. Otherwise, it works fine. – Roshnal Mar 19 '13 at 12:02
  • So the problem you're experiencing is only about performances? How did you get animations and popupwindows work together? I think you should post some code in order to give some more detail. – a.bertucci Mar 24 '13 at 20:54
  • 1
    And you remembered to use android:hardwareAccelerated="true" in the manifest? – Warpzit Mar 25 '13 at 08:49
  • @Warpzit No, will that make a difference? And I'll post some code soon. – Roshnal Mar 26 '13 at 03:27
  • @Roshnal It makes a HUGE difference on animations so please try out with android:hardwareAccelerated="true" under your application tag. – Warpzit Mar 26 '13 at 06:29
  • @Warpzit Yeah, it did make a difference, but not completely for my case. I'll upvote your answer, but one other answer also contributed. So I'm going to award the bounty to that. Thanks again! – Roshnal Mar 26 '13 at 10:47

2 Answers2

2

All animations appear much cleaner if you use android:hardwareAccelerated="true" in the manifest under the application tag. Even regular slide left/right animation will seem choppy without being hardware accelerated.

Warpzit
  • 27,966
  • 19
  • 103
  • 155
1

An easy solution would be to:

  1. Disable swiping until the current animation ends.
  2. Use android:duration="@android:integer/config_mediumAnimTime" making it pretty standard and sort of fast.

You can also implement some sort of dragging:

Catch Touch Events and change the location of the Popup accordingly. When the user removes his finger, either dispatch the swipe and show the next/previous popup window. This would actually involve some head scratching.


The best would be to use a ViewPager that just shows the popup windows with all the functionality of swiping implemented:

Example:

yourViewPager.setAdapter(new PagerAdapter() {
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view;
        //intialise view to a PopupWindow or some Layout with a PopupWindow in the location you want
        container.addView(view, 0);
        return view;
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return (view==object);
    }

    @Override
    public int getCount() {
        //return the count
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View)object);
    }
    @Override
    public void finishUpdate(ViewGroup arg0) {
    }

    @Override
    public void restoreState(Parcelable arg0, ClassLoader arg1) {
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void startUpdate(ViewGroup arg0) {
    }
});
Sherif elKhatib
  • 45,786
  • 16
  • 89
  • 106
  • Great answer! Your first solution kinda worked. Not exactly what I had in mind, but now I've got a interesting effect. Thanks a lot..! :) – Roshnal Mar 26 '13 at 10:48