onOptionsItemSelected listener not working - android

I'm developing an android app and I have an issue with the options menu. The onOptionsItemSelected() method is not called when the menu item is pressed, I'm using an actionLayout so, as many questions posted in this site, I've set my own listener. Nothing seems to work and I can't see how my solution differs from others.
Here it's my code:
On MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d("Listener", "Created");
getMenuInflater().inflate(R.menu.main, menu);
for (int i = 0; i < menu.size(); i++) {
final MenuItem item = menu.getItem(i);
if (item.getItemId() == R.id.action_cart) {
View itemChooser = item.getActionView();
if (itemChooser != null) {
itemChooser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Listener", "Clicked1");
onOptionsItemSelected(item);
}
});
}
}
}
return super.onCreateOptionsMenu(menu);
}
#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.
switch (item.getItemId()) {
case R.id.action_cart:
Log.d("Listener", "Clicked");
CartFragment newFragment = new CartFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
On menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:title="cart"
android:id="#+id/action_cart"
app:showAsAction="always"
app:actionLayout="#layout/badge_layout"/>
</menu>
On layout/badge_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:addStatesFromChildren="true">
<com.joanzapata.iconify.widget.IconButton
android:layout_width="44dp"
android:layout_height="44dp"
android:textSize="24sp"
android:textColor="#ffffff"
android:background="#mipmap/ic_cart"
android:id="#+id/badge_icon_button"/>
<TextView
android:id="#+id/badge_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#id/badge_icon_button"
android:layout_alignLeft="#id/badge_icon_button"
android:layout_alignStart="#id/badge_icon_button"
android:text="10"
android:paddingEnd="12dp"
android:paddingRight="0dp"
android:paddingLeft="0dp"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="13sp"
android:textStyle="bold"
android:background="#drawable/badge_circle"/>
</FrameLayout>
As for the logs, "Listener: Created" is the only one printed.
I've already tried the solutions of several related questions like this one and this one. The actionlayout represents a badge inside a shopping cart and I know it has something to do with that since before the actionlayout it worked.
Any help is appreciated. Thanks.

remove the onOptionsItemSelected method and change the oncreateOptionsMenu to
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.action_cart);
if (item != null) {
item.getActionView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Listener", "Clicked");
}
});
}
return true;
}
and the layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true">
<com.joanzapata.iconify.widget.IconButton
android:layout_width="44dp"
android:layout_height="44dp"
android:clickable="false"
android:textSize="24sp"
android:textColor="#ffffff"
android:background="#mipmap/ic_cart"
android:id="#+id/badge_icon_button"/>
<TextView
android:id="#+id/badge_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#id/badge_icon_button"
android:layout_alignLeft="#id/badge_icon_button"
android:layout_alignStart="#id/badge_icon_button"
android:text="10"
android:paddingEnd="12dp"
android:paddingRight="0dp"
android:paddingLeft="0dp"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="13sp"
android:textStyle="bold"
android:background="#android:color/holo_red_dark"/>
</RelativeLayout>
What really solved the problem was android:clickable="false" on com.joanzapata.iconify.widget.IconButton

Related

SearchView in activity toolbar and filter to fragment

