I added the android-support-library-v7-appcompat to my project to support ActionBar from API level 7 above.
It works like a charm on android 4.0+ and also on android 2.3 with a normal Activity that has setContentView in onCreate, but when the activity is loading an Fragment in onCreate the ActionBar gets overlapped with the content of my layout. At all other scenarios the ActionBar works well.
Here is some code:
class AssetsActivity extends ActionBarActivity{
#Override
protected void onCreate(Bundle arg0)
{
super.onCreate(arg0);
OpenLocalFragment assets = OpenLocalFragment.newInstance(index);
assets.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, assets).commit();
}
}
The theme of this activity is set in the manifest to:
#style/Theme.AppCompat
An this is the result on android 2.3 (on 4.0+ the ActionBar shows well)
You can se that the first lisview item is overlaping the ActionBar(White round icon and title "My activity")
It is possible that i found a bug in the support library, it is released only for 2 days now?
Thanks to all.
Edit:
This is now officially fixed and released in the Support Library v19.
As JJD commented below, you can use normally android.R.id.content with appcompat-v7 r.19.0.0 or newer. The home button works too.
With other words: The workaround below is no more needed if you use version 19.0.0 or newer.
I got the answer at code.google.com. i've made a summary from frederic's answer:
For pre ICS devices you must use:
R.id.action_bar_activity_content
instead of
android.R.id.content
R.id.action_bar_activity_content is a new id used in layout for displaying app content, it would appear that it replace android.R.id.content when you use support v7 appcompat ActionBarActivity.
You can use this code to retrieve the correct id of the activity content :
public static int getContentViewCompat() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH ?
android.R.id.content : R.id.action_bar_activity_content;
}
Thanks to frederic
Another alternative if you do not want to modify the source code of android-support-library-v7-appcompat is to add an empty layout in the layout xml file such as:
<LinearLayout
android:id="#+id/content_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
and make the fragment call to add to that layout instead:
ft.add(R.id.content_view, mFragment, mTag);
Seems a bit late to contribute but I had the same problem and haven't seen the answer here....
Check your styles.xml file, there might be an xml attribute for overlaying the actionbar set to true ie
true
The whole entry looks something like this
<item name ="actionBarTabTextStyle" > #style/TabTextStyle</item>
<item name = "windowActionBarOverlay">true</item>
If that is the case then just change the value of "windowActionBarOverlay" to false.
Add a extra empty list header with the size of the actionbar. Should be a good workaround.
Related
Sometimes, when I want to add SDK 21+ feature to my layout, I need to create whole layout in another file. It's heavy to me because I want to do or check everything in one layout. More of layouts are looking complex and hard to manage. Instead of having two layouts for different SDK versions, can I do something like this:
<ImageView
android:id="#+id/x"
android:layout_width="16dp"
android:layout_height="wrap_content"
<compatibility sdk_higher_than="21">
android:elevation="xdp" //my problem not about the elevation. Its just an example that pops in my mind about the compatibility.
</compatibility>
app:srcCompat="#drawable/ic_x" />
I can make this stuff programmatically but when I should see the view instantly on designer, making it programmatically is not a good way for me. If there is a good practice or idea for this problem can anybody illuminate me?
Yes you can do that by adding tool target API:
First add: <RootTag xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
Example:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="14" >
or by name: tools:targetApi="jelly_bean"
If you want your layout directries to be use in different versions, name your files as:
/res/layout/layout.xml - (default directries)
/res/layout-v14/layout.xml
/res/layout-v17/layout.xml
Also, if you want to dynamically create element in your code:
You can also use annotations in your java code to make things easy:
First import: import android.annotation.TargetApi;
Then, use this annotation above your method:
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
There are more annotation that you can get help:
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
Above annotation to warn for methods that are used lower API level. Read more about requiresApi: Android API level annotation for Android libraries
Now, inside your method you can dynamically generate views.
Example from the doc:
private void setUpActionBar() {
// Make sure we're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
Read doc for more details about annotations: https://developer.android.com/studio/write/annotations
You can not give your view elevation in your XML and check for your SDK version in your code - if it's over 21 give the view elevation programmatically.
For example:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
//the API level is above 21 and you can manipulate your view with all the features that available to API level 21+
}
After updating Android Support Libary v7 AppCompat
I'm not able to change style to the title and the following
is not wotking anymore:
int myTitleId = Resources.GetIdentifier("action_bar_title", "id", "android");
TextView barTitle = FindViewById<TextView>(myTitleId);
barTitle.SetTypeface(FontFactory.GetMyFont(this), TypefaceStyle.Normal);
That's because AppCompat now uses a ToolBar widget as replacement for ActionBar. ToolBar creates a TextView instance for the title on-the-fly; if you dig into the (android.support.v7.widget.)ToolBar code, you'll find something like this:
mTitleTextView = new TextView(context);
(Refer to line 607 of android.support.v7.widget.ToolBar in appcompat-v7-23.0.1-sources.jar)
More importantly, no id is ever assigned to the view. This can also easily be seen by inspecting the view hierarchy:
That TextView that you see is the one that holds the title. The id is a generated value and not predefined (like i.e. the one for the ActionBarContainer), which means you can no longer look it up through some sort of static reference.
That explains why your code, which does an id-lookup-by-name, no longer works: the action_bar_title id is simply no longer being used here.
There are several solutions to make setting a custom font to the ActionBar title work again. The cleanest is probably to leverage the fact that setTitle() takes a CharSequence, which means you can attach a custom typeface span to it that enables the custom font and/or style to work. Doing this is some sort of a 'base' Activity would probably make most sense.
You can of course also iterate over the local view hierarchy, starting at ToolBar, but I'd say that's not quite as robust and prone to suffer from future changes (like your current code ;)).
Alternatively, consider using a library to simplify dealing with applying custom fonts. Calligraphy is usually my first stop for this.
After integrating the new Toolbar this is how I changed style.
inside protected override void OnCreate(Bundle bundle) of my Activity (that now extends AppCompatActivity)
where before there was the previous code now I have:
toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
var f = toolbar.Class.GetDeclaredField("mTitleTextView");
f.Accessible = true;
var barTitle = (TextView)f.Get(toolbar);
barTitle.SetTypeface(FontFactory.GetMyFont(this), TypefaceStyle.Normal);
I needed also to add this on the top:
using Java.Lang; //for the reflection
using Toolbar = Android.Support.V7.Widget.Toolbar;
and in the layout.axml I included the toolbar.axml in this way:
//...
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
//...
I asked this question before (here) but nobody answered so I ask It a little bit simpler.
The problem is when I change the layout direction to RTL
(in
xml file : android:layoutDirection="rtl"
or programmatically :
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
getWindows().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
doesn't matter) the navigation icon remain LTR
How can I fix this issue?
To be more specific the arrow should point at right!
In the Activity Class -->
Add these lines :
onCreate(){
ActionBar ab = getSupportActionBar();
// Enable the Up button
ab.setDisplayHomeAsUpEnabled(true);
ab.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_arrow_back_black_24dp, getApplicationContext().getTheme()));
}
#Override
public void onBackPressed() {
super.onBackPressed();
Intent login = new Intent(LoginActivity.this, MainActivity.class);
login.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(login);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
Write a custom drawable using File--> New--> VectorAsset
https://developer.android.com/studio/write/vector-asset-studio.html
Choose the arrow accordingly and Enable the field -->(Enable the auto mirroring for RTL Layout)
Auto-Mirror Property checked
I have changed the color of Arrow to be White, You can choose your own color
FileName: ic_arrow_back_black_24dp.xml in drawable folder
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#00000000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
</vector>
After changing the Locale to Arabic - which changes the entire Layout from RTL to LTR
I just added a drawable icon that rotated 180 degree and set the icon in onCreate() but the problem is we should do this in every activity that It's layout is RTL. So if our application supports both directions we should check if layout direction is RTL then change the up indicator:
if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_arrow_up_rtl);
}
There is property called auto mirror which itself rotate the icon on the basis of locale .
If you are using Toolbar and added the icon as navigation icon , then use the below line to rotate the icon
toolbar.navigationIcon?.isAutoMirrored = true
If you are using image view , then just add a style to the image view to rotate icon . Do create a different style for arabic .
In your style file add the following code :
<style name="ImageMirror">
<item name="android:scaleX">-1</item>
</style>
Go for the vector drawables as they default have this auto mirror property .
u can use :
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_arrow_forward_24dp);
and Add RTL arrow to drawable
The problem is because the arrow is not following the RTL situation of the app
I had the same problem and I ended up creating a custom toolbar
use a NoActionBar theme and create an empty with only android.support.v7.widget.Toolbar in it
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
</android.support.v7.widget.Toolbar>
then include it in all activities needing a toolbar
<include layout="#layout/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and in activity do this
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if(toolbar != null) {
setSupportActionBar(toolbar);
toolbar.inflateMenu(R.menu.whatever);
}
the custom one will follow the RTL direction of the app
I had same problem with Animation, and I resolved it! As I noticed, it is bug for versions below KitKat(and for sure above 4.2, include).
What you need to do, as was said here, it is rotate for 180 in right place.
You have to create your own ActionBarDrawerToggle based on the given code by Google. Inside you will find class DrawerArrowDrawableToggle - it is custom Drawable, that draw Arrow/Humberger "animation". Like before you have to create your own class, based on the code of DrawerArrowDrawableToggle, and inside you will find variable "flipToPointRight" and take care that it will be "RIGHT" and you have take care that rotation won't work on versions >= Kitkat, otherwise will have the problem there. It is all.
This bug happens on Android 4.2 (API 17) only, when using the AppCompat support library version 24 or above.
In previous support library versions like:
compile 'com.android.support:appcompat-v7:23.0.1'
... It was handled automatically, because this older library contained the drawable images of the arrow facing both left and right:
R.drawable.abc_ic_ab_back_mtrl_am_alpha (This is inside the AppCompat v23 library, and multiple versions were available in drawable and drawable-ldrtl, ...)
You can see these images in Android Studio -> View -> Tool Windows -> Project -> Select "Project" in the drop-down menu -> appcompat-v7-23.0.1 -> res -> drawable -> ...
In newer versions of AppCompat, such as
compile 'com.android.support:appcompat-v7:24.0.0' // or anything above 23
The arrow image now only exists as a single vector drawable pointing towards the left:
R.drawable.abc_ic_ab_back_material (Vector XML file inside AppCompat v24 library)
And Android 4.2 does not seem to be able to mirror it in the opposite direction for RTL mode. And the library does not contain a fallback image.
So a potential way to fix it, without creating your own custom image, is to use the older AppCompat support library version 23 or below. But this may not be compatible with newer tools/libraries.
As far as I know this happens in all android studio versions. Luckily, the solution is easier than you think. You just need to disable RTL support. Just go to your Manifest file and change the value in this line to False: android:supportsRtl="true". Another good thing is that this solution will solve most of the problems that occur in RTL languages like Arabic. Hope this helps (:
I declared my menu items with android:showAsAction="ifRoom". My Activity is extending ActionBarActivity. In preview it is as expected but when run on my phone is it always in overflow.
From what I've seen nothing else is needed. My phone runs in Android 4.4.2 KitKat.
Am I missing anything else?
You have to define your own namespace, if you want to use the showAsAction attribute with ActionBarCompat(I assume you are using ActionBarCompat because you mentioned, that you're extending ActionBarActivity):
xmlns:app="http://schemas.android.com/apk/res-auto"
and use showAsAction like this:
<item [...] app:showAsAction="always"></item>
Just try this...
<item android:id="#+id/action_blah"
android:icon="#drawable/ic_c"
android:title="#string/action_blah"
app:showAsAction="(yourOptions)"/>
(yourOptions):
always = To force to show on the actionbar.
never = Not to show on your actionbar ever.
and
ifRoom = It will let your item if there is enough space on your action bar.
You can see these in Landscape mode.
HappyCoding
This question already has answers here:
How to Set a Custom Font in the ActionBar Title?
(17 answers)
Closed 9 years ago.
How can i add custom font(Kulturista _Bold.ttf) to Action bar and change text color to #ffffff without changing min api level 11
see this it might be useful to you
Use the support library you should have backward compatibility. Import the support library into your workspace which can be found in ~/adt-bundle-linux-x86_64-20130729/sdk/extras/android/support/v7/appcompact and use is in your project. And also don't forget to add the support library which can be brought up right clicking into your project and entering Android Tools -> Add Support Library
Using appcompact you will have to extend your activity class with ActionBarActivity. And also using the appcompact you have to make changes in your styles folder. You could refer to this. Do not also forget to update the values-v11 and values-v14 file. Doing all of this will make your application compatible.
P.S. If any error occurs in your appcompact library. Don't panic look at the error logs and open the file that seems to contain the error. Most probably you will have to refresh the file and after that you just fix project properties, and the error goes away.
For custom font, add to assests:
Create a helper class to initialize font:
public class Utils {
public static Typeface fontsStyle;
public static void TypeFaceOne(TextView tv, AssetManager asm){
fontsStyle=Typeface.createFromAsset(asm, "fonts/Roboto-Bold.ttf");
tv.setTypeface(fontsStyle);
}
}
Finally use a custom view for actionbar:
this.getSupportActionBar().setDisplayShowCustomEnabled(true);
this.getSupprotActionBar().setDisplayShowTitleEnabled(false);
LayoutInflater inflator = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.customabview, null);
//customize text
Utils.TypeFaceOne(textview, getAssets());
textview.setTextColor(Color.parseColor("#FFFFFF"));
this.getSupportActionBar().setCustomView(v);
Hope this helps :)