Currently listening for the back event from the Android device is only done in Activity by overriding the onBackPressed () function and implementing the necessary methods. What about Fragment? We cannot use the same method as in Activity because there is simply no function to let us override. So how to listen for events back from the system, the most commonly used method is the method below
1 2 3 4 | <span class="token function">requireActivity</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> onBackPressedDispatcher <span class="token punctuation">.</span> <span class="token function">addCallback</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Thực hiện implement các chức năng khi có sự kiện back</span> <span class="token punctuation">}</span> |
This approach can listen for the back event when the user presses the back button on the device at fragments that are directly interacting with the user, but on some devices with low firmware may not work and receive the back event. And if the Activity containing this Fragment together listens to the onBackPressed () event, it will easily lead to conflicts and the code will be difficult to manage.
With the above problems, in this article we would like to introduce a method of listening effectively to the onBackPressed () event to avoid some device problems, conflicts when listening to this event.
First, we can see that current Andoird application code is usually based on framework models such as MVP, MVVM, Clean Architect … We all build BaseActivity, BaseFragment … to implement special features. general calculation.
We will create the BaseFragment class that has the onBackPressed () function to listen for back events when needed, if any Fragment needs to handle this event just override it. The function has the following content
1 2 3 4 5 6 | <span class="token keyword">abstract</span> <span class="token keyword">class</span> BaseFragment <span class="token operator">:</span> <span class="token function">Fragment</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">open</span> <span class="token keyword">fun</span> <span class="token function">onBackPressed</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> Boolean <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Returning a Boolean value to signal whether the Fragment is handling the onBackPressed () event. We will see its meaning in the function below.
As the first part of the article said in Fragment there is no onBackPressed () method to override, so where do we listen for this event? The answer is from the Activity that contains these Fragments. And here is how we listen for event back from Activity and pass back to Fragment.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onBackPressed</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> handled <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token comment">// 1</span> supportFragmentManager <span class="token punctuation">.</span> fragments <span class="token punctuation">.</span> <span class="token function">forEach</span> <span class="token punctuation">{</span> fragment <span class="token operator">-></span> <span class="token keyword">if</span> <span class="token punctuation">(</span> fragment <span class="token keyword">is</span> NavHostFragment <span class="token punctuation">)</span> <span class="token punctuation">{</span> fragment <span class="token punctuation">.</span> childFragmentManager <span class="token punctuation">.</span> fragments <span class="token punctuation">.</span> <span class="token function">forEach</span> <span class="token punctuation">{</span> childFragment <span class="token operator">-></span> <span class="token comment">//2</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> childFragment <span class="token keyword">is</span> BaseFragment <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 3</span> handled <span class="token operator">=</span> childFragment <span class="token punctuation">.</span> <span class="token function">onBackPressed</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// 4</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> handled <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//5</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> handled <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//6</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">onBackPressed</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> e <span class="token operator">:</span> Exception <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">onBackPressed</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
We can understand the above function by performing the following steps:
- Create a handled variable to help confirm whether a Fragment needs to handle the onBackPressed event or not
- Run through the Fragments that this Activity manages
- Check whether Fragment is a child of BaseFragment or not
- If it is a child of BaseFragment then call Fragment’s onBackPressed function. It is on this line that will help to invoke the necessary functions when the user presses Back in that Fragment. If there is override onBackPressed function in Fragment, it returns true value, otherwise it returns false value by default.
- If Fragment has handle for Back event handling, then there is no need for Activity handling, return out of the function which avoids the collision when more parties listen to the Back event.
- If there are no Fragments to handle the Back event, use the Activity’s Back event
Based on this installation will help us easily manage pressing Back from the device, helping to avoid problems arising. Hope everyone can have better ways. The article here is to end