Android Lollipop, AppCompat ActionBar custom view doesn't take up whole screen width
Solution 1
Looks like this is caused by the latest changes to the ActionBar
in the recent appcompat-v7
update.
It seems like that there are significant changes to how you should handle action bars.
I faced the same issue and after reading the ActionBar
documentation, and especially the following quote I found a solution.
Beginning with Android L (API level 21), the action bar may be represented by any Toolbar widget within the application layout. The application may signal to the Activity which Toolbar should be treated as the Activity's action bar. Activities that use this feature should use one of the supplied .NoActionBar themes, set the windowActionBar attribute to false or otherwise not request the window feature.
The way I see it, the AppCompat
themes were changed and on one hand seemed to break a few things but provide much more flexibility on the other.
I recommend following these steps:
- Use
.NoActionBar
style in your activity as described in the above quote - Add a
android.support.v7.widget.Toolbar
to your Activity layout - Set the
app:contentInsetStart="0dp"
attribute. This is the main issue with the margin that you describe in your question
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/actionBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp" >
</android.support.v7.widget.Toolbar>
It's usually recommended that you do that in a separate layout file and use include
in your activity layout so you will only need to customize the Toolbar in one place if used in multiple activities
<include layout="@layout/view_action_bar" />
- Use
findViewById
andsetSupportActionBar
in your ActivityonCreate
tosignal to the Activity which Toolbar should be treated as the Activity's action bar
Toolbar actionBar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(actionBar);
- Once you do that, all actions added in
onCreateOptionsMenu
will be added to the toolbar and it will be treated as the activity action bar. - Further customize the Toolbar as desired (Add child views etc.)
Solution 2
Instead of doing so much of work as mentioned by Muzikant and like this answer
getSupportActionBar().setDisplayShowHomeEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
LayoutInflater mInflater = LayoutInflater.from(this);
View mCustomView = mInflater.inflate(R.layout.action_bar_home, null);
getSupportActionBar().setCustomView(mCustomView);
getSupportActionBar().setDisplayShowCustomEnabled(true);
Toolbar parent =(Toolbar) mCustomView.getParent();//first get parent toolbar of current action bar
parent.setContentInsetsAbsolute(0,0);// set padding programmatically to 0dp
You have to add only the last two lines of code to solve your problem.
I hope this might help you and anyone else.
UPDATE: After making some research on it, i found that this solution will not work in some cases. The left side gap (HOME or BACK) will be removed with this but the right side gap (MENU) will remain as is. Below is the solution in these cases.
View v = getSupportActionBar().getCustomView();
LayoutParams lp = v.getLayoutParams();
lp.width = LayoutParams.MATCH_PARENT;
v.setLayoutParams(lp);
Add these four lines to above code, so that the right side gap is also removed from support action bar.
Solution 3
I think you can also do that in styles. try this. tested it on kitkat
<style name="AppTheme" parent="Theme.AppCompat">
<item name="toolbarStyle">@style/AppThemeToolbar</item>
</style>
<style name="AppThemeToolbar" parent="Widget.AppCompat.Toolbar" >
<item name="contentInsetStart">0dp</item>
</style>
Solution 4
None of the other answers worked for me, so I took a look at the actual AppCompat v7 styles, found here.
If you look at the Base.Widget.AppCompat.ActionBar style, it has:
<item name="contentInsetStart">@dimen/abc_action_bar_content_inset_material</item>
<item name="contentInsetEnd">@dimen/abc_action_bar_content_inset_material</item>
So obviously we just need to override those properties in our own action bar style:
<style name="ActionBar" parent="@style/Base.Widget.AppCompat.ActionBar">
<item name="contentInsetStart">0dp</item>
<item name="contentInsetEnd">0dp</item>
</style>
This worked great for me, hope it helps others too.
Solution 5
After much beating my head against the monitor, this worked for me
Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
toolbar.setContentInsetStartWithNavigation(0);
toolbar.setContentInsetEndWithActions(0);
toolbar.setContentInsetsAbsolute(0, 0);
toolbar.setPadding(0, 0, 0, 0);
The getCustomView().getParent() is what did the trick
Stevie Kideckel
Updated on August 14, 2020Comments
-
Stevie Kideckel over 3 years
So, I just updated my codebase to Lollipop, and I'm having issues with the Action Bar. I'm using AppCompat and ActionBarActivity, and inflating a custom view. It seems that the custom view no longer takes up the whole width of the screen, leaving a thin strip on the left
Way it used to look
Way it looks now
This is the code I'm using to set up the Action Bar. Anyone have any ideas?
final ActionBar actionBar = getSupportActionBar(); if(actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setDisplayShowHomeEnabled(false); actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayShowCustomEnabled(true); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setCustomView(R.layout.action_bar_content_search_custom_view); actionBar.setBackgroundDrawable(null); // actionBar.setStackedBackgroundDrawable(null); TextView title = (TextView) actionBar.getCustomView().findViewById(R.id.action_bar_title); title.setText(R.string.youtube); ImageView back = (ImageView) actionBar.getCustomView().findViewById(R.id.action_bar_back); back.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); } }); }
Edit
Taking out the custom view and changing the background now takes up the whole width. So the issue is, how can we make a CustomView take up the whole width of the ActionBar?
-
Ahmed Nawaz over 9 yearsI am trying to use Toolbar with navigation drawer however I am getting error
Error inflating class fragment
-
Muzikant over 9 yearsAll the relevant code is shared on the answer. Looks like you should start a new question for your case as it seems like a different problem.
-
Ahmed Nawaz over 9 yearsThanks. I solved the problem by replacing actionbar with Toolbar.
-
JPMagalhaes over 9 yearsThanks so much! You saved my day! But I'm still looking for a way to put the bottom divider of action bars in my toolbar. Actually, I don't know if it is really a divider in the action bar. It is normally bellow the action bar and it is really a shadow over the content. Any idea?
-
Liminal over 9 yearsYou shouldn't use explicit package names in the namespace declarations. Use
xmlns:app="http://schemas.android.com/apk/res-auto"
-
Matt Wolfe over 9 yearsDo you add the custom view to the new Toolbar or by using actionbar.setCustomView()?
-
Muzikant over 9 yearsThere is no need for
setCustomView
. Just build a layout file with the widgets you want to include in your toolbar (e.g. add child views to the layout file described in section 3 of the answer) -
SBotirov over 9 yearsThis answer is wrong: android:contentInsetStart requires API level 21 (current min is 14)
-
SBotirov over 9 yearsBut, idiom very good! You need write style separately for api 21 and old versions.
-
Chitrang over 9 yearsNot able to get click event in onOptionsItemSelected with setSupportActionBar(actionBar);, can you please provide solution for this.
-
Tooroop over 9 yearsThis is the correct answer to remove the left margin if you are still using the default action bar.
-
BoD over 9 yearsThis works indeed! With the latest version of the support lib, I think you don't need to declare the attributes twice (the android: ones are not necessary).
-
digitalmidges about 9 yearsthanks! thanks! the last 2 lines was what ive been looking for!
-
void about 9 yearsI added following in toolbar app:contentInsetEnd="0dp" app:contentInsetStart="0dp" and it is working now!
-
user1732313 almost 9 yearsI've been searching for this problem and when I've found your answer I see that I already upvoted it! So thanks twice.
-
Bala Vishnu almost 9 yearsWorked for me..Thanks
-
Justin over 8 yearsDidn't work for me, still have the left/right padding.
-
Stevie Kideckel over 8 yearsYep, as the chosen answer states, the key is the contentInsetStart and contentInsetEnd attributes of the ActionBar/Toolbar. It's valid to define your own style, but you can also set them to 0dp on the attributes of the Toolbar in your xml
-
h_k over 8 yearsThis only works when extending
AppCompatActivity
, assetSupportActionBar(ToolBar)
is not available in a regularActivity
. Any workaround without having to useAppCompatActivity
? -
Mahdi over 8 years@Muzikant thanks for your answer. when I put my sutom action bar i doesn't have shadow as normal action bar. how or where I can implement it to have shadow?
-
praxmon over 8 yearsI am supporting the 14th API version and sadly it does not work. Minimum supported version is 21. Any work around?
-
Md. Sajedul Karim about 8 yearsThanks a lot. You saves my life. The tonic code is app:contentInsetEnd="0dp" app:contentInsetStart="0dp"
-
Zen about 8 yearsWhere do we add these lines? After the Toolbar part?
-
Amrut Bidri about 8 years@summers yes add them immediately after toolbar code.
-
avluis about 8 yearsThis was killing me: app:contentInsetEnd="0dp" app:contentInsetStart="0dp" 10xs