6 | * User: chengwangyong(cwy545177162@163.com) 7 | * Date: 2015-12-28 8 | * Time: 23:41 9 | */ 10 | public interface OnNewIntent { 11 | /** 12 | * SingleTop mode,this fragment not be Re create 13 | */ 14 | void onNewIntent(); 15 | } 16 | -------------------------------------------------------------------------------- /stacklibrary/src/main/java/com/mrwang/stacklibrary/RootActivity.java: -------------------------------------------------------------------------------- 1 | package com.mrwang.stacklibrary; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.AnimRes; 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.KeyEvent; 9 | import android.view.ViewGroup; 10 | import android.widget.FrameLayout; 11 | 12 | /** 13 | * extends this Activity to facilitate the management of multiple fragment instances 14 | * User: chengwangyong(cwy545177162@163.com) 15 | * Date: 2016-01-19 16 | * Time: 18:32 17 | */ 18 | public abstract class RootActivity extends AppCompatActivity { 19 | 20 | public StackManager manager; 21 | public KeyCallBack callBack; 22 | 23 | 24 | @Override 25 | protected final void onCreate(@Nullable Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | FrameLayout frameLayout = new FrameLayout(this); 28 | frameLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); 29 | frameLayout.setId(R.id.framLayoutId); 30 | setContentView(frameLayout); 31 | RootFragment fragment = getRootFragment(); 32 | manager = new StackManager(this); 33 | manager.setFragment(fragment); 34 | onCreateNow(savedInstanceState); 35 | } 36 | 37 | /** 38 | * Set the bottom of the fragment 39 | * 40 | * @return fragment 41 | */ 42 | protected abstract 43 | @NonNull 44 | RootFragment getRootFragment(); 45 | 46 | /** 47 | * Set page switch animation 48 | * 49 | * @param nextIn The next page to enter the animation 50 | * @param nextOut The next page out of the animation 51 | * @param quitIn The current page into the animation 52 | * @param quitOut Exit animation for the current page 53 | */ 54 | public void setAnim(@AnimRes int nextIn, @AnimRes int nextOut, @AnimRes int quitIn, @AnimRes int quitOut) { 55 | manager.setAnim(nextIn, nextOut, quitIn, quitOut); 56 | } 57 | 58 | /** 59 | * Rewriting onCreate method 60 | * 61 | * @param savedInstanceState savedInstanceState 62 | */ 63 | public void onCreateNow(Bundle savedInstanceState) { 64 | 65 | } 66 | 67 | 68 | @Override 69 | public final boolean onKeyDown(int keyCode, KeyEvent event) { 70 | switch (keyCode) { 71 | case KeyEvent.KEYCODE_BACK: 72 | manager.onBackPressed(); 73 | return true; 74 | default: 75 | if (callBack != null) { 76 | return callBack.onKeyDown(keyCode, event); 77 | } 78 | break; 79 | } 80 | return super.onKeyDown(keyCode, event); 81 | } 82 | 83 | /** 84 | * Set button to click callback 85 | * 86 | * @param callBack callback 87 | */ 88 | public void setKeyCallBack(KeyCallBack callBack) { 89 | this.callBack = callBack; 90 | } 91 | 92 | 93 | } 94 | -------------------------------------------------------------------------------- /stacklibrary/src/main/java/com/mrwang/stacklibrary/RootFragment.java: -------------------------------------------------------------------------------- 1 | package com.mrwang.stacklibrary; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.AnimRes; 5 | import android.support.annotation.NonNull; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v4.app.FragmentActivity; 8 | 9 | /** 10 | * extends this Fragment to facilitate the management of multiple fragment instances 11 | * User: chengwangyong(cwy545177162@163.com) 12 | * Date: 2016-01-18 13 | * Time: 18:19 14 | */ 15 | public abstract class RootFragment extends Fragment implements OnNewIntent { 16 | 17 | /** 18 | * open a new Fragment 19 | * 20 | * @param fragment fragment 21 | */ 22 | public void open(@NonNull RootFragment fragment) { 23 | getRoot().manager.addFragment(this, fragment, null); 24 | } 25 | 26 | /** 27 | * open a new Fragment,And transfer parameters with bundle 28 | *
29 | * Like this 30 | *
{@code 31 | * Bundle bundle=new Bundle(); 32 | * bundle.put(key,value); 33 | * In the new fragment, you can accept parameters like this 34 | * Bundle bundle = fragment.getArguments(); 35 | * bundle.get(key); 36 | * }37 | * 38 | * @param fragment fragment 39 | * @param bundle bundle 40 | */ 41 | public void open(@NonNull RootFragment fragment, Bundle bundle) { 42 | getRoot().manager.addFragment(this, fragment, bundle); 43 | } 44 | 45 | /** 46 | * open a new Fragment,And transfer parameters with bundle andr set StackMode 47 | * Like this 48 | *
{@code 49 | * Bundle bundle=new Bundle(); 50 | * bundle.put(key,value); 51 | * 52 | * }53 | * In the new fragment, you can accept parameters like this 54 | *
{@code 55 | * Bundle bundle = fragment.getArguments(); 56 | * bundle.get(key);58 | * 59 | * @param fragment fragment 60 | * @param bundle bundle 61 | * @param stackMode stackMode,{@link StackManager#STANDARD} or more 62 | */ 63 | 64 | public void open(@NonNull RootFragment fragment, Bundle bundle, int stackMode) { 65 | getRoot().manager.addFragment(this, fragment, bundle, stackMode); 66 | } 67 | 68 | /** 69 | * Jump to the specified fragment and do not hide the current page. 70 | * 71 | * @param to To jump to the page 72 | */ 73 | public void dialogFragment(Fragment to) { 74 | getRoot().manager.dialogFragment(to); 75 | } 76 | 77 | /** 78 | * Set the animation to add fragment in dialog mode 79 | * 80 | * @param dialog_in The next page to enter the animation 81 | * @param dialog_out The next page out of the animation 82 | */ 83 | public void setDialogAnim(@AnimRes int dialog_in, @AnimRes int dialog_out) { 84 | getRoot().manager.setDialogAnim(dialog_in, dialog_out); 85 | } 86 | 87 | /** 88 | * close this current Fragment 89 | */ 90 | public void close() { 91 | getRoot().manager.close(this); 92 | } 93 | 94 | /** 95 | * Closes the specified fragment 96 | * 97 | * @param fragment the specified fragment 98 | */ 99 | public void close(RootFragment fragment) { 100 | getRoot().manager.close(fragment); 101 | } 102 | 103 | 104 | @Override 105 | public void onHiddenChanged(boolean hidden) { 106 | if (hidden) { 107 | onNowHidden(); 108 | } else { 109 | onNextShow(); 110 | } 111 | } 112 | 113 | @Override 114 | public void onPause() { 115 | super.onPause(); 116 | } 117 | 118 | /** 119 | * Override this method to facilitate access to the current page page Pause callback 120 | */ 121 | private void onNowHidden() { 122 | 123 | } 124 | 125 | /** 126 | * Override this method to facilitate access to the current page page Resume callback 127 | */ 128 | private void onNextShow() { 129 | 130 | } 131 | 132 | /** 133 | * Get fragment dependent Activity, many times this is very useful 134 | * 135 | * @return RootActivity dependent Activity 136 | */ 137 | public RootActivity getRoot() { 138 | FragmentActivity activity = getActivity(); 139 | if (activity instanceof RootActivity) { 140 | return (RootActivity) activity; 141 | } else { 142 | throw new ClassCastException("this activity mast be extends RootActivity"); 143 | } 144 | } 145 | 146 | /** 147 | * Override this method in order to facilitate the singleTop mode to be called in 148 | */ 149 | @Override 150 | public void onNewIntent() { 151 | } 152 | 153 | 154 | } 155 | -------------------------------------------------------------------------------- /stacklibrary/src/main/java/com/mrwang/stacklibrary/StackManager.java: -------------------------------------------------------------------------------- 1 | package com.mrwang.stacklibrary; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.AnimRes; 5 | import android.support.annotation.IntDef; 6 | import android.support.annotation.NonNull; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v4.app.FragmentActivity; 9 | import android.support.v4.app.FragmentManager; 10 | import android.support.v4.app.FragmentTransaction; 11 | import android.view.View; 12 | import android.view.animation.Animation; 13 | import android.view.animation.AnimationUtils; 14 | 15 | /** 16 | * Fragment task stack manager 17 | *
57 | * }
18 | * User: chengwangyong(cwy545177162@163.com)
19 | * Date: 2015-12-06
20 | * Time: 20:25
21 | */
22 | public class StackManager implements CloseFragment {
23 | private FragmentStack stack;
24 | private final FragmentActivity context;
25 | private long CLICK_SPACE = 500;
26 | private long currentTime;
27 | private int currentMode;
28 | private int nextIn;
29 | private int nextOut;
30 | private int quitIn;
31 | private int quitOut;
32 | private Animation next_in;
33 | private Animation next_out;
34 | private int dialog_in;
35 | private int dialog_out;
36 | public static final int STANDARD = 0x11;
37 | public static final int SINGLE_TOP = 0x12;
38 | public static final int SINGLE_TASK = 0x13;
39 | public static final int SINGLE_INSTANCE = 0x14;
40 | public static final int KEEP_CURRENT = 0x15;
41 |
42 | /**
43 | * Set the time to click to Prevent repeated clicks,default 500ms
44 | *
45 | * @param CLICK_SPACE Repeat click time
46 | */
47 | public void setClickSpace(long CLICK_SPACE) {
48 | this.CLICK_SPACE = CLICK_SPACE;
49 | }
50 |
51 |
52 | public StackManager(FragmentActivity context) {
53 | stack = new FragmentStack();
54 | stack.setCloseFragmentListener(this);
55 | this.context = context;
56 |
57 | }
58 |
59 | /**
60 | * Set the bottom of the fragment
61 | * @param mTargetFragment bottom of the fragment
62 | */
63 | public void setFragment(@NonNull RootFragment mTargetFragment) {
64 | FragmentTransaction transaction = context.getSupportFragmentManager().beginTransaction();
65 | transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
66 | .replace(R.id.framLayoutId, mTargetFragment, mTargetFragment.getClass().getName())
67 | .commit();
68 | stack.putStandard(mTargetFragment);
69 | }
70 |
71 | /**
72 | * Jump to the specified fragment
73 | * @param from current fragment
74 | * @param to next fragment
75 | */
76 | public void addFragment(@NonNull final Fragment from, @NonNull final Fragment to) {
77 | if (System.currentTimeMillis() - currentTime > CLICK_SPACE) {
78 | currentTime = System.currentTimeMillis();
79 |
80 | FragmentTransaction transaction = context.getSupportFragmentManager().beginTransaction();
81 | if (nextIn != 0 && nextOut != 0 && quitIn != 0 && quitOut != 0) {
82 | transaction
83 | .setCustomAnimations(nextIn, nextOut)
84 | .add(R.id.framLayoutId, to, to.getClass().getName())
85 | .setCustomAnimations(nextIn, nextOut)
86 | .hide(from)
87 | .commit();
88 | } else {
89 | transaction
90 | .add(R.id.framLayoutId, to, to.getClass().getName())
91 | .hide(from)
92 | .commit();
93 | }
94 |
95 | }
96 | }
97 |
98 | /**
99 | * Set page switch animation
100 | *
101 | * @param nextIn The next page to enter the animation
102 | * @param nextOut The next page out of the animation
103 | * @param quitIn The current page into the animation
104 | * @param quitOut Exit animation for the current page
105 | */
106 | public void setAnim(@AnimRes int nextIn, @AnimRes int nextOut, @AnimRes int quitIn, @AnimRes int quitOut) {
107 | this.nextIn = nextIn;
108 | this.nextOut = nextOut;
109 | this.quitIn = quitIn;
110 | this.quitOut = quitOut;
111 | next_in = AnimationUtils.loadAnimation(context, quitIn);
112 | next_out = AnimationUtils.loadAnimation(context, quitOut);
113 | }
114 |
115 |
116 | /**
117 | * Jump to the specified fragment
118 | * @param from current fragment
119 | * @param to next fragment
120 | * @param bundle Parameter carrier
121 | * @param stackMode fragment stack Mode
122 | */
123 | public void addFragment(RootFragment from, RootFragment to, Bundle bundle,@StackMode int stackMode) {
124 | if (stackMode != KEEP_CURRENT) {
125 | currentMode = stackMode;
126 | }
127 | if (bundle != null) {
128 | to.setArguments(bundle);
129 | }
130 | switch (currentMode) {
131 | case SINGLE_TOP:
132 | if (!stack.putSingleTop(to)) {
133 | addFragment(from, to);
134 | }
135 | break;
136 | case SINGLE_TASK:
137 | if (!stack.putSingleTask(to)) {
138 | addFragment(from, to);
139 | }
140 | break;
141 | case SINGLE_INSTANCE:
142 | stack.putSingleInstance(to);
143 | addFragment(from, to);
144 | break;
145 | default:
146 | stack.putStandard(to);
147 | addFragment(from, to);
148 | break;
149 | }
150 |
151 |
152 | }
153 |
154 | /**
155 | * open this fragment
156 | * @param from current fragment
157 | * @param to next fragment
158 | */
159 | public void openFragment(RootFragment from, RootFragment to) {
160 | addFragment(from, to, null, KEEP_CURRENT);
161 | }
162 |
163 | /**
164 | * Jump to the specified fragment with a parameter form
165 | * @param from current fragment
166 | * @param to next fragment
167 | * @param bundle Parameter carrier
168 | */
169 | public void addFragment(RootFragment from, RootFragment to, Bundle bundle) {
170 | addFragment(from, to, bundle, KEEP_CURRENT);
171 | }
172 |
173 | /**
174 | * Jump to the specified fragment and do not hide the current page.
175 | *
176 | * @param to To jump to the page
177 | */
178 | public void dialogFragment(Fragment to) {
179 | FragmentTransaction transaction = context.getSupportFragmentManager().beginTransaction();
180 | if (!to.isAdded()) {
181 | if (dialog_in != 0 && dialog_out != 0) {
182 | transaction
183 | .setCustomAnimations(dialog_in, dialog_out)
184 | .add(R.id.framLayoutId, to, to.getClass().getName())
185 | .commit();
186 | } else {
187 | transaction
188 | .add(R.id.framLayoutId, to, to.getClass().getName())
189 | .commit();
190 | }
191 |
192 | }
193 | }
194 |
195 | /**
196 | * Set the animation to add fragment in dialog mode
197 | *
198 | * @param dialog_in The next page to enter the animation
199 | * @param dialog_out The next page out of the animation
200 | */
201 | public void setDialogAnim(@AnimRes int dialog_in, @AnimRes int dialog_out) {
202 | this.dialog_in = dialog_in;
203 | this.dialog_out = dialog_out;
204 | }
205 |
206 | /**
207 | * Closes the specified fragment
208 | *
209 | * @param mTargetFragment fragment
210 | */
211 | public void closeFragment(Fragment mTargetFragment) {
212 | FragmentTransaction transaction = context.getSupportFragmentManager().beginTransaction();
213 | transaction.remove(mTargetFragment).commit();
214 | }
215 |
216 | /**
217 | * Close the specified fragment by tag
218 | *
219 | * @param tag fragment tag
220 | */
221 | public void closeFragment(String tag) {
222 | Fragment fragmentByTag = context.getSupportFragmentManager().findFragmentByTag(tag);
223 | if (fragmentByTag != null) {
224 | closeFragment(fragmentByTag);
225 | context.getSupportFragmentManager().popBackStackImmediate(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE);
226 | }
227 | }
228 |
229 | public void close() {
230 | context.getSupportFragmentManager().popBackStack();
231 | }
232 |
233 |
234 | /**
235 | * Close all fragment
236 | */
237 | public void closeAllFragment() {
238 | int backStackCount = context.getSupportFragmentManager().getBackStackEntryCount();
239 | for (int i = 0; i < backStackCount; i++) {
240 | int backStackId = context.getSupportFragmentManager().getBackStackEntryAt(i).getId();
241 | context.getSupportFragmentManager().popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
242 | }
243 | }
244 |
245 | public void onBackPressed() {
246 | Fragment[] last = stack.getLast();
247 | final Fragment from = last[0];
248 | Fragment to = last[1];
249 |
250 | if (from != null) {
251 | if (to != null) {
252 | FragmentTransaction transaction = context.getSupportFragmentManager().beginTransaction();
253 | transaction.show(to).commit();
254 | }
255 | View fromVie = from.getView();
256 | if (fromVie != null && next_out != null) {
257 | fromVie.startAnimation(next_out);
258 | next_out.setAnimationListener(new Animation.AnimationListener() {
259 | @Override
260 | public void onAnimationStart(Animation animation) {
261 |
262 | }
263 |
264 | @Override
265 | public void onAnimationEnd(Animation animation) {
266 | stack.onBackPressed();
267 | closeFragment(from);
268 | }
269 |
270 | @Override
271 | public void onAnimationRepeat(Animation animation) {
272 |
273 | }
274 | });
275 |
276 | } else {
277 | stack.onBackPressed();
278 | closeFragment(from);
279 | }
280 | }
281 | if (to != null) {
282 | View toView = to.getView();
283 | if (toView != null && next_in != null) {
284 | toView.startAnimation(next_in);
285 | }
286 | } else {
287 | closeAllFragment();
288 | context.finish();
289 | }
290 | }
291 |
292 | public static boolean isFirstClose = true;
293 |
294 | @Override
295 | public void close(final RootFragment fragment) {
296 | if (isFirstClose) {
297 | View view = fragment.getView();
298 | if (view != null) {
299 | if (next_out != null) {
300 | view.startAnimation(next_out);
301 | next_out.setAnimationListener(new Animation.AnimationListener() {
302 | @Override
303 | public void onAnimationStart(Animation animation) {
304 |
305 | }
306 |
307 | @Override
308 | public void onAnimationEnd(Animation animation) {
309 | closeFragment(fragment);
310 | }
311 |
312 | @Override
313 | public void onAnimationRepeat(Animation animation) {
314 |
315 | }
316 | });
317 | } else {
318 | closeFragment(fragment);
319 | }
320 | }
321 | isFirstClose = false;
322 | } else {
323 | closeFragment(fragment);
324 | }
325 |
326 | }
327 |
328 | @Override
329 | public void show(RootFragment fragment) {
330 | FragmentTransaction transaction = context.getSupportFragmentManager().beginTransaction();
331 | transaction.show(fragment).commit();
332 | View view = fragment.getView();
333 | if (view != null && next_in != null) {
334 | view.startAnimation(next_in);
335 | }
336 | }
337 |
338 | @IntDef({STANDARD, SINGLE_TOP, SINGLE_TASK,SINGLE_INSTANCE,KEEP_CURRENT})
339 | public @interface StackMode {
340 |
341 | }
342 |
343 | }
344 |
--------------------------------------------------------------------------------
/stacklibrary/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |