I want to make a persistent toolbar (with icons) which launches fragment activities into another fragment. I followed this tutorial, but I can't figure out how to turn the listview into a horizontal toolbar under the DetailFragment display.
I've tried to add buttons to the fragment, but there is no equivalent for setContentView for fragments. Also, Android doesn't seem to have any horizontal Listviews.
I looked at ActionBar as well, but that doesn't seem to be exactly what I want.
In general, how does one go about creating a persistent toolbar that launches activities in an Android app?
Any help is much appreciated!
Thanks to responders!
I realized that a tabhost that implements fragments solves my problem.
Here's a really good tutorial that I found. I hope it helps someone else.
http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/
ActionBar really does seem to be the right option here
Have a menu XML which sets Icons
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/action_frag1" android:title="#string/action_frag1"
android:icon="#android:drawable/ic_menu_add"
android:orderInCategory="450" app:showAsAction="ifRoom" />
<item android:id="#+id/action_frag2" android:title="#string/action_frag2"
android:icon="#android:drawable/ic_menu_revert"
android:orderInCategory="400" app:showAsAction="ifRoom" />
...
</menu>
Use it from Activity and respond to Presses
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.action_frag1:
//Here we change the fragment
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction tr = fm.beginTransaction();
tr.replace(R.id.container, Fragment1.newInstance());
tr.commit();
break;
case R.id.action_frag2:
... // same thing, but stay DRY
break;
}
return super.onOptionsItemSelected(item);
}
Related
I have a MainActivity and 3 different Fragments. The toolbar I created in MainActivity appears in all 3 Fragments I have. And I can switch between these Fragments using the button.
As an example;
binding.buttonSelectFile.setOnClickListener(v -> NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_ThirdFragment));
I want to create a similar behavior for the Toolbar item. For example, every time the user presses a "help" item defined as below, I want the application to navigate to the HelpFragment.
<menu
<!-- other items -->
<item
android:id="#+id/action_help"
android:orderInCategory="100"
android:title="#string/action_help"
app:showAsAction="never" />
</menu>
I tried to do something like this in the onCreate() method of the MainActivity class, purely as a guess.
binding.toolbar.getMenu().getItem(R.id.action_help).setOnMenuItemClickListener(item -> {
Navigation.findNavController(view).navigate(R.id.HelpFragment);
return true;
});
However, this method is of course not correct.
Is such use possible? Or should I follow another way to show the help screen to the user?
I am calling the setSupportActionBar() method for it
So, the action_help menu item is a part of the default optionsMenu. Then you need to override onCreateOptionsMenu() to inflate the menu, and onOptionsItemSelected to handle the click on the R.id.action_help menu item.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu); // replace "my_menu" with the name of your menu xml file
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.action_help) {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); // replace "nav_host_fragment" with the id of your navHostFragment in activity layout
navController.navigate(R.id.HelpFragment);
return true;
}
return super.onOptionsItemSelected(item);
}
I started my project with the template "Tabbed Activity" and am now trying to add an options menu. I have done this before with a blank activity and it worked fine. As far as I can tell I have done all the same steps, even as outlined by the documentation: https://developer.android.com/guide/topics/ui/menus#options-menu
When I run the app, nothing shows up. I would expect to see the 3 dots icon. I also tried adding icons to see if they would show up as actions. No luck. Here's what I've got in my MainActivity.java file:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu_layout, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.settingsMenuItem:
ShowSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void ShowSettings() {
// TODO show settings
}
}
And this is the options menu xml file which is "options_menu_layout.xml" located in the res/menu directory:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/settingsMenuItem"
android:icon="#drawable/baseline_settings_black_48"
android:title="#string/menu_option_settings"/>
</menu>
This seems to work on a blank activity, but not in this tabbed activity. Is there something I'm missing that is required to make these compatible?
show the xml, style and manifest files.
According to the documentation of onCreateOptionsMenu(),
"You must return true for the panel to be displayed; if you return false it will not be shown."
In your code sample, you have return super.onCreateOptionsMenu(menu);.
Is there a reason for calling the parent's class method as well? (The android developer guide code sample also does a return true;)
So I would first try to change onCreateOptionsMenu() to return true; to see if the options menu shows up and as a next step investigate the need to call the parent class' super.onCreateOptionsMenu(menu).
Turns out when using the template "Tabbed Activity" the manifest file uses a "NoActionBar" version of the theme.
I deleted the last part of this line:
android:theme="#style/Theme.ExampleApp.NoActionBar">
So it is this instead:
android:theme="#style/Theme.ExampleApp">
I'm learning the nav_graph feature and created one new fragment(AddNoteFragment). After editing in the navigation design UI, yes I can navigated to AddNoteFragment from NoteFragment, and there's a back icon(left-pointing arrow) on the topleft corner. I assume it's handled by the framework itself and it should be able to navigate me back if I click the button. See below screenshot.
But actually it has no action as I clicked. I searched for similar questions and tried override "onOptionsItemSelected" but no luck. One thing I haven't try yet is to add new tool bar in the fragment, because I think I don't have to. There should be a way to make the current button work. Shouldn't it have a default behavior defined? Else what's meaning of displaying the icon? This is a common bahavior and requirment.
Related code for your reference.
frangment "navigation_note" is one of the three bottom navigation tab fragments. You can see the I added the action for navigating to "addNoteFragment".
<fragment
android:id="#+id/navigation_note"
android:name="com.guo.ultrasecretary.ui.note.NoteFragment"
android:label="#string/title_note"
tools:layout="#layout/fragment_note" >
<action
android:id="#+id/action_navigation_note_to_addNoteFragment"
app:destination="#id/addNoteFragment" />
</fragment>
java code for addNoteFragment:
public class AddNoteFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View addNoteView = inflater.inflate(R.layout.fragment_note_add, container, false);
return addNoteView;
}
//tried but not working
/* #Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getActivity().onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}*/
}
layout of the fragment:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/textInputEditText2"
android:layout_width="293dp"
android:layout_height="94dp"
android:hint="Input note here"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="394dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
I'm using Android Studio 4.1 and running the code on AVD Nexus 6.
Please help to correct me.
To enable the back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
To work
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
Alternative way to work the button
public boolean onSupportNavigateUp(){
onBackPressed();
return true;
}
After googling little bit I found an answer for you.
As you said you have back button in actionBar in Fragment. But, you also said it isn't working. So, why android studio implement it?
Here is the answer for you.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
...
case android.R.id.home:
switch(currentFragment){
case FRAGMENT1:
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction
.replace(R.id.fragment_container, fragment2);
transaction.commit();
currentFragment = FRAGMENT_2;
return true;
default:
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction
.replace(R.id.fragment_container, fragment1);
transaction.commit();
currentFragment = FRAGMENT_1;
return true;
}
}
I found another useful link for you but, which may not be similar to your question.
Clicking the up button triggers the onSupportNavigateUp and as mentioned in the official docs,
If a parent was specified in the manifest for this activity or an activity-alias to it, default Up navigation will be handled automatically.
To implement the expected behaviour override onSupportNavigateUp instead of onOptionsItemSelected
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp()
}
Edit:
The Up and Back buttons are used to navigate up the hierarchy and the difference between them is
Back, the system button(left facing triangle), is used to navigate up the hierarchy and when in the home screen/fragment in your app and on pressing back, you will be navigated out of the app.
Up, the left-facing arrow in your appbar, is used to navigate up the hierarchy but it doesn't take you away from the app.
check out the docs for more info
I am having an issue where i have 2 items in my action bar (one 'refresh' button and one 'Save' Button, but for some reason they do not show, instead they are nested inside an options menu (3 dots). Would anyone know how to remove the 3 dots menu and display my 2 items? I have tried many things but ultimately I just end up removing all three items. Thanks in advance.
Here is my code
add_event_action.xml (this is my menu xml)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_refresh"
android:showAsAction="always"
android:icon="#drawable/ic_action_refresh"
android:title="Refresh"/>
<item
android:id="#+id/action_save"
android:showAsAction="always"
android:title="#string/save"/>
</menu>
Here is my Java class
public class RandomActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_events_list);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.add_event_action, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// action with ID action_refresh was selected
case R.id.action_refresh:
Toast.makeText(this, "Refresh selected", Toast.LENGTH_SHORT)
.show();
break;
// action with ID action_settings was selected
case R.id.action_save:
Toast.makeText(this, "Save selected", Toast.LENGTH_SHORT)
.show();
break;
default:
break;
}
return true;
}
}
If I understood correctly, you need two menu buttons in your toolbar.
This works for me, place it in your menu.xml:
<item
android:id="#+id/done"
android:title="#string/done"
app:showAsAction="always|withText"/>
Try to use app:showAsAction instead of android:showAsAction
To expand on the other answers somewhat:
When your activity extends from AppCompatActivity, your menu items should use app:showAsAction. When your activity does not (that is, when you're not using the AppCompat support libraries), your menu items should use android:showAsAction.
Documentation: http://tools.android.com/tips/lint-checks
AppCompatResource
Summary: Menu namespace
Priority: 5 / 10
Severity: Error
Category: Correctness
When using the appcompat library, menu resources should refer to the
showAsAction in the app: namespace, not the android: namespace.
Similarly, when not using the appcompat library, you should be using the android:showAsAction attribute.
I am very new to Android and Java programming. What I am trying to do is to get Actionbar with couple of tabs (11 in final). I have managed to install ActionBar Sherlock but then I am stuck with adding tabs to actionbar. From what I read it looks that also I would need to add separate Fragment for each tab. Is there a simple solution how to make that work.
You don't need to have a fragment per tab in the action bar. It should just be as simple as defining your menu in xml, then in your activity initialising the action bar with your menu.
For instance your menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/my_menu_item"
android:showAsAction="always|withText"
android:title="Tab name here"/>
</menu>
Then in your activity override onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.my_menu, menu);
return super.onCreateOptionsMenu(menu);
}
Then you'll need to override onOptionItemSelected to respond to when a tab is pressed:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.my_menu_item:
//do something
}
return super.onOptionsItemSelected(item);
}