逆引きAndroid入門 スライディングドローワー(SlidingDrawer)を使用するには

スライディングドローワー(SlidingDrawer)を使用するには

スライディングドローワー(SlidingDrawer)とは

スライド式のハンドルでコンテンツを画面外に出し入れできるウィジットです。

このウィジットは、Android1.0では、非公開API(frameworks\base\core\java\com\android\internal\widget\SlidingDrawer.java)でしたが、
Android1.5から、正式に、公開API(android.widgetパッケージ-SlidingDrawerクラス)として追加されています。

実際に使用されている例で言えば、ホームスクリーンのアプリケーションランチャーで使用されている↓です(下図参照)。

  • クローズ(close)状態のSlidingDrawer(赤枠内がhandle)

  • オープン(open)状態のSlidingDrawer(赤枠のhandleを除く下部分がcontent)

160-2.png

 

サンプルリソース

SlidingDrawerは、単体で記述することができず、その子としてhandleとcontentという名前のidの記述が必要です。

具体的には、以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#808080">
    <SlidingDrawer
        android:id="@+id/slidingdrawer"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:handle="@+id/handle"
        android:content="@+id/content">        
        <LinearLayout
            android:id="@id/handle"
            android:layout_width="88dip"
            android:layout_height="44dip"
            android:background="#0000FF"/>
        <LinearLayout
            android:id="@id/content"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#00FF00">
            <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button"/>
            <EditText
                android:id="@+id/editText"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"/>
        </LinearLayout>
    </SlidingDrawer>
</LinearLayout>

実行させると、下図のようになります。

  • クローズ(close)状態のSlidingDrawer(handleは、青色背景のLinearLayout)

160-3.png

  • オープン(open)状態のSlidingDrawer(contentは、緑色背景のLinearLayout)

160-4.png

 

ここでは、できるだけ短く説明するために、handleとcontentにLinearLayoutを用いましたが、実際には、適当なものに置き換えてください。

例えば、handleをボタンにするには、上記のhandleの箇所を以下のように書き換えてみてください。
※実行して試すには、サンプルリソースの一部を書き換えるだけでなく、下図を参考にpngファイルとhandle.xmlを追加する必要があります

  • プロジェクトファイル構成(resフォルダ)

160-5.png

  • res\layout\main.xml(書き換え)
    ※idがhandleのLinearLayoutのブロック<~/>をButtonに書き換える
<Button
    android:id="@id/handle"
    android:layout_width="88dip"
    android:layout_height="44dip"
    android:background="@drawable/handle"/> 

  • res\drawable\handle.xml(追加)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_window_focused="false"
        android:state_enabled="true"
        android:drawable="@drawable/handle_normal" />
    <item android:state_pressed="true"
        android:drawable="@drawable/handle_pressed" />
    <item android:state_focused="true"
        android:state_enabled="true"
        android:drawable="@drawable/handle_selected"/>
    <item android:state_enabled="true"
        android:drawable="@drawable/handle_normal" />
    <item android:state_focused="true"
        android:drawable="@drawable/handle_selected" />
</selector> 
  • res\drawable\handle_normal.png(追加)

handle_normal.png

  • res\drawable\handle_pressed.png(追加)

 handle_pressed.png

  •  res\drawable\handle_selected.png(追加)

handle_selected.png

 

トラブルシューティング

SlidingDrawerリソースを記述したが、handleとcontentという名前のidを記述しなかった場合、
ビルドエラーにはなりませんが、以下のように実行時例外が発生します。

android.view.InflateException: Binary XML file line #: Error inflating class java.lang.reflect.Constructor

対処方法としては、上記のリソースの記述方法を参考に、handleとcontentという名前のidを追加してください。

 

サンプルソースコード

(必須ではないですが、)handleの開閉(オープン/クローズ)やスクロール時に応答したければ、
以下のようなソースコードを書くことで、各々のコールバックを受け取ることができます。

public class SlidingDrawerActivity extends Activity {
    private SlidingDrawer mDialerDrawer;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mDialerDrawer = (SlidingDrawer) findViewById(R.id.slidingdrawer);
        
        mDialerDrawer.setOnDrawerScrollListener(new SlidingDrawer.OnDrawerScrollListener() {
            @Override
            public void onScrollStarted() {
                Log.v("SlidingDrawerActivity", "onScrollStarted()");
            }
            @Override
            public void onScrollEnded() {
                Log.v("SlidingDrawerActivity", "onScrollEnded()");
            }
        });
        
        mDialerDrawer.setOnDrawerOpenListener(new SlidingDrawer.OnDrawerOpenListener() {
            @Override
            public void onDrawerOpened() {
                Log.v("SlidingDrawerActivity", "onDrawerOpened()");
            }
        });
        
        mDialerDrawer.setOnDrawerCloseListener(new SlidingDrawer.OnDrawerCloseListener() {
            @Override
            public void onDrawerClosed() {
                Log.v("SlidingDrawerActivity", "onDrawerClosed()");
            }
        });
    }
}

 

その他参考なるソースコード

Androidソースコードの「packages\apps\Launcher」(ランチャーアプリ)と「packages\apps\Phone」(電話アプリ)が参考になります。