Android : Navigation button show wrong side when l

2019-05-02 10:00发布

问题:

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!

回答1:

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);
}


回答2:

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



回答3:

u can use :

getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_arrow_forward_24dp);

and Add RTL arrow to drawable



回答4:

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



回答5:

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.



回答6:

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.



回答7:

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 .