I have given SearchView in activity with custom toolbar and filter data goes to fragment. When I click on the search icon,toolbar size increasing. Navigation bar is used in that activity,may be it is issue?.
It is working with separate activity without navigation bar.vb
Here is my code:
Activity.xml :
<android.support.design.widget.AppBarLayout
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="wrap_content"
app:elevation="5dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
style="#style/Toolbar"
app:contentInsetEnd="5dp"
app:contentInsetLeft="15dp"
app:contentInsetRight="5dp"
app:contentInsetStart="15dp"
app:theme="#style/AppTheme.Toolbar"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:contentInsetStartWithNavigation="15dp"
app:titleTextColor="#color/colorWhite"
tools:targetApi="lollipop">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
android:layout_gravity="start"
android:gravity="center"
android:text=""
android:textAllCaps="false"
android:textColor="#color/colorWhite"
android:textSize="16sp"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<TextView
android:id="#+id/toolbar_student_details"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="end"
android:gravity="center"
android:text=""
android:textAllCaps="false"
android:textColor="#color/colorWhite"
android:textSize="16sp"
tools:ignore="RelativeOverlap" />
<Spinner
android:id="#+id/toolbar_student_details_spinner"
android:spinnerMode="dropdown"
android:layout_width="120dp"
android:backgroundTint="#color/colorWhite"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="end"
android:textAllCaps="false"
android:textColor="#color/colorWhite"
android:textSize="16sp"
tools:ignore="RelativeOverlap"
android:visibility="gone"
>
</Spinner>
<ImageView
android:id="#+id/admin_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:contentDescription="#string/app_name"
android:visibility="gone" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
Fragament code:
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup
container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView=
inflater.inflate(R.layout.fragment_staff_fragment_admin,
container, false);
setHasOptionsMenu(true);
ButterKnife.bind(this, rootView);
return rootView;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getBaseActivity().getMenuInflater().inflate(R.menu.menu_main,
menu);
SearchView searchView;
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager)getBaseActivity().
getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
assert searchManager != null;
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getBaseActivity().getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
// listening to search query text change
searchView.setOnQueryTextListener(new
SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// filter recycler view when query submitted
mAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
// filter recycler view when text is changed
mAdapter.getFilter().filter(query);
return false;
}
});
}
#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_search) {
return true;
}
return super.onOptionsItemSelected(item);
}
You should listen to changes in the Activity and send the result to your Fragment as your SearchView is inside the Activity ( in the custom Toolbar). One of the problems you may be facing is that the searchview is null when you are calling it.
I recommend doing this through your ViewModel if you are using Android Architecture Components and the MVVM pattern as follows:
Listen to changes in your Activity
// listening to search query text change
searchView.setOnQueryTextListener(new
SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
//filter the data in step 2
return false;
}
#Override
public boolean onQueryTextChange(String query) {
// filter data in step 2
return false;
}
});
Send the query to your ViewModel function to filter the data
inside your Activity:
...
#Override
public boolean onQueryTextSubmit(String query) {
//filter the data
viewModel.filterData(query);
return false;
}
...
inside your ViewModel:
public List<String> listOfData = getListOfData();
public LiveData<List<String>> searchResults = new MutableLiveData(listOfData);
// filter list of data when query submitted
public void filterData(String query) {
//filter outside of your RecyclerView Adapter through your listOfData variable
searchResults.value = getFilter().filter(query);
}
public LiveData<List<String>> getSearchResults() {
return searchResults;
}
by setting the result on your LiveData through searchResults.value you can listen to it change directly from your Fragment, thus completing the communication between your Activity and your Fragment RecyclerView through this variable in step 3.
Observe the ViewModel variable inside your Fragment & update the Adapter
inside your Fragment
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel.getSearchResults().observe(this, { searchResults->
Log.w("onActivityCreated()", "new search list received :" +searchResults)
mAdapter.updateList(searchResults)
listItemsAdapter.notifyDataSetChanged()
});
}
With these changes, you're filtering from the Activity SearchView and sending the results to the Fragment RecyclerView which should work. If you are using another pattern, the important thing is to send the query from your Activity to your Fragment instead of listening in your Fragment only.
If you aren't using these yet, I recommend taking a look at AAC with MVVM. You can find more info in the Android Developers Documentation about these concepts.
Hope this helped, good luck.

Clicking hamburger icon on Toolbar does not open Navigation Drawer

