DRY options menus on Android - android

I'm learning about creating Options Menus for Android apps.
In the guide it has the following tip for staying DRY with menus:
Tip: If your application contains
multiple activities and some of them
provide the same Options Menu,
consider creating an activity that
implements nothing except the
onCreateOptionsMenu() and
onOptionsItemSelected() methods. Then
extend this class for each activity
that should share the same Options
Menu. This way, you have to manage
only one set of code for handling menu
actions and each descendant class
inherits the menu behaviors.
This appears problematic. If the Activitys that need to share the same options inherit from different classes, what should my OptionsMenuActivity inherit from? I read that Java does not support multiple inheritance, so how do you get around this?

Your activity that has the code for options menu should extend the Activity class.
public class YourRootActivity extends Activity {
// Any other stuff that you want for all activities
public boolean onCreateOptionsMenu(Menu menu){
// your main options menu
}
}
Now for the classes that need this menu, make them extend the activity that we created above.
class Activity1 extends YourRootActivity {
}
In case you want slight modifications in your options menu in the subclasses, you can overwrite the onCreateOptionsMenu method in those classes.

Related

Android: how to open a ListPreference dialog from outside PreferenceActivity/PreferenceFragment?

I've created a settings menu for my app based on PreferenceFragment, and would like to access the settings dialog(s) from elsewhere in the app without having to open the settings menu.
My settings menu has this:
and I want to show the same dialog when I click this menu item from the main activity:
The main Activity has one ListFragment which is where all of the UI handling code is. Neither is a PreferenceActivity or PreferenceFragment.
I just want to invoke the same PreferenceFragment object to get to the dialog, otherwise I'd have to write custom code to handle the preference changes manually, which I'd like to avoid.
I thought adding the PreferenceFragment to the FragmentManager in the main Activity would properly instantiate it, but it doesn't seem to work.
From my menu handler code for the "Sort" option:
SettingsFragment fragment = (SettingsFragment) getFragmentManager().findFragmentByTag(SettingsActivity.FRAGMENT_TAG);
// first run case
if (fragment == null) {
fragment = SettingsFragment.newInstance(getActivity());
getFragmentManager().beginTransaction().add(fragment, SettingsActivity.FRAGMENT_TAG).commit();
}
CustomListPreference listPref = (CustomListPreference) fragment.findPreference(SettingsFragment.KEY_PREF_SORTORDER);
listPref.show(); // invokes showDialog(null)
This crashes with a NullPointerException on listPref, which shows the PreferenceFragment was not properly initialized.
Is there any way to achieve this effect, or do I have to write the functionality as an AlertDialog and manually handle the Preference changes?
I think you'll have to write this functionality yourself outside of the Preference classes.
Preference, PreferenceActivity, and PreferenceFragment were all
designed to work together to provide a consistent UIX for android
apps. As such it's recommended to use them together as they were
intended.
You can't directly replicate the UI of PreferenceActivity or
PreferenceFragment outside of those two classes in a regular activity
because the UI is built from Preference objects, not View objects like
regular Activities. So if you want that particular UI you'd have to
try and duplicate it using custom Views.
https://discussions.udacity.com/t/way-to-do-listpreference-outside-of-settings-menu/45473

android common OnItemClickListener and separate button listeners

In my app I have around 12 activities. The first layout of my activity is a list view. By clicking each list it gets redirected to other activities. I have implemented the Listview with OnItemClickListener and is working good.
In all the other 11 activities, I have a common title bar with a logo and a button named as S. When the user clicks on the S button, I am showing the same list of items in the First activity of my app, within the current activities by splitting the page. Now instead of writing a separate OnItemClickListener for each activity, how to write it once and use in multiple activities?
In the same way I have placed 3 button in include layout and I am using this in various activities, how to write a separate common button action, it can be used in multiple activities.
While #SamirMangroliya's method works, this is an alternate method you can use, and the one I've been using for a while.
Create your listener in another class file (say, MyClickListener.java):
public class MyClickListener implements OnItemClickListener {
// This can be OnClickListener, OnTouchListener, whatever you like.
// Implement your method here:
public onItemClick(...) {
// Your selection process, etc.
}
}
Then in each of your Activity objects, all you have to do is:
myObject.setOnItemClickListener(new MyClickListener());
how to write a separate common button action, it can be used in multiple activities.
you should create one Activity(called BaseActivity),
class BaseActivity extends Activity{
#Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
Button btn1 = (Button)findViewById(r.id.btn1);
.
.
.
//now setonclickListner here...
}
}
then extends it ...class MyActivity extends BaseActivity
It sounds like you should implement ActionBar navigation. For a more detailed description about how to do it the Android way, see the Design guide. To support versions of Android between 1.6 and 2.3, link in the ActionBarSherlock library.

How do I create common code for parts of Android activities?

In my application there are 14 activities. Out of that 9 activity contains custom title bar and tab pane. so here I need to write this common code at one place instead of redundant code in each activity that contain custom title bar and tab pane code (i.e layout and it's activity specific code)
What are the possible ways to do this?
The common way is:
Create a super class called, for instance, CommonActivity which extends Activity
Put the boilerplate code inside that class
Then make your activities extend CommonActivity instead of Activity:
Here a simple example:
public class CommonActivity extends Activity{
public void onCreate(Bundle b){
super.onCreate(b);
// code that is repeated
}
protected void moreRepeatitiveCode(){
}
}
And your current activities:
public class AnActivity extends CommonActivity{
public void onCreate(Bundle b){
super.onCreate(b);
// specific code
}
}
Hmm.. Common code doesn't always need to be in Activity class but just regular class. Than we could call those methods according to our needs referring to the common code class.
Am I right with this example?
Of course in case we need it like Activity, above proposal would work perfectly if we take care of Activity lifecycle and we don't forget to add it to manifest file.
In general Activities should just create UI, handle events occurrences and delegate business logic and/or other actions to the other components in our App.
Cheers

Android UINavigationController-like feature

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

How to add a menu to MapActivity?

I've got an app using MapActivity.onCreate() to initialize the map and show it on screen. Now I would like to add a menu to my app. From what I've found out I can't add a menu from MapActivity and need to use Activity (correct me if I'm wrong).
Now I have no idea how to "initialize" the map from my Activity-class.
And how would I have to fix the views, will I wrap my activity-layout around my Map-layout?
MapActivity extends a regular Android Activity, so there's nothing irregular you should need to do to create a menu.
Just override the onCreateOptionsMenu method, as shown in the developers' guide.
MapActivity extends Activity, so you should be able to add a menu.
MapActivity is a subclass of Activity, and thus you do it the same way as in any normal Activity (instructions here). I've been able to successfully create menus the same way in MapActivity as in a normal Activity.
Make sure that it doesn't extend from FragmentActivity but from AppCompatActivity!
If that's the case, the onCreateOptionsMenu method will be called and you are able to overwrite it like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu); //"menu_main" is the XML-File in res
return super.onCreateOptionsMenu(menu);
}

Categories

Resources