I am currently building an app, and have decided to implement a navigation drawer for ease of use. currently, nearly all my classes extend activity, however, looking at the navigation drawer examples, they all use fragments. do I have to use fragments for this, or can i keep my classes as activities?
I am only worried, as I have nearly finished the app, and have been told that they do not use the same methods.
No. you can acheive with Activity. Not required to use Fragment.
http://developer.android.com/training/implementing-navigation/nav-drawer.html
Read this reference , this has detail about Drawer layout.
Create a Base class called DrawerBaseActivity which extends Activity. Add all the drawer code to DrawerBaseActivity and Make all your custom activity extends DrawerBaseActivity.
The link reference ask you to replace the fragment on drawerItemClick. But instead of fragment replace create intent to an activity and start your activity.
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
switch (position)
{ case 1 :
// start your respective activity
}
}
}
To keep the rich UI feature you would be better off using fragments.
If you have trouble calling methods you can always call
getActivity( ).TheMethod ( )
That will use the parent activity to call the relevant methods for you.
Related
I'm newbie with MvvmCross. I'm developing an app using Mvx v6.0.1.
I want to make a kind of stepper using fragments (specifically 4 fragments or 4 steps), all of these fragments are embedded into an main activity. The main activity layout has a button, when I tap these button fragment is switched to the next step. I have created one viewmodel for each fragment and one more for the main activity. The problem I have is that I need to get some values from each step and pass to the next step.
I'm trying to share only one viewmodel for every view (fragments and activity). Is there any way to achieve this?
If yes, How can I distinguish each steps/fragments for navigate across them?
I was trying to set same viewmodel to Activity and fragment:
//Activity code
public class AttendanceActivity : BaseActivity<AttendanceViewModel>
{
protected override int ActivityLayoutId => Resource.Layout.activity_attendance;
//some logic
}
//Fragment code
[MvxFragmentPresentation(ActivityHostViewModelType = typeof(AttendanceViewModel),
FragmentContentId = Resource.Id.attendance_content_frame,
AddToBackStack = true)]
public class AttendanceFragmentSetpOne : BaseFragment<AttendanceViewModel>, IOnClickListener
{
protected override int FragmentLayoutId => Resource.Layout.fragment_attendance_step_one;
//Some logic
}
But when I make this, the app never pass from splash screen.
I hope explain myself and somebody help me with this "problem".
Thanks in advance.
I'm aware the View structure for Android is completely different (ie. Activities instead of View Controllers) but I need to create a Navigation Bar that persists between views.
Is the best way really to have just one single Activity and then a lot of Fragments?
If so, has this implementation already been done somewhere else that I can use? It seems like something that would come up a lot as I've seen numerous Android apps do this.
I made a Framework (github) to provide a hierarchical navigation pattern, with animations to provide sense of navigation, rather than launching new Activities every time.
Here's how to use it:
Add the framework to your project as a Module
Add a new Java class in your project ("File - New - Java Class").
Note: If you are editing the Activity.java file that provides you the template, delete all its implementations and leave it empty.
Make it extend NavigationActivity
Implement all the NavigationActivity abstract methods
(in Android Studio if you click Alt + insert and select implement - methods all the function definitions are automatically generated).
public class NavigationTest extends NavigationActivity{
#Override
public Fragment firstFragment() {
//return the first fragment that will be shown
}
#Override
public Boolean showBackButtonInFirstFragment() {
//show back button already in the first Fragment
//set to True if this activity is called by another Activity
//the back button will then pop back to the previous Activity
}
#Override
public Boolean showMasterDetailLayoutInTablets() {
//set to false if you don't want a master-detail layout in tablets
}
}
Presenting a new Fragment
You can present a new fragment (with a nice animation) by calling the pushFragment method from NavigationActivity.
public void pushFragment(Fragment newFragment, animationType animation, boolean showAsDetailFragmentIfPossible)
newFragment (Fragment): New Fragment that will be presented
animation (animationType): Animation type enum: RIGHT_TO_LEFT, BOTTOM_TO_TOP, FLIP
showAsDetailFragmentIfPossible (boolean): If set as True, the user is in a Tablet, and you are using a master-detail layout, the Fragment will be shown in the detail Fragment (the panel in the right)!
Since you can access the activity from any Fragment with the getActivity() method, you can show a new Fragment from the currently displaying Fragment.
For example you can put this code within a button click listener:
NextFragment f = new NextFragment();
NavigationActivity nav =((NavigationActivity)getActivity());
nav.pushFragment(f,NavigationActivity.animationType.RIGHT_TO_LEFT,false);
You don't have to worry about implementing the back button behaviour. This is handled automatically by the NavigationActivity class.
I am more familiar with iOS development than Android and I am wondering if all code should be written in an Activity rather than having a "model" class.
I have a couple screens each with a few checkboxes and I want them all to behave the same on click, I am trying to figure out how I would do this without writing repeating code in each activity. Thanks!
No you should not. If you are familiar with java, think of an activity as a extension of main with OO added.
In your particular example you can create a class with a method like:
<MethodName>(View <checkboxClickedName>){ //your code here }. and then add this to the checkbox in the XML android:onClick="<MethodName>", you may need the full package path (e.g. com.example.app.)
Note: if some of the commands/objects you need are only available within an activity you should create this in an calss that extends Activity or preferably within the running activity.
You could have a base class that extends activity that contains the methods that you want executed on click (either implemented or abstract). Use this new base class instead of activity when making new activities. In the layout xml, you can set the onclick of each checkbox to be the method in the base activity you want executed.
The best practice would be to use a single activity and switch fragments as if they were your screens. Then, the activity could simply implement the listener interface that the fragments would re-use.
Since you have multiple activities this becomes a little bit harder. To really re-use a single listener, I can think of a single (not so beautiful) option. Create a static listener and lazy load it:
public class MainActivity extends Activity {
private static View.OnClickListener sCheckboxClickListener;
public static View.OnClickListener getCheckboxClickListener() {
if (sCheckboxClickListener == null) {
sCheckboxClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Work with v
}
};
}
return sCheckboxClickListener;
}
}
And in each of your activities call:
findViewById(R.id.checkbox1)
.setOnClickListener(MainActivity.getCheckboxClickListener());
I'm wondering why are the Fragments communicating through the container Activity are called reusable.
From: http://developer.android.com/guide/components/fragments.html I know that:
You should design each fragment as a modular and reusable activity
component. That is, because each fragment defines its own layout and
its own behavior with its own lifecycle callbacks, you can include one
fragment in multiple activities, so you should design for reuse and
avoid directly manipulating one fragment from another fragment.
Let's take an example; I have a DateSetFragment which contains two buttons; first button fires TimePickerDialog (FragmentDialog) which allows user to pick an hour and the second one DatePickerDialog (FragmentDialog) which allows user to pick a day. At the end gathered data should be sent back to the DateSetFragment.
According the: http://developer.android.com/training/basics/fragments/communicating.html:
All Fragment-to-Fragment communication is done through the associated
Activity. Two Fragments should never communicate directly.
communication between fragments should be done via interfaces through the container activity. Given that I should send my collected data from both Fragment Dialogs to the container activity and then from the Activity back to the DateSetFragment. I don't see how this make my DateSetFragment reusable and modular in any way. Doing so I have to implement fragment interfaces and some crucial logic in my container Activity which makes it connected with it.
The question is; Is it wrong in this situation if Fragment Dialogs will communicate directly with the DateSetFragment ?
It is "modular" because those interfaces are well defined and explicitly implemented by the hosting activity.
Anywhere you drop that fragment in, if the activity implements the callback interface defined by the fragment events the activity can choose what to do depending on what environment the fragment is attached in.
Example,
DatePickerFragment extends Fragment {
public interface DatePickerFragmentEventListener {
public void onDateSelected(DateTime dt);
}
}
Activity1 extends Activity implements DatePickerFragmentEventListener {
DatePickerFragment mDatePickerFragment;
OtherFragment mFragment2;
#Override
public void onDateSelected(DateTime dt) {
mFragment2.setSomeViewsText(dt.toString());
}
}
Activity2 extends Activity implements DatePickerFragmentEventListener {
DatePickerFragment mDatePickerFragment;
#Override
public void onDateSelected(DateTime dt) {
SharedPrefClient c = SharedPrefClient.getInstance();
c.setExpirationDateTime(dt);
}
}
I have a dateTimePickerFragment (or whatever), in one activity I have 2 fragments, when you change the date on the picker I want to update the other fragment's text view to display that date. In another activity I might use that exact same callback to write the chosen date to SharedPreferences.
The point is that the Fragment is a contained piece of UI interaction, and certain events it will notify the enclosing Activity of what just happened to it, so that the activity dictates that the result of an action on the fragment does to either other fragment or the application itself. There is no reason to implement a custom fragment for each and every situation.
On the iPhone I use a Navigation Controller to push and pop Views from. Very handy.
Is there an equivalent in Android?
This is an old question, but I believe the answer has changed. It is now possible to imitate the Nav stack in iOS in android using Fragments.
http://developer.android.com/reference/android/app/Fragment.html
Basically instead of jumping from Activity to Activity you instead stay in one Activity that controls the display, organization, and animation of Fragments which each contain their own behavior much like the NavController / UIViewController model in iOS.
It is also backwards compatible as a static library so you can implement it on pre-Honeycomb devices.
Strategies for Honeycomb & backward compatibility
Typically in android, each view is displayed in its own Activity. You can read about activities in the application fundamentals documentation. To move to a new Activity, or view, you use an intent.
If you haven't done so yet, I'd highly recommend reading through those introductary android docs. They aren't too long, and do a good job of explaning the basic program structure.
I made a Framework (github) to provide a hierarchical navigation pattern, with animations to provide sense of navigation, rather than launching new Activities every time.
Here's how to use it:
Add the framework to your project as a Module
Add a new Java class in your project ("File - New - Java Class").
Note: If you are editing the Activity.java file that provides you the template, delete all its implementations and leave it empty.
Make it extend NavigationActivity
Implement all the NavigationActivity abstract methods
(in Android Studio if you click Alt + insert and select implement - methods all the function definitions are automatically generated).
public class NavigationTest extends NavigationActivity{
#Override
public Fragment firstFragment() {
//return the first fragment that will be shown
}
#Override
public Boolean showBackButtonInFirstFragment() {
//show back button already in the first Fragment
//set to True if this activity is called by another Activity
//the back button will then pop back to the previous Activity
}
#Override
public Boolean showMasterDetailLayoutInTablets() {
//set to false if you don't want a master-detail layout in tablets
}
}
Presenting a new Fragment
You can present a new fragment (with a nice animation) by calling the pushFragment method from NavigationActivity.
public void pushFragment(Fragment newFragment, animationType animation, boolean showAsDetailFragmentIfPossible)
newFragment (Fragment): New Fragment that will be presented
animation (animationType): Animation type enum: RIGHT_TO_LEFT, BOTTOM_TO_TOP, FLIP
showAsDetailFragmentIfPossible (boolean): If set as True, the user is in a Tablet, and you are using a master-detail layout, the Fragment will be shown in the detail Fragment (the panel in the right)!
Since you can access the activity from any Fragment with the getActivity() method, you can show a new Fragment from the currently displaying Fragment.
For example you can put this code within a button click listener:
NextFragment f = new NextFragment();
NavigationActivity nav =((NavigationActivity)getActivity());
nav.pushFragment(f,NavigationActivity.animationType.RIGHT_TO_LEFT,false);
You don't have to worry about implementing the back button behaviour. This is handled automatically by the NavigationActivity class.
There are thee basic types in Android to show UI in Android:
View
Fragment
Activity
Google IO 2018 introduced Navigation component which should make life easier. It is a wrapper under a standard mechanisms.
Here you can find NavGraph which looks like storyboard and NavController which help to navigate to destination