I have a simple android.support.v7.widget.Toolbar and all I am trying to do is to open a NavigationDrawer by pressing the "hamburger" icon in the top left corner. The "hamburger" button is visible, and when I start to pull from the left I see the animation on the button but pressing the button does not open/close the NavigationDrawer as I expect. I have followed the [Google Documentation][1] and still am not able to figure this out. Sorry for any confusion, below is the simplified code I am currently attempting to use:
public class MainActivity extends AppCompatActivity implements
View.OnClickListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("NICK", "button button button..................");
}
});
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
NavigationView n = (NavigationView) findViewById(R.id.nav);
mDrawerLayout.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.d("NICK", "button button button..................");
}
});
//mDrawerLayout.setDrawerListener(mDrawerToggle);
n.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
////.......
}
mDrawerLayout.closeDrawers(); // CLOSE DRAWER
return true;
}
});
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START); // OPEN DRAWER
Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.drawer, menu);
return true;
}
}
}
And as it is I do not get any of the log debug statements when running.
This is essentially the issue I have: https://stackoverflow.com/a/26636045/1489990. I've followed this and it just doesn't work.
It is my understanding that setNavigationOnClickListener is called when the hamburger icon is pressed, and this is where I am focusing my efforts is to get the event handled properly because when I press the button I do not get my log statement. Let me know if this idea is incorrect. https://developer.android.com/reference/android/widget/Toolbar.html#setNavigationOnClickListener(android.view.View.OnClickListener)
My Layouts:
ActivityMain.xml
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/d"
android:background="#drawable/home_wall">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:layout_marginBottom="10dp"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:layout_marginTop="25dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" />
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="#+id/drawer"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:layout_width="fill_parent"
android:layout_height="200dp"
android:id="#+id/imageView"
android:src="#drawable/trans2"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:paddingBottom="300dp" />
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/d8"
android:layout_alignParentTop="true"
android:layout_alignLeft="#+id/imageView"
android:layout_alignStart="#+id/imageView"
android:paddingTop="0dp">
<Button
android:layout_width="75dp"
android:layout_height="50dp"
android:text="Gallery"
android:id="#+id/save_button"
android:background="#dd2c00" android:textColor="#fff"
android:layout_below="#+id/Purchases"
android:layout_toRightOf="#+id/start_button"
android:layout_toEndOf="#+id/start_button" />
<Button
android:layout_width="125dp"
android:layout_height="50dp"
android:text="Store"
android:id="#+id/Purchases"
android:background="#ff6e40" android:textColor="#fff"
android:layout_above="#+id/instructions_button6"
android:layout_toLeftOf="#+id/start_button"
android:layout_toStartOf="#+id/start_button"
android:layout_marginBottom="98dp" />
<Button
android:layout_width="75dp"
android:layout_height="50dp"
android:text="Help"
android:id="#+id/instructions_button6"
android:background="#dd2c00" android:textColor="#fff"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="#+id/start_button"
android:layout_toStartOf="#+id/start_button"
android:layout_marginLeft="5dp"
android:layout_marginBottom="10dp" />
<Button
android:layout_width="75dp"
android:layout_height="300dp"
android:text="Start"
android:id="#+id/start_button"
android:background="#ff3d00"
android:textColor="#fff"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp" />
<Button
android:layout_width="125dp"
android:layout_height="50dp"
android:text="Achievements"
android:id="#+id/Scores"
android:background="#ff6e40" android:textColor="#fff"
android:layout_alignTop="#+id/Purchases"
android:layout_toRightOf="#+id/start_button"
android:layout_toEndOf="#+id/start_button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to the quiz!"
android:id="#+id/textView"
android:textColor="#fff"
android:textSize="20dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="70dp" />
<!-- sign-in button -->
<com.google.android.gms.common.SignInButton
android:id="#+id/sign_in_button"
android:layout_width="110dp"
android:layout_height="50dp"
android:layout_above="#+id/start_button"
android:layout_centerHorizontal="true"
android:visibility="visible" />
<!-- sign-out button -->
<Button
android:id="#+id/sign_out_button"
android:layout_width="125dp"
android:layout_height="wrap_content"
android:text="Sign Out"
android:visibility="invisible"
android:background="#dd4b39"
android:textColor="#fff"
android:layout_alignTop="#+id/sign_in_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="160dp" />
</RelativeLayout>
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
android:id="#+id/nav"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
Drawer.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_menu"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:title="Google Play Games"
android:icon="#drawable/ic_local_airport_white_48dp">
<menu>
<item
android:id="#+id/Sign_in_drawer"
android:icon="#drawable/games_controller_grey"
android:title="Sign in" />
<item
android:id="#+id/ach"
android:icon="#drawable/games_achievements"
android:title="Achievements" />
</menu>
</item>
<item android:title="Start a Quiz"
android:icon="#drawable/ic_local_airport_white_48dp">
<menu>
<item
android:id="#+id/quizStart25"
android:icon="#drawable/ic_local_airport_white_48dp"
android:title="25 Questions" />
<item
android:id="#+id/quizStart10"
android:icon="#drawable/ic_local_airport_white_48dp"
android:title="10 Questions" />
</menu>
</item>
<group
android:checkableBehavior="single">
<item
android:id="#+id/gallery"
android:icon="#drawable/ic_photo_library_white_48dp"
android:title="Gallery" />
<item
android:id="#+id/stats"
android:icon="#drawable/ic_toc_white_48dp"
android:title="Statistics" />
<item
android:id="#+id/store"
android:icon="#drawable/ic_shop_white_48dp"
android:title="Store" />
<item
android:id="#+id/settings"
android:icon="#drawable/ic_settings_white_48dp"
android:title="Settings" />
<item
android:id="#+id/about"
android:icon="#drawable/ic_info_white_48dp"
android:title="About" />
</group>
<item android:title="Support">
<menu>
<item
android:id="#+id/help_drawer"
android:icon="#drawable/ic_help_white_48dp"
android:title="Help" />
<item
android:id="#+id/report"
android:icon="#drawable/ic_report_problem_white_48dp"
android:title="Contact Developer" />
<item
android:id="#+id/GPlusCommunity"
android:icon="#drawable/btn_g_white_normal"
android:title="Google+ Community" />
</menu>
</item>
In your ActivityMain.xml, the toolbar is outside of the DrawerLayout. That's the problem. If you want Toolbar to interact with DrawLayout, Toolbar needs to be a child of DrawerLayout.
To fix the problem, make DrawerLayout the root of your activity. Here's the documentation. The relevant quote is:
To add a navigation drawer, declare your user interface with a
DrawerLayout object as the root view of your layout. Inside the
DrawerLayout, add one view that contains the main content for the
screen (your primary layout when the drawer is hidden) and another
view that contains the contents of the navigation drawer.
So basically, structure your ActivityMain.xml to be something like this:
<android.support.v4.widget.DrawerLayout ...>
<RelativeLayout ...>
<android.support.v7.widget.Toolbar .../>
<!-- Your other content goes here -->
</RelativeLayout>
<android.support.design.widget.NavigationView .../>
</android.support.v4.widget.DrawerLayout>
That should take care of the problem.
Override onOptionsItemSelected method and use below
if(item.getItemId() == android.R.id.home){ // use android.R.id
mDrawerLayout.openDrawer(Gravity.LEFT);
}
You need to sync the drawer toggle:
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
EDIT: That code is working for me (copied from your post)
public class TempActivity extends AppCompatActivity {
private ActionBarDrawerToggle mDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.temp);
setupDrawer();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
private void setupDrawer() {
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.my_drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
}
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<RelativeLayout
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:text="DRAMER MENU" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
But if you are using the new NavigationView, then you don't need the toggle etc. Here is a good example how to use it.
I fixed it by giving openable which is drawerLayout to navigateUp function.
More info navigateUp Doc
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.host_fragment)
return NavigationUI.navigateUp(navController,drawer_layout)
}
If it helps somebody, to me it happened the same because of the stupid error of calling setSupportActionBar(toolbar) two times. Just call it once in onCreate method and never again. My mistake was I called it later in another method.
Use ActionBarDrawerToggle and implement public boolean onOptionsItemSelected(MenuItem item)
Toolbar DOES NOT have to be within a DrawerLayout, it's not likely to be the cause of this issue. toggle.onOptionsItemSelected(item) looks for the ID of the item selected and if it is android.R.id.home then the drawer's visibility is toggled. Thus Toolbar, or any View that creates a Home MenuItem, can be placed anywhere in your layout.
Within your activity:
ActionBarDrawerToggle toggle;
private void setupDrawerToggleInActionBar() {
// assuming a Toolbar has been initialized in your onCreate
this.setSupportActionBar(toolbar);
// setup the action bar properties that give us a hamburger menu
ActionBar actionBar = this.getSupportActionBar();
if(actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
// the toggle allows for the simplest of open/close handling
toggle = new ActionBarDrawerToggle(this,
drawerLayout,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
// drawerListener must be set before syncState is called
drawerLayout.setDrawerListener(toggle);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// This is required to make the drawer toggle work
if(toggle.onOptionsItemSelected(item)) {
return true;
}
/*
* if you have other menu items in your activity/toolbar
* handle them here and return true
*/
return super.onOptionsItemSelected(item);
}
Simply call function onOptionsItemSelected(MenuItem menuItem) of ActionBarDrawerToggle class on activity options menu managing function like below.
mDrawerToggle= new ActionBarDrawerToggle(activity, drawerLayout, R.string.nav_drawer_accessbility_drawer_open,
R.string.nav_drawer_accessbility_drawer_close);
#Override
public boolean onOptionsItemSelected(final android.view.MenuItem item) {
navigation().getOptionsMenuInflater(this).closeSearchView();
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this behavior.
mDrawerToggle.onOptionsItemSelected(item);
return super.onOptionsItemSelected(item);
}
OR
override onOptionsItemSelected of activity like below
public boolean onOptionsItemSelected(MenuItem item) {
if (item != null && item.getItemId() == android.R.id.home) {
toggle();
}
return super.onOptionsItemSelected(item);
}
private void toggle() {
if (mDrawerLayout.isDrawerVisible(GravityCompat.START)) {
mDrawerLayout.closeDrawer(GravityCompat.START);
} else {
mDrawerLayout.openDrawer(GravityCompat.START);
}
}
For the drawer toggle you need to set "display home as up" to false:
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
As i have no specific answer to your problem, i want to suggest a completely different approach:
In my projects im using the Material Drawer developed by Mike Penz.
Its looks really nice, is easy to implement, and there is not much you have to worry about.
So if you cant find a solution for your problem, you could give it a try.
While accepted answer here works alright however, as they say "Prevention is better than cure".. Adding mDrawerToggle.syncState(); in onPostCreate and onConfigurationChanged() wroks much better as answerd by #mbmc above:
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
After a lot of different problems I found a way to make it work putting Toolbar Widget inside AppBarLayout.
Be sure that there is no other layout on top of widget toolbar!
<androidx.drawerlayout.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/drawable_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
xmlns:android="http://schemas.android.com/apk/res/android">**
<androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_page_toolbar"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:background="#color/colorPrimaryDark"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>**
.... YOUR LAYOUT ...
</RelativeLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_marginBottom="3dp"
app:menu="#menu/navigation_menu">
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
Idk why...but changing return value to false rather than true fixed the ham Icon for me. on onOptionItemSelected override method
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if(item.getItemId() == R.id.logout){
ParseUser.logOut();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
Toast.makeText(this, "Logout Successful!", Toast.LENGTH_SHORT).show();
} else if(item.getItemId() == R.id.action_settings){
Toast.makeText(this, "No setting to update! Will be available later...", Toast.LENGTH_SHORT).show();
}
return true; // here change this to false
}
If none of the above answer works, please cross check again,
First you need to call setSupportActionBar(toolbar); and then do the necessary work for nav drawer. I wasted my 2 hours because of this silly mistake.
I had the same problem. However, it did not occur on all fragments. It occurred on one particular fragment.
Firstly, please follow #hungryghost 's answer mentioned above. Then do the following.
Adding the following piece of code helped the drawer open on click of the hamburger icon. It worked flawlessly for me. Thank you very much. :) My sincere apologies if this isn't the right way.
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int itemId = item.getItemId();
if(itemId == android.R.id.home){
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
I have found a simple solution to this problem is to call the setSupportActionBar(toolbar) method before the navigation drawer functions.

Why does OnTabSelected get called after adding a fragment via FragmentTransaction

So I have this code :
public void openSearch() {
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
if(mSearchFragment == null) {
mSearchFragment = SearchFragment.newInstance("Search");
t.add(android.R.id.content,mSearchFragment);
} else {t.show(mSearchFragment); }
t.commit();
}
I call openSearch from here:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
boolean returnValue = false;
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
}
}
after openSearch() runs.. onTabSelected is called immediately after. Why is this?
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction ft) {
If you need mroe information please let me know. I included only the pieces I thought were relevant to lessen the chatter. What's even crazier is that the first time I run this onTabSelected gets selected, but if i navigate my app and run openSearch again the 2nd and consecutive times the onOptionsItemSelected won't be called. it's only the initial time
Edit:
This is the main content view and I'm just supplying fragments for the viewPager. The Layouts for each fragment is the same, a FrameLayout with one LinearLayout child.
<LinearLayout
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#android:color/holo_orange_dark"
android:visibility="gone" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is the search view" />
</LinearLayout>
<android.support.v4.view.ViewPager
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Facebook Login Button Appears Over Navigation Drawer

I'm trying to implement the facebook login tutorial, along with a navigation drawer. I managed to create the drawer successfully, but when I tried it on the emulator, the facebook login button appears over the drawer, even though it is part of another layout (fragment).
Here's my MainActivity layout:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#ff939393"
android:dividerHeight="1dp"
android:background="#ff333333"/>
</android.support.v4.widget.DrawerLayout>
And here is my fragment layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/facebook_login_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1">
<com.facebook.widget.LoginButton android:id="#+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center|center_horizontal"
android:layout_marginTop="40dp" />
<TextView
android:id="#+id/textView"
android:layout_width="312dp"
android:layout_height="101dp"
android:text="#string/please_login_with_facebook"
android:padding="10dp"
android:textStyle="bold"
android:typeface="serif"
android:singleLine="false"
android:layout_weight="0.13"
android:textAlignment="center"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:layout_marginTop="150dp" />
<Button android:id="#+id/connection_settings_button"
android:layout_width="188dp"
android:layout_height="wrap_content"
android:text="#string/turn_on_internet_button"
android:layout_gravity="center"
android:layout_marginTop="36dp"
android:visibility="invisible" />
</FrameLayout>
And this is the MainActivity class:
public class MainActivity extends ActionBarActivity {
private String[] mDrawerTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private FacebookLoginFragment fbFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
mDrawerTitles = getResources().getStringArray(R.array.nav_drawer_items);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, mDrawerTitles));
// Set the list's click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
fbFragment = new FacebookLoginFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, fbFragment)
.commit();
} else {
// Or set the fragment from restored state info
fbFragment = (FacebookLoginFragment) getSupportFragmentManager().findFragmentById(android.R.id.content);
}
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mDrawerTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I'll post more code if necessary. Unfortunately I still don't have the reputation to post images, but here is my problem. Any help is very appreciated!
When you FragmentTransaction.replace your FacebookLoginFragment, don't use the id android.R.id.content. Instead use the id of the FrameLayout that acts as the content of your DrawerLayout, which in this case is R.id.content_frame.

android facebook UserSettingsFragment not working

I am pretty new to android and facebook plugin.trying to follow the below steps as mentioned in facebook
developer site.
https://developers.facebook.com/docs/android/scrumptious/authenticate/
Go to Step 3.
I followed it without missing any steps.
However, I do not see a menu at the bottom when i am logged in.Any help?
Below is the snippet of important codes and xml.
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// only add the menu when the selection fragment is showing
if (fragments[SELECTION].isVisible()) {
if (menu.size() == 0) {
Log.d("onPrepareOptionsMenu","Yes");
settings = menu.add(R.string.settings);
}
return true;
} else {
menu.clear();
settings = null;
}
return false;
}
Following the main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.punit.xxx.SelectionFragment"
android:id="#+id/selectionFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="com.punit.xxx.SplashFragment"
android:id="#+id/splashFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="com.facebook.widget.UserSettingsFragment"
android:id="#+id/userSettingsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I tried to put some log and found that OnPrepareotionsMenu is never called.
Remove the onPrepareOptionsMenu(Menu menu) from your code.
Add *item
android:id="#+id/action_logout"
MyNews:showAsAction="never"
android:actionProviderClass="android.support.v7.widget.ShareActionProvider"
android:orderInCategory="10"
android:title="#string/logout"/*
Note: replace * with < or >.
Add #Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.action_logout:
showSettingsFragment();
return true;
}
return false;
}
public void showSettingsFragment(){
showFragment(SETTINGS, true);
}
It worked for me.

Categories

Resources