Navigation with abstract base fragment - android

I have a setup like the navigation graph below. The 3 fragments in the middle are very similar and all extend a BaseFragment class.
What I would like to do is to make BaseFragment abstract, so that my navigation graph can be reduced to the figure below.
Is this even possible? It would drastically reduce the clutter of my navigation graph, because there will eventually be upwards of 20 children. However, I think this improvement would require me to instantiate an abstract class, which isn't possible.

No, a Fragment cannot be abstract.
The solution I decided upon was to have a helper class that stores the data I want to display in my Fragment. This helper class has a child for each of the original ChildFragment classes.
I can dynamically population my Fragment by simply reading the data stored in this helper class, thus allowing me to implement the second figure in the question.

Related

Does a BottomSheetFragment need ViewModel?

When working with Bottom Sheets and Dialog how to perform operation:
Use a SharedViewModel with fragment that created this bottom sheet?
Don't use a ViewModel at all?
Creating a separate ViewModel for the BottomSheet?
Any other approach that is best practice
If the bottom sheet/dialog is tightly bound to your "host" fragment (it shares some specific live data), and it is never going to be created from some other fragment, then it's OK to use a shared view model.
If the dialog is dead simple (like one input + 2 buttons), then the viewmodel might not be needed
If the dialog really needs a viewmodel (i.e. it fetches and displays some dynamic data), then a separate viewmodel makes sense
I'll go with the first approach by using a ShareViewModel, but if you understand the underlying layer, shared ViewModel is also ViewModel it's just a name convention we gave it to them.
Also sometimes it becomes tedious to write separate ViewModel to deal with fragments and bottom sheet where a MainActivity ViewModel can also do the exact same thing.
What I meant, in order to avoid complexity I use one view model per activity. Now, whenever I want to execute something in fragment or bottom sheet I just pass the view model in the constructor itself. Many people will think this is bad practice but it's not coz as per the concept of view model it will only be created and destroyed in accordance with the activity's lifecycle and only one instance will be created all along. Also by doing this, I can use Dependency injection with the fragment (I don't think that DI works with navigation component but I think you got my point).

Extending Fragment in Android

I have a created a Base Fragment. This Fragment contains 2 buttons on the right hand side.Now I want to created two more fragments which should be similar to the above base fragment but should have different control on the left hand side. For example FragmentA should have additional textView on left hand side. FragmentB should have textView and ImageButton on the left hand side. What is the good way to implement this ?
Should I add these control programmatically to the BaseFragment in onCreateView call of the extended FragmentA and FragmentB.
Or do I need to create different layout file for extended fragments which includes the base Fragment.In this case how would I inflate the base and extended fragment?
There're multiple ways to do that. So here're three of them I came up with:
Don't use inheritance. Instead add the reusable fragment as a nested fragment to FragmentA and FragmentB. With this approach it becomes a little difficult to send data to the nested fragment and listen to events from it.
Add an abstract method that inflates and configures an additional layout. Then subclass the fragment and override this method. This approach is pretty good if the inner layout is always positioned in the same way but may have different contents.
Add a layoutId parameter to the constructor of the base fragment class and pass if from subclasses. Override onViewCreated() in subclasses, call super implementation and perform subclass related configuration.

How to use activities with ViewPagerIndicator?

Let's say I have an Activity with a certain content. Now I need to create a new screen with tabs, so that the content of this activity will become the content of one of those tabs. I know I can do tabs with ViewPagerIndicator, for example. But, in order to do that, I need the screens to be implemented as Fragments. The problem is that the current implementation relies heavily on the Activity hierarchy (lots of calls to methods on the superclass, etc). So, I cannot simply make the current class extend Fragment. What other options do I have in this case?
Now I need to create a new screen with tabs, so that the content of this activity will become the content of one of those tabs
Having activities be the contents of tabs has been deprecated as a technique for nearly three years.
The problem is that the current implementation relies heavily on the Activity hierarchy (lots of calls to methods on the superclass, etc). So, I cannot simply make the current class extend Fragment.
Replace most of those "calls to methods on the superclass" to use getActivity(). as a prefix, where relevant.
What other options do I have in this case?
You could remove the activities entirely and rewrite your UI as custom views. This would be more work than converting them to fragments.
Or, you can just not do tabs.
So, I cannot simply make the current class extend Fragment.
That sounds like you have a huge Software architecture problem. In this case you may consider a complete rewrite (or more a copy & paste rewrite)
Normally it should be really straight forward to "convert" a Activity to a Fragment.
Fragment has nearly the same lifecycle callbacks:
Activity.onCreate() ---> Fragment.onCreateView() etc.
You can also access the parent Activity of the Fragment by calling Fragment.getActivity().
I don't know your code, but it should be definitely possible to "convert" Activities to Fragments.
You may split your activities code in own classes and inject them to the Fragment.
There is not really a alternative I could recommend you!
If you want tabs, use a ViewPager with Fragments. DO NOT USE OLD DEPRECATED STUFF like TabActivity

Referencing ViewPager and Fragments in another Android java file

I'm designing a similar interface to MathStep pictured below but my main activity already extends
public class MainActivity extends Activity implements TextWatcher
and Java doesn't have multiple inheritance.
In this program, you can ViewPager between Basic, functions and extra tabs. My program is not using tabs but I am swiping between fragments of buttons in a RelativeView.
How do I have part of my screen as a ViewPager, if I'm already extending Activity? Do I need to have a separate java file? How do I link the fragments that will contain the button sets back to the original activity?
I have been working on this with a friend for, I'm not kidding, 8 hours before we resorted to asking a question here. I have looked at this and this post and they were very helpful in understanding how ViewPager and Fragments work, but in all the examples they reference full paged ViewPagers, every time we attempted to create this scenario, something either wouldn't compile, or we weren't linking our XML correctly and code wasn't running... I've searched extensively for this answer and I hope I'm not the only one who has struggled with this so others can learn.
I'll admit, part of the confusion has been the learning curve but that's why I'm doing this, to learn.
How do I have part of my screen as a ViewPager, if I'm already extending Activity? Do I need to have a separate java file? How do I link the fragments that will contain the button sets back to the original activity?
All Fragments have a reference to the Activity via the getActivity() method, but you should only use it if you really need a handle to the context.
Inheritance is not required in any way whatsoever (technicality: other than for your activity, fragment, and FragmentPagerAdapter which must inherit from their respective parent classes...). The ViewPager itself can be included in the view heirarchy by referencing it from XML. The different fragments are displayed in the ViewPager by a FragmentPagerAdapter that you will have to implement yourself, this should be a separate class. If you want, it can be an inner static class, but, do not use an inner class. Keeping the scope organized by forcing dependencies to be passed through constructors will keep your code clean.
You should start by reading the ViewPager/Fragment related documentation on d.android.com. There is example code for these things and once you understand them individually everything will come together.

Design pattern for extending Android's activities?

While programming on Android, I end up writing a parent activity which is extended by several others. A bit like ListActivity. My parent activity extends Activity. if I intend to use a Map or a List, I can't use my parent activity as superclass - the child activity can only extend one activity obviously. As such I end up writing my parent activities with the same logic for Activity, ListActivity, MapActivity and so forth.
What am I looking for is some sort of trait functionality/design pattern which would help in this case. Any suggestions?
I really dislike ListActivity, MapActivity etc. Basically they are activities which simply add a single view element at the cost of some flexibility. By adding a MapView or ListView to your XML appropriately, you end up with the same thing which can extend an Activity derived superclass directly. So just don't use any of those SomethingActivity classes for the most part.
I've ended up having a base MyAbstractActivity extends Activity that incorporates shared logic and a MyAbstractListActivity extends MyAbstractActivity that mimics ListActivity (inflates layout.R.id.list, layout.R.id.empty, etc.; not much going on there).
I'm using a delegate with all the shared functionality. This enables me to have all the shared functionality in one single class for all the different activities.
All my activities extend their special activity and then implement a common interface. The problem with this approach is that I need to implement all the methods defined in the interface and call the matching method in the delegate object. This code at the moment amounts to 30 duplicate lines of code and I think that is not that much of a problem.

Categories

Resources