Drawer menu icon disappears after applying a custom view to ActionBar - android

I have a drawer menu icon before adding a custom action bar view, in this custom view, it's a just a imageView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/bell_icon"
android:layout_gravity="right"
android:layout_marginRight="#dimen/double_spacer"
android:id="#+id/ic_notif"/>
</LinearLayout>
and in the fragment that will have this custom view applied, I have the following lines:
#Override
public void onStart() {
super.onStart();
ActionBar actionBar = getActivity().getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
LayoutInflater mInflater = LayoutInflater.from(getActivity());
View customView = mInflater.inflate(R.layout.action_bar_custom_layout, null);
setHasOptionsMenu(true);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM|ActionBar.DISPLAY_SHOW_HOME|ActionBar.DISPLAY_SHOW_TITLE);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(R.string.plan_member_services);
actionBar.setCustomView(customView);
actionBar.setDisplayShowCustomEnabled(true);
ImageView img_notification = customView.findViewById(R.id.ic_notification);
img_notif.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
System.out.println("*** icon clicked ***");
}
});
if(isShowIcon){
img_notifi.setVisibility(View.VISIBLE);
}else{
img_notifi.setVisibility(View.GONE);
}
...
With above code, I am able to see the icon of the action bar defined in "AndroidMenifest.xml":
<application
android:name=".MyApp"
android:allowBackup="true"
android:allowClearUserData="false"
android:fullBackupContent="#xml/backup"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/MyActionBarTheme">
and also I'm able to see the title, but the menu icon for the drawer menu is gone! What have I missed?

I found when I put those codes in the activity instead of the fragment, the drawer menu icon appears when the fragment loaded.

Related

Fill horizontal Custom View in action bar

I want to display to use a custom view on my action bar that completely covers the action bar (width match parent)
But my custom view does not cover the entire width of the action bar.
public class MyActivity extends AppCompatActivity {
private ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.data_entry_screen);
setActionBar();
}
private void setActionBar() {
actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
View abView = actionBar.getCustomView();
LayoutInflater inflator = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutParams layout = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
View v = inflator.inflate(R.layout.action_bar, null);
actionBar.setCustomView(v, layout);
actionBar.setDisplayShowCustomEnabled(true);
}
action_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/mvp_logo"
android:layout_alignParentRight="true" />
</RelativeLayout>
I have referred the following links:
How to display custom view in ActionBar?
Manually inflating custom view yields different layouts for ActionBar custom view
Android center custom view in actionbar
Android: How to center a component in a custom view in action bar?
Thanks
The Toolbar might be better for you, but as a note, this is breaking the design guidelines and will make your app not 'fit' in the Android ecosystem, that area is usually where the context menu is found and most users will have learned that behaviour.
You can fix the behaviour by removing content insets as follows
View myLogo = mInflater.inflate(R.layout.actionbar_custom, null);
getSupportActionBar().setCustomView(myLogo);
((Toolbar) myLogo.getParent()).setContentInsetsAbsolute(0,0);
If you've already changed to Toolbar you can fix it in the XML for the custom view
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"

Toggle button not working for navigation drawer

I am implementing a Navigation Drawer for my android application. I got the drawer to work by dragging from the side, but the home/toggle button on the action bar doesn't change to the icon I want and doesn't respond to clicks, thou the onDrawerClosed and onDrawerOpened methods defined in it are called.
My code is as follows:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/loadingFragment"
android:name="com.whostr.clients.android.LoadingFragment" />
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/eventFragment"
android:name="com.whostr.clients.android.EventDisplayFragment"/>
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/emptyFragment"
android:name="com.whostr.clients.android.EmptyView"/>
<!-- Listview to display slider menu -->
<ListView android:id="#+id/left_drawer"
android:layout_width = "240dp"
android:layout_height = "match_parent"
android:layout_gravity = "start"
android:choiceMode = "singleChoice"
android:dividerHeight = "1dp"
android:divider = "#android:color/transparent"
android:background="#111"
/>
And in the activity I have the following code:
#Override
public void onCreate(Bundle savedDataInstace)
{
super.onCreate(savedDataInstace);
setContentView(R.layout.eventdisplay);
fm = getSupportFragmentManager();
//get fragments by id
fragments[EVENT_VIEW]= fm.findFragmentById(R.id.eventFragment);
fragments[LOADING] = fm.findFragmentById(R.id.loadingFragment);
fragments[EMPTY_VIEW] = fm.findFragmentById(R.id.emptyFragment);
menuList = getResources().getStringArray(R.array.menuArray);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawwer_open, R.string.drawer_closed)
{
/*
* Called when a drawer has settled in a completely closed state
*/
public void onDrawerClosed(View view)
{
Log.d("drawerToggle", "Drawer closed");
super.onDrawerClosed(view);
getActionBar().setTitle(R.string.app_name);
invalidateOptionsMenu(); //Creates call to onPrepareOptionsMenu()
}
/*
* Called when a drawer has settled in a completely open state
*/
public void onDrawerOpened(View drawerView)
{
Log.d("drawerToggle", "Drawer opened");
super.onDrawerOpened(drawerView);
getActionBar().setTitle("NavigationDrawer");
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
//Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, menuList));
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position,
long id) {
Log.d("navigationDrawer", "Clicked on an item");
}
});
FragmentTransaction transaction = fm.beginTransaction();
//Hide the event view
transaction.hide(fragments[EVENT_VIEW]);
transaction.hide(fragments[EMPTY_VIEW]);
transaction.commit();
AsyncTask<String, Void, EventResponseCollection> task = new GetEventsNearByAsyncTask().execute();
try {
if(task != null)
events = task.get().getItems();
} catch (InterruptedException | ExecutionException e) {
Log.d("viewEvent", "Error when retrieving task details " + e.getMessage());
}
if(events == null)
{
//show create your own event fragment
changeFragment(EMPTY_VIEW);
}
else
{
Log.d("viewEvent", "I have " + events.size());
//show proper fragment with the first event displayed
currentEvent = events.get(eventIndex);
((EventDisplayFragment) fragments[EVENT_VIEW]).updateFragment(currentEvent);
changeFragment(EVENT_VIEW);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
Log.d("onOptionsItemSelected", "In the on item select");
//Pass the event to ActionBarDrawerToggle, if it returns
//true, then it has handled the app icon touch event
if(mDrawerToggle.onOptionsItemSelected(item))
{
Log.d("onOptionsItemSelected", "Clicked on action bar item");
return true;
}
//Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
Does anyone have any suggestion on what I can do? I've tried all solutions I found online to make this work, but apparently I'm out of luck and nothing seems to be working :(
You have to add something like this in your Activity
#Override
public boolean onOptionsItemSelected(android.view.MenuItem item) {
return drawerToggle.onOptionsItemSelected(item);
}
This worked for me, its almost like the previous post
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
} }
Ok, it was a small omission from my side, I forgot to include the following 2 lines of code:
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
in the onCreate method.
I've faced the similar issue.
I hope this answer can help somebody facing similar problem.
Check for openDrawer attribute in your drawer layout
tools:openDrawer="start"
Also, check for drawer lock mode in your Activity and remove it, if you have accidentally locked drawer.
//drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
Years later but anyway..... it could help anyone, when you have a layout with a Drawerlayout, the Drawer assumes that the First child is the view to overlap when shown and the Second child is the navigation panel. So in your case you could do something like...
enter code here
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/loadingFragment"
android:name="com.whostr.clients.android.LoadingFragment" />
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/eventFragment"
android:name="com.whostr.clients.android.EventDisplayFragment"/>
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/emptyFragment"
android:name="com.whostr.clients.android.EmptyView"/>
</RelativeLayout>
<!-- Listview to display slider menu -->
<ListView android:id="#+id/left_drawer"
android:layout_width = "240dp"
android:layout_height = "match_parent"
android:layout_gravity = "start"
android:choiceMode = "singleChoice"
android:dividerHeight = "1dp"
android:divider = "#android:color/transparent"
android:background="#111"
/>
So in that way, the Drawer knows that the RelativeLayout is the view to overlap and the ListView is the left panel you want.
Also you have to do in the java code all the things you know.. setting up the toolbar, setting up the drawer indicating the toolbar, setting up the toogle etc... it's all in the comments.

Remove Action bar Icon with custom view and show home up button

I am able to add custom view in actionbar. My application is supporting from version 2.3 so I had used ActionbarActivity. Now my query is to remove app icon from the actionbar and only to have home up icon i.e back image.
I had tried lots of option that I found while searching. But its not working with custom view.
edit
ActionBar actionBar = getSupportActionBar();
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, Gravity.RIGHT
| Gravity.CENTER_VERTICAL);
View customNav = LayoutInflater.from(this).inflate(
R.layout.custom_action_view, null); // layout which contains
actionBar.setCustomView(customNav, lp);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setBackgroundDrawable(new ColorDrawable(Color
.parseColor("#a40404")));
Help me out with this issue. Thanks in advance.
The up button is tied to home icon. That's why it's called "home as up" setDisplayHomeAsUpEnabled(true).
So you can't show up arrow with disabled "home" icon.
But you can make a View that looks like it in your custom View.
For example:
<LinearLayout
android:id="#android:id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:background="?attr/actionBarItemBackground"
android:paddingRight="5dp">
<!-- this will show tha up arrow -->
<ImageView
android:id="#+id/up"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="?attr/homeAsUpIndicator"/>
<!-- place here any View that will be clickable along with "up" arrow (in this example, it's an icon) -->
<ImageView
android:id="#+id/home_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/action_bar_icon_vertical_padding"
android:layout_marginBottom="#dimen/action_bar_icon_vertical_padding"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/app_icon"/>
</LinearLayout>
Where
android:src="?attr/homeAsUpIndicator"
Will set the up arrow based on your theme.
android:background="?attr/actionBarItemBackground"
Will set the blue selection background for pressed state
Now set an OnClickListener to a layout with arrow
View customNav = LayoutInflater.from(this).inflate(
R.layout.custom_action_view, null);
customNav.findViewById(android.R.id.home).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick() {
// up button clicked
}
});
actionBar.setCustomView(customNav, lp);
To remove Actonbar Icon:
Just add actionBar.setDisplayUseLogoEnabled(false); this line in oncreate() method:
To enable back button:
you need to extends SherlockActivity and insert this code in oncreate() method:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Handle back button action using this code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// do your action here when click on back button showing on action bar
onBackPressed();
}
}

How to centre text in Sherlock Action Bar with icon and sliding menu

I am trying to implement an Action Bar on an Android Activity which implements Jeremy Feinstein's sliding menu and actionbarSherlock. The issue I am facing is to centre align the title text in the Action Bar. My action bar has a menu icon named "icon_sliding_menu" on the left of the text to activate the left menu sliding action.
I have used this example to write attached below. However, when I add the line "getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);" to try to customize my view, my title just goes away, and I don't see any text at all.
ActionBar when the line mentioned above is not in the code:
ActionBar when the line mentioned above is written in the code:
How can I align the text to centre? I am attaching my code below.
actionbar.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center" >
<TextView
android:id="#+id/action_bar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="18sp" />
</LinearLayout>
HomeActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
final View actionBarLayout = LayoutInflater.from(this).inflate(
R.layout.actionbar, null);
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setCustomView(actionBarLayout);
getSupportActionBar().setTitle("Home");
getSupportActionBar().setHomeButtonEnabled(true);
initSlidingMenu();
}
private void initSlidingMenu() {
slidingMenu = new SlidingMenu(this);
slidingMenu.setMode(SlidingMenu.LEFT_RIGHT);
slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
slidingMenu.setAboveOffset(50);
slidingMenu.setBehindOffset(150);
slidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
slidingMenu.setOnOpenListener(new OnOpenListener() {
#Override
public void onOpen() {
getSupportActionBar().setTitle("Menu");
}
});
slidingMenu.setOnCloseListener(new OnCloseListener() {
#Override
public void onClose() {
getSupportActionBar().setTitle("Home");
}
});
slidingMenu.setSecondaryOnOpenListner(new OnOpenListener() {
#Override
public void onOpen() {
getSupportActionBar().setTitle("Current Trip");
}
});
// Add left menu
mTransaction = this.getSupportFragmentManager().beginTransaction();
slidingMenu.setMenu(R.layout.left_menu);
mTransaction.commit();
// Add right menu
mTransaction = this.getSupportFragmentManager().beginTransaction();
slidingMenu.setSecondaryMenu(R.layout.right_menu);
mTransaction.commit();
}
#Override
protected void onResume() {
super.onResume();
getSupportActionBar().setIcon(R.drawable.icon_sliding_menu);
}
You can do it using titleTextStyle attribute of ActionBar.
In your styles.xml, in the App theme, set actionBarTabSyle to a custom style as,
<item name="titleTextStyle">#style/TitleTextStyle</item>
And heres the CustomActionBarTabs,
<!-- action bar tab styles -->
<style name="TitleTextStyle" parent="#style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">#color/actionbar_text</item>
<item name="android:gravity">center</item> //center the title
</style>
Using this you can set various styles to the Title Text like color etc. Remember this will only center the text for the space provided to the Title within the ActionBar. In case this doen't help much you can always create your own custom view and add it to ActionBar as,
getSupportActionBar().setCustomView(R.layout.action_bar);
In case you want to create your own layout, follow these 2 simple steps:
Java Code
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.actionbar);
Where R.layout.actionbar is the following XML.
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="YOUR ACTIVITY TITLE"
android:textColor="#ffffff"
android:textSize="24sp" />
</LinearLayout>
Source.

Custom layout with ActionBar in appcompat causes content to overlap with action bar

I have implemented a custom action bar layout with AppCompat:
public class DoneBarActivity {
public interface OnSaveActionListener {
public void onSave();
}
public static void setupActionBar(final ActionBarActivity activity,
final OnSaveActionListener listener) {
// Inflate a "Done/Cancel" custom action bar view.
final LayoutInflater inflater = (LayoutInflater) activity
.getSupportActionBar().getThemedContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View customActionBarView = inflater.inflate(
R.layout.actionbar_custom_view_done_cancel, null);
customActionBarView.findViewById(R.id.actionbar_done)
.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// "Done" (or "Save")
if (listener != null) {
listener.onSave();
}
activity.finish();
}
});
customActionBarView.findViewById(R.id.actionbar_cancel)
.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// "Cancel"
activity.finish();
}
});
// Show the custom action bar view and
// hide the normal Home icon and title.
final ActionBar actionBar = activity.getSupportActionBar();
actionBar.setDisplayOptions(
ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM |
ActionBar.DISPLAY_SHOW_HOME |
ActionBar.DISPLAY_SHOW_TITLE);
actionBar.setCustomView(customActionBarView,
new ActionBar.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
);
}
}
My activity is just a dumb ActionBarActivity that loads a fragment in a FrameLayout. Here's the fragment code:
#Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container,
final Bundle savedInstanceState) {
// ...
DoneBarActivity.setupActionBar((ActionBarActivity) getActivity(),
new DoneBarActivity.OnSaveActionListener() {
#Override
public void onSave() {
saveIssueChangesAndClose();
}
});
return v;
}
Here's the action bar layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:divider="?attr/dividerVertical"
android:showDividers="middle"
android:dividerPadding="12dp">
<include layout="#layout/include_cancel_button"/>
<include layout="#layout/include_done_button"/>
</LinearLayout>
Here are the two buttons:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?actionButtonStyle"
android:id="#+id/actionbar_cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
style="?actionBarTabTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingRight="20dp"
android:drawableLeft="#drawable/ic_action_cancel"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="#android:string/cancel"/>
</FrameLayout>
and
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?actionButtonStyle"
android:id="#+id/actionbar_done"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
style="?actionBarTabTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingRight="20dp"
android:drawableLeft="#drawable/ic_action_done"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="#string/save"/>
</FrameLayout>
Here's the result in Jelly Bean vs. Gingerbread (Galaxy Nexus for the first, emulator for the latter):
Sorry for the quality, the animated PNG didn't work properly so I switched to animated GIF.
As you can see, the content layout is going over the action bar custom layout (notice the blue overflow in JB and scrollbar position).
Using a non-custom action bar layout works properly on both JB and GB.
The overlay is caused due the different resource id used to reference the content view in different versions of Android. Please refer to the post of Shellom for detailed information. Meanwhile, the following snippet should help you to identify the relevant portion of your code.
// http://code.google.com/p/android/issues/detail?id=58108
private static int getContentViewCompat() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH ?
android.R.id.content : R.id.action_bar_activity_content;
}
Update: The switch is no longer needed. You can update appcompat-v7 to revision 19.0.0. or newer and then reference android.R.id.content on all Android versions.

Categories

Resources