16

enter image description here

I need help about transition between activities:

I have two activities A and B and both have a ViewPager with the same image list. Every page has an ImageView with the transitionName equals to ​​​​​​​​image_x​​​​ where​​​​​​​​ x is the page index.

A starts activity B calling ActivityOptionsCompat.makeSceneTransitionAnimation and the enter transition is totally fine.

The problem is the following: when I close activity B, the exit transition does not initialize the view pager of activity A at the same position of B.

When user closes B, the latter sets the current page position in the result. In onActivityResult of activity A, I call the setCurrentItem and the behavior is showed in the gif.

Is there a way to update activity A before the exit transition starts?

rciovati
  • 27,603
  • 6
  • 82
  • 101
fran
  • 1,119
  • 1
  • 10
  • 27
  • Activity result is the best way of doing this because you do not have the object of activity so activity result is the best way to implement it. – Pratik Goyal Dec 22 '15 at 11:19
  • @PratikGoyal yes but acting this way the exit transition is as showed in the gif, and it is very bad. I would like to see the exit transition just like the start transition (from A to B). – fran Dec 22 '15 at 11:24
  • What if you eliminate the transition animation in the viewPager when coming back to A (if possible)? If it changes instantly, the user wouldn't notice. – Nilzor Dec 22 '15 at 13:16
  • @Nilzor If I remove the exit transition and the animation of the viewpager when changing the page there are no problems. I wanted to know if there were a way to avoid this solution. – fran Dec 22 '15 at 13:57
  • Yea I was suggesting to remove it only temporary, so that the ViewPager animations are there when the user interacts with it but not when the system goes back. But I guess the exit page transition will be a problem as well, as there will be some milliseconds the old image is shown – Nilzor Dec 22 '15 at 14:23
  • @fran: you can use `interface` between **A** and **B**. When you get page change event in **B**, pass event through `interface` to **A** Activity – Kushal Jan 08 '16 at 11:06
  • @fran I have solved your query... please check my answer... i used `interface` concept for solution... i hope this will help you – Kushal Jan 09 '16 at 07:17

2 Answers2

7

You should be able to do achieve that if you use setCurrentItem in the onActivityReenter instead of in onActivityResult (in your ActivityA).

Just be sure you:

  1. Before finishing ActivityB, set the result (either with setResult(int resultCode) or setResult(int resultCode, Intent data))
  2. Call supportFinishAfterTransition() (or finishAfterTransition()) instead of regular finish() to "close" the ActivityB.

To summerize:

in ActivityB:

public void close(){
    Intent data = new Intent();
    data.putExtra(KEY_CURRENT_ITEM, mFullscreenViewPager.getCurrentItem());
    setResult(RESULT_CODE, data);
    supportFinishAfterTransition();
}

in ActivityA:

@Override
public void onActivityReenter(int resultCode, Intent data) {
    super.onActivityReenter(resultCode, data);
    if (data.hasExtra(KEY_CURRENT_ITEM)){
         mViewPager.setCurrentItem(data.getIntExtra(KEY_CURRENT_ITEM, 0), false);
    }
}
Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
0

I have got solution.

1. Create Interface class which works between both Activity : demoClass.java

public class demoClass {

public static demoClass instance;
public demoInterface mCallback;

public static demoClass getInstance() {
    if(instance == null) {
        instance = new demoClass();
    }
    return instance;
}

public void setListener(demoInterface callback) {
    this.mCallback = callback;
}

public void changePage(int which) {
    if(this.mCallback != null) {
        this.mCallback.changePage(which);
    }
}


public interface demoInterface {
    public void changePage(int which);
}

}

2. From Activity B , call interface method :

demoClass.getInstance().changePage(mFullscreenViewPager.getCurrentItem());

3. From Activity A , implement interface and register listen to interface :

public class ActivityA extends Activity implements demoClass.demoInterface {
...
} 
---------------------
demoClass.getInstance().setListener(ActivityA.this);

4. Implement changePage(int) method in A :

@Override
public void changePage(int which) {
    mViewPager.setCurrentItem(page);
}

Explaination

When Activity B changes page, report event to interface demoClass.demoInterface thorugh demoClass.getInstance().changePage(index). This will ultimately call method changePage(int) of Activity A and we will change ViewPager content on the go.

Result

You can check output at GIF here

Kushal
  • 8,100
  • 9
  • 63
  • 82
  • Ok, it's a solution. But if the system releases activity A for some reason, will it work? – fran Jan 09 '16 at 08:30
  • Yes... just you need to save `page` variable value, you can restore when activity A re-starts. For storing, you can use SharedPreference... – Kushal Jan 09 '16 at 09:10
  • Ok, I will try. Thanks! – fran Jan 09 '16 at 09:12
  • Your solution doesn't solve my issue. The behavior is still this: http://giphy.com/gifs/d3l2J0f2o84YL0tO Thanks – fran Jan 11 '16 at 10:21
  • Please post your code... because same solution is working for me... i can share code example if you wish... – Kushal Jan 11 '16 at 10:38
  • From gif, i can say you are resetting mViewPager.setCurrentPage from Activity A somewhere... so page 5 is changing to page 3 when going to Activity A... pls post your code so tht i can help – Kushal Jan 11 '16 at 10:40
  • I think that trying your code with images instead of text, you'll get the same behavior... – fran Jan 11 '16 at 10:58
  • No... I have used different texts in different pages... It do not have relation with text or image... code is working :) – Kushal Jan 11 '16 at 14:02