Как сделать фоновое действие меньше при открытии ящика навигации?

Я хочу сделать мой фон Activity немного меньше при открытии Navigation Drawer, Имитировать эффект, который существует в приложении Airbnb. Я думаю, лучшим объяснением будет скриншот:

enter image description here

Но дело не в том, чтобы сделать View чуть меньше, а чтобы сделать его анимацией, синхронизированной с анимацией Open/Close Drawer. Поэтому, если вы начали открывать ящик, а посередине решили остановиться и вернуться назад, на экран будет влиять масштаб активности.

Как это можно сделать с помощью сборки в DrawerLayout? Есть ли какая-то реализация для этого?

Спасибо заранее.

Ответ 1

Вы можете выполнить этот эффект, используя ActionBarDrawerToggle в библиотеке поддержки v4.

Все, что вам нужно сделать, это переопределить метод onDrawerSlide для извлечения% открытия меню ящика, а затем масштабировать ваш FrameLayout, где находится ваш фрагмент.

Пример с кодом:

main_layout.xml

<?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">

    <FrameLayout android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>    

    <ListView 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.support.v4.widget.DrawerLayout>

Теперь в вашей деятельности, которая содержит ящик:

public class ConfigurerActivity extends ActionBarActivity 
{
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    private FrameLayout frame;
    private float lastScale = 1.0f;

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);
        frame = (FrameLayout) findViewById(R.id.content_frame);

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.acc_drawer_open, R.string.acc_drawer_close) 
        {            
            @SuppressLint("NewApi")
            public void onDrawerSlide(View drawerView, float slideOffset)
            {
                float min = 0.9f;
                float max = 1.0f;
                float scaleFactor = (max - ((max - min) * slideOffset));

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
                {
                    frame.setScaleX(scaleFactor);
                    frame.setScaleY(scaleFactor);
                }
                else
                {               
                    ScaleAnimation anim = new ScaleAnimation(lastScale, scaleFactor, lastScale, scaleFactor, frame.getWidth()/2, frame.getHeight()/2);
                    anim.setDuration(0);
                    anim.setFillAfter(true);
                    frame.startAnimation(anim);

                    lastScale = scaleFactor;
                }
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);

        // ... more of your code
    }
}

Обратите внимание, что я использую 2 разных метода масштабирования, потому что setScaleX/Y недоступны в версиях PRE-Honeycomb Android.

С помощью этого вы можете установить свой собственный scaleFactor (я думаю, что его достаточно 0,9f) или, возможно, попробовать новые эффекты (изменить цвет) на основе открытия% ящика.

Надеюсь, что это поможет.

Ответ 2

Эй, вы также можете дать лучший эффект для меньшей активности. Проверьте ResideMenu

демо с библиотекой.

Ответ 3

если вы посмотрите на стороннюю библиотеку SlidingMenu, которая должна иметь все, что вы хотите.

Бит, который вас интересует, это behindScrollScale, который говорит следующее:

behindScrollScale - плавающий элемент, представляющий взаимосвязь между прокруткой вверх и прокруткой позади. Если установлено значение 0.5f, то за спиной будет прокручиваться 1px для каждых 2px, которые прокручиваются выше. Если установлено значение 1.0f, то в обратном представлении будет прокручиваться 1px для каждого 1px, который прокручивается выше. А если установлено значение 0.0f, то заглавная страница никогда не будет прокручиваться; он будет статичным. С этим интересно поиграть. Значение по умолчанию равно 0,25f.