Сайт разработчика Александр Климова

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

SlidingDrawer

Начиная с API 17, данный компонент считается устаревшим

Общая информация
Горизонтальное выдвижение
Вертикальное выдвижение
Немного кода
Хак: тянем слева

Общая информация

Виджет SlidingDrawer работает с двумя дочерними элементами. Можно сравнить с выдвижным ящиком стола. Первый элемент - окно, содержащее элементы управления (сам ящик), второй - управляющий элемент для выдвижения (ручка от ящика). Пользователь, нажав на управляющий элемент и двигая пальцем по экрану, перемещает управляющий элемент (выдвигает ящик), а за ним показывается содержимое. Если пользователь отпустит палец, то в зависимости на сколько он вытянул форму, содержимое либо скрывается, либо полностью раскрывается. Можно также просто щелкнуть по выдвижному элементу, чтобы автоматически выдвинуть "ящик".

В зависимости от ориентации управляющий элемент располагается снизу или справа экрана, соответственно вытягивать можно только снизу вверх, или справа налево.

SlidingDrawer используется как правило внутри шаблонов разметки FrameLayout или RelativeLayout.

Находится в папке Composite.

Composite

Наиболее важные атрибуты:

  • handle - определяет идентификатор (id) управляющего элемента
  • content - определяет идентификатор (id) содержимого
  • orientation - определяет ориентацию виджета, по умолчанию vertical

Методы

  • animateClose() - закрыть виджет с анимацией
  • animateOpen() - открыть виджет с анимацией
  • animateToggle() - переключить состояние открыт/закрыт
  • close() - закрыть виджет без анимации
  • getContent() - получить окно содержимого
  • getHandle() - получить окно управляющего элемента
  • isMoving() - проверяет, находится ли виджет в движении
  • isOpened() - проверяет, открыт ли виджет
  • lock() - заблокировать виджет, события касания будут игнорироваться
  • onInterceptTouchEvent(MotionEvent event) - метод для перехвата всех события прикосновения
  • onTouchEvent(MotionEvent event) - метод для того, что делать при касании на экран
  • open() - открыть виджет
  • setOnDrawerCloseListener(SlidingDrawer.OnDrawerCloseListener onDrawerCloseListener) - обработчик закрытия виджета
  • setOnDrawerOpenListener(SlidingDrawer.OnDrawerOpenListener onDrawerOpenListener) - обработчик открытия виджета
  • setOnDrawerScrollListener(SlidingDrawer.OnDrawerScrollListener onDrawerScrollListener) - обработчик прокрутки виджета
  • toggle() - переключить состояние открыт/закрыт без анимации
  • unlock() - разблокировать виджет

Горизонтальное выдвижение

Создадим разметку для горизонтального выдвижения. Никакого кода нам не придётся писать. "Ручкой" нам послужит маленькое изображение стандартного значка программы, а в реальных приложениях лучше использовать стрелки-указатели.


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/ic_launcher" />

    <SlidingDrawer
        android:id="@+id/drawer"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:content="@+id/content"
        android:handle="@+id/handle"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/handle"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:src="@drawable/ic_launcher" />

        <LinearLayout
            android:id="@+id/content"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#55000000"
            android:orientation="vertical"
            android:padding="10dp" >

            <Button
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text=" - Button - " />

            <Button
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text=" - Button - " />

            <Button
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text=" - Button - " />

            <Button
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text=" - Button - " />

            <Button
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text=" - Button - " />

            <Button
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text=" - Button - " />
        </LinearLayout>
    </SlidingDrawer>

</FrameLayout>

SlidingDrawer

На рисунке запечатлён момент, когда я вытянул содержимое почти наполовину.

Вертикальное выдвижение

Аналогично работает вертикальное выдвижение.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="390dip"
        android:layout_gravity="bottom"
        android:background="#808080" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Пример: \nИспользуем SlidingDrawer" />

        <SlidingDrawer
            android:id="@+id/drawer"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:content="@+id/content"
            android:handle="@+id/handle"
            android:orientation="vertical" >

            <ImageView
                android:id="@+id/handle"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="#404040"
                android:src="@drawable/ic_launcher" />

            <LinearLayout
                android:id="@+id/content"
                android:layout_width="fill_parent"
                android:layout_height="200dip"
                android:background="#606060"
                android:orientation="vertical" >

                <Button
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text=" - Button - " />

                <Button
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text=" - Button - " />

                <Button
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text=" - Button - " />

                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="Содержимое" />
            </LinearLayout>
        </SlidingDrawer>
    </FrameLayout>

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Неперемещаемая кнопка" />

</LinearLayout>

Небольшой видеоролик даст представление об этом элементе

Немного кода

Мы рассмотрели примеры без написания кода. Вот простой пример с динамическим изменением изображения для "ручки ящика". Первоначально на экране отображается стрелка вверх, когда мы дотянем эту ручку до конца, то сменим изображение на стрелку вниз. Разметку можно оставить от последнего примера. Предварительно вам надо подготовить изображения со стрелками и скопировать их в папку drawable.


package ru.alexanderklimov.slidingdrawer;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SlidingDrawer;
import android.widget.SlidingDrawer.OnDrawerCloseListener;
import android.widget.SlidingDrawer.OnDrawerOpenListener;
import android.widget.SlidingDrawer.OnDrawerScrollListener;

public class SlidingDrawerDemoActivity extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		final ImageView ibHandle = (ImageView) findViewById(R.id.handle);

		SlidingDrawer slidingdrawer = (SlidingDrawer) findViewById(R.id.drawer);
		
		slidingdrawer.setOnDrawerOpenListener(new OnDrawerOpenListener() {
			public void onDrawerOpened() {
				ibHandle.setImageResource(R.drawable.icon_down);
			}
		});
		
		slidingdrawer.setOnDrawerCloseListener(new OnDrawerCloseListener() {
			public void onDrawerClosed() {
				ibHandle.setImageResource(R.drawable.icon_up);
			}
		});
		
//		slidingdrawer.setOnDrawerScrollListener(new OnDrawerScrollListener() {
//
//			public void onScrollEnded() {
//				// TODO Auto-generated method stub
//
//			}
//
//			public void onScrollStarted() {
//				// TODO Auto-generated method stub
//			}
//		});
	}
}

В примере закоментированы строчки метода, который выполняется при скроле. Нас сейчас интересуют только момент открытия и закрытия.

Open SlidingDrawer Close SlidingDrawer

Хак: тянем слева

SlidingDrawer позволяет тянуть справа-налево или снизу-вверх. Но народные умельцы ловко обошли эту проблему. Нужно повернуть все элементы на 180 градусов и тогда элемент, за который нужно тянуть, окажется слева! Данный способ сработает только на Android 3.0 и выше (нашел на Stackoverflow).


<SlidingDrawer xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/slidingDrawer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:content="@+id/content"
    android:gravity="center_horizontal"
    android:handle="@+id/handle"
    android:orientation="horizontal"
    android:rotation="180" >

    <LinearLayout
        android:id="@+id/handle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:rotation="180"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

    <ImageView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#FF0000"
        android:rotation="180"
        android:src="@drawable/ic_launcher" />

</SlidingDrawer>

Там есть одна особенность. При выдвижении картинка контента выводится вверх ногами, но в конце она переворачивается. Можно считать это дополнительным эффектом.

SlidingDrawer SlidingDrawer

Реклама