I don't understand why in this case is not recongnizing my menu item.
I have another activities with similar code and it's working fine, but in this case i'm having NPE.
Layouts
General (activity_completas)
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
tools:context=".activities.CompletasActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/content_breviario_general" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_breviario_general
<?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"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<include
android:id="#+id/include"
layout="#layout/tv_zoomable" />
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintBottom_toTopOf="#+id/include"
app:layout_constraintEnd_toStartOf="#+id/include"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
Menu
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:context=".activities.BreviarioActivity">
<item
android:id="#+id/item_voz"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="#drawable/ic_play"
android:visible="false"
android:title="#string/leer"
app:showAsAction="ifRoom" />
<item
android:id="#+id/item_calendario"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="#drawable/ic_calendar_toolbar"
android:title="#string/all_calendar"
app:showAsAction="ifRoom" />
</menu>
Java code
Relevant parts only for this case:
public class CompletasActivity extends AppCompatActivity {
//...
private Menu menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_completas);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
showData();
}
private void showData() {
sbReader = new StringBuilder();
//I fill sbReader correctly
if (sbReader.length()>0) {
menu.findItem(R.id.item_voz).setVisible(true); //******NPE here*******
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
getMenuInflater().inflate(R.menu.toolbar_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if (tts != null) {
tts.cerrar();
}
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.item_voz:
String html = String.valueOf(Utils.fromHtml(sbReader.toString()));
String[] textParts = html.split(SEPARADOR);
tts = new TTS(getApplicationContext(), textParts);
return true;
case R.id.item_calendario:
Intent i = new Intent(this, CalendarioActivity.class);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
super.onBackPressed();
if (tts != null) {
tts.cerrar();
}
}
}
Error
java.lang.NullPointerException: Attempt to invoke interface method
'android.view.MenuItem android.view.Menu.findItem(int)' on a null
object reference
I do the same thing in another activities and i don't have NEP. What's happening here?
You are getting null point exception because your menu isn't instantiated. As i can see, your are calling showData before creating the menu. Call showData in the onCreateMenu. This should solve your problem.
Related
enter image description hereAs you can see I have added 6 item in navigation drawer but on clicking Logout it is not triggered. And sorry for bad code format. I'm new here.
#Override public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_log_out) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.nav_profile:
break;
case R.id.nav_wallet:
break;
case R.id.nav_search:
break;
case R.id.nav_about_us:
break;
case R.id.nav_contact_us:
break;
case R.id.nav_log_out:
Intent intent = new Intent(this,LogIn.class);
FirebaseAuth.getInstance().signOut();
startActivity(intent);
}
This is my XML file for menu item. The id are the same I declared in the XML file. Log out in action bar is working fine but it is not working in Navigation Drawer.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_profile"
android:icon="#drawable/ic_person_black_24dp"
android:title="Profile" />
<item
android:id="#+id/nav_wallet"
android:icon="#drawable/ic_attach_money_black_24dp"
android:title="EasyFare Wallet" />
<item
android:id="#+id/nav_search"
android:icon="#drawable/ic_directions_bus_black_24dp"
android:title="Search Bus" />
<item
android:id="#+id/nav_about_us"
android:icon="#drawable/ic_folder_shared_black_24dp"
android:title="About Us"/>
<item
android:id="#+id/nav_contact_us"
android:icon="#drawable/ic_email_black_24dp"
android:title="Contact Us" />
<item
android:id="#+id/nav_log_out"
android:icon="#drawable/ic_exit_to_app_black_24dp"
android:title="Log Out" />
</group>
</menu>
activity file with DrawerLayout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
You have to add brackets for case in logout..
case R.id.nav_log_out:
{
Intent intent = new Intent(this,LogIn.class);
FirebaseAuth.getInstance().signOut();
startActivity(intent);
}
Could you include the code in your activity's onCreate?
One possibility is that you forgot to register your activity as the listener for the navigation view.
mNavigationView.setNavigationItemSelectedListener(this)
Clicking on some other item, let's say the second one, gets this item triggered?
If yes add a break statement in your logout case and also create a default case.
You could also try replacing your code with the following sample.
#SuppressWarnings("StatementWithEmptyBody")
#Override public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.nav_profile:
break;
case R.id.nav_wallet:
break;
case R.id.nav_search:
break;
case R.id.nav_about_us:
break;
case R.id.nav_contact_us:
break;
case R.id.nav_log_out:
{
Intent intent = new Intent(this,LogIn.class);
FirebaseAuth.getInstance().signOut();
startActivity(intent);
break;
}
DrawerLayout drawer;
drawer = findViewById(R.id.THE_ID_OF_YOUR_DRAWER);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
Also make sure that in your OnCreate , OnStart or onResume you include the following
DrawerLayout drawer;
drawer = findViewById(R.id.THE_ID_OF_YOUR_DRAWER);
I will provide you with a code i use for a project of mine and try to see if you find any differences that would explain the fact your code does not work.
AnnouncementsActivity.java
.
.
.
.
public class AnnouncementsActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_announcements);
.
.
.
.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer;
drawer = findViewById(R.id.drawer_layout_astiko);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
toolbar.setNavigationIcon(R.mipmap.ic_toolbar);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
.
.
.
.
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_first_item) {
if(prev_activity_routes){
Intent intent = new Intent(this,RoutesActivity.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
startActivity(intent);
}else{
if(isAstiko){
Intent intent = new Intent(this,TicketIssuanceActivityAstiko.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
startActivity(intent);
}else{
Intent intent = new Intent(this,TicketIssuanceActivity.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
startActivity(intent);
}
}
} else if (id == R.id.nav_second_item) {
Intent intent = new Intent(this,DefinedTicketsActivity.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
intent.putExtra("PreviousActivityRoutes",prev_activity_routes);
intent.putExtra("isAstiko",isAstiko);
startActivity(intent);
}
.
.
.
.
}else if (id == R.id.nav_eighth_item) {
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
}
DrawerLayout drawer;
drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
}
ActivityAnnouncements.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_announcements"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="500dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:theme="#style/NavigationDrawerStyle"
app:headerLayout="#layout/my_nav_header"
app:menu="#menu/my_drawer" />
</android.support.v4.widget.DrawerLayout>
app_bar_announcements.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
tools:context="com.e_analysis.AlphaPro.MobileTicketing.AnnouncementsActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/MyTheme">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="65dp"
android:background="?attr/colorPrimary"
app:popupTheme="#style/MyTheme"/>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_announcements" />
</android.support.design.widget.CoordinatorLayout>
content_announcements.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:layout_marginBottom="-0dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:orientation="vertical"
android:background="#color/colorPrimary"
android:gravity="fill"
tools:context="com.e_analysis.AlphaPro.MobileTicketing.AnnouncementsActivity"
tools:showIn="#layout/app_bar_announcements">
.
.
.
.
</LinearLayout>
my_drawer.xml in the menu subfolder
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_first_item"
android:icon="#mipmap/ic_printer_black"
android:title="#string/nav_first_item_value"/>
<item
android:id="#+id/nav_second_item"
android:icon="#mipmap/ic_tune_vertical"
android:title="#string/nav_second_item_value" />
.
.
.
.
<item
android:id="#+id/nav_eighth_item"
android:icon="#mipmap/ic_logout"
android:title="#string/nav_eighth_item_value" />
</group>
</menu>
my_nav_header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:background="#drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
.
.
.
.
</LinearLayout>
This code is working (not as it is ofcourse) so try to do some cross-checking with it and see what you are missing. Most probably it will be something easy to overlook and frustrating when you find out. Good luck!
I have a Bottom Navigation View with 4 items.
I wish to set the items in the middle of each bottom navigation view button and I have found a method but it works only when the application starts.
After I select another item, every icon moves up and I don't know why they are not keeping their position.
public class MainActivity extends AppCompatActivity{
private Toolbar mToolbar;
private BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.customToolbar);
setSupportActionBar(mToolbar);
setTitle("");
mToolbar.setNavigationIcon(R.mipmap.back_icon);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
BottomNavigationViewShiftDisable.disableShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.profile:
fragment = new FirstFragment();
break;
case R.id.friends:
fragment = new SecondFragment();
break;
case R.id.circle:
fragment = new ThirdFragment();
break;
case R.id.settings:
fragment = new ForthFragment();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, fragment);
transaction.commit();
setMenuIconsInMiddle(bottomNavigationView);
return true;
}
});
bottomNavigationView.setSelectedItemId(R.id.profile);
}
/**
* This method is used to set margins for all the icons in the menu that is used in the
* bottom navigation view.
* #param navigationView an instance of the Bottom navigation view that holds the menu with
* the icons.
*/
public void setMenuIconsInMiddle(BottomNavigationView navigationView){
BottomNavigationMenuView menuView = (BottomNavigationMenuView)navigationView.getChildAt(0);
for(int index = 0; index <menuView.getChildCount(); index++){
final View iconView = menuView.getChildAt(index).findViewById(android.support.design.R.id.icon);
final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)iconView.getLayoutParams();
layoutParams.setMargins(0,50,0,0);
navigationView.requestLayout();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.example.hermes.profilescreen.MainActivity">
<include layout="#layout/custom_toolbar"/>
<include layout="#layout/bottom_navigation"/>
</RelativeLayout>
bottom_nav_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="#+id/profile"
android:enabled="true"
android:icon="#drawable/ic_people_outline_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/friends"
android:enabled="true"
android:icon="#drawable/ic_person_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/circle"
android:enabled="true"
android:icon="#drawable/ic_panorama_fish_eye_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/settings"
android:enabled="true"
android:icon="#drawable/setting_white"
app:showAsAction="ifRoom"
android:title=""
/>
</menu>
bottom_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frame_layout"
android:layout_above="#+id/bottom_navigation"
>
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/light_black"
app:itemBackground="#drawable/set_backgorund"
app:itemIconTint="#color/item_state"
app:menu="#menu/bottom_nav_main"
/>
</RelativeLayout>
call setMenuIconsInMiddle on a thread. try this:-
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
//your code here
...
...
...
//Looper.getMainLooper() runs on main thread
new Handler(Looper.getMainLooper()).post(new Runnable(){
#Override
public void run() {
setMenuIconsInMiddle(bottomNavigationView);
}
});
return true;
}
});
this is working for me...
I've set my app so it changes to a different layout when the device is orientated, which works fine but now my action buttons are not being displayed. Do I need to create a new app bar xml file for the landscape orientation? Here is my code, appreciate any help.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
if (savedInstanceState != null) {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
setContentView(R.layout.activity_main_landscape);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
menu_main.xml - I want this to be used in both landscape and portrait orientations, meaning I want the same action buttons on both.
<menu 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"
tools:context="com.example.james.task02b.MainActivity">
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_search_white_24dp"
android:title="#string/action_search"
app:showAsAction="ifRoom"/>
<item
android:id="#+id/action_delete"
android:icon="#drawable/ic_delete_white_24dp"
android:title="#string/action_delete"
app:showAsAction="ifRoom"/>
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
activity_main_landscape.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
android:fitsSystemWindows="true"
tools:context="com.example.james.task02b.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="This is the landscape layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/textView2" />
</RelativeLayout>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
I'm using PreferenceFragment that I launch from the NavigationDrawer. In the preferenceFragment I show the toolbar. All looks good, but when I press the arrow in the toolbar to come back it doesn't work. I can see in the log this:
D/ViewRootImpl: ViewPostImeInputStage ACTION_DOWN
But don't do nothing. The only way to come back is press button back in the device
Some help will be appreciated.
This is my code:
PreferenceFragment:
public class AnPreferenceActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pref_with_actionbar);
getFragmentManager().beginTransaction()
.replace(R.id.content_frame, new SettingsPreference())
.commit();
}
public static class SettingsPreference extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
}
}
}
Layout xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:navigationContentDescription="#string/abc_action_bar_up_description"
app:navigationIcon="?attr/homeAsUpIndicator"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:title="#string/action_settings" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/appbar" />
</RelativeLayout>
In onCreate() of your fragment first you should declare it has option Menu:
setHasOptionsMenu(true);
Then you should handle your own menu:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// close fragment here
getActivity().getFragmentManager().popBackStack();
return true;
default:
break;
}
return false;
}
If you need more Menu create new menu item:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.fragment_menu, menu);
return true;
}
Accessing to toolbar from fragment is not good approach you should handle it in better way. There are lots of thread about this issue out there. (in fact Activity should handle Toolbar behaviour)
I have read a lot of similar topics but none of the solutions works to me. I'm getting the MenuItem normaly, but when i try to get its view, I get a null view. I already tried put the code in the onPrepareOptionsMenu, get the view with MenuItemCompat, and other sutff.
activity_main.xml, where is the toolbar
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
...
tools:context=".activities.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"
android:elevation="4dp"/>
</android.support.design.widget.AppBarLayout>
...
</android.support.design.widget.CoordinatorLayout>
menu_main.xml
<menu 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"
tools:context=".activities.MainActivity">
<item
android:id="#+id/action_location"
android:orderInCategory="0"
android:icon="#android:drawable/ic_dialog_map"
android:title="Localização"
app:showAsAction="ifRoom" />
...
</menu>
onCreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
...
}
onCreateOptionsMenu method
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem menuItem = menu.findItem(R.id.action_location); // here is fine, found the item
View view = menuItem.getActionView(); // here is null
return super.onCreateOptionsMenu(menu);
}
Familiarize yourself with what a ActionView really is.
Just by assigning menuItem, you receive all the attributes about it, including the title, "Localização."
If you're trying to get the result of click "action_location," then onOptionsItemSelected may be the method call you need.