Androidアプリ開発 ViewDragHeleper ドラッグ可能なViewを作成する

2016年08月30日(編集2016年08月30日)
このエントリーをはてなブックマークに追加

Androidアプリ開発では、ViewDragHeleperを利用してドラッグ可能なViewを作成できます。
この記事は、AndroidアプリでViewDragHeleperを利用してドラッグ可能なViewを作成する方法を記載した記事です。

環境はAndroid 7.0 (API level 24) です。

環境

  • OS X Yosemite
  • Oracle jdk version 1.8.0_72
  • Android Studio 2.1.3
  • android sdk 24
  • Gradle 2.1.3

難易度

初心者向け

サンプルコード

Android-Material-Design-Demo

ViewDragHelper

ViewDragHelperは、カスタムViewGroupsを作成するためのライブラリです。
親のViewGroups内で、ドラッグ、スワイプ等の便利な操作をする機能を提供します。

コードの実装

ViewDragHelperの実装は、ViewGroupを継承したクラスで行います。

ここでは、ViewGroupを継承しているRelativeLayoutを使ってSwipeRelativeLayoutを作成します。

{project_folder}/view/SwipeRelativeLayout.java
public class SwipeRelativeLayout extends RelativeLayout {

    private final static String TAG = "SwipeRelativeLayout";

    public SwipeRelativeLayout(Context context) {
        super(context);
    }

    public SwipeRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        setupViewDragHelper();
    }

    private static final float SENSITIVITY = 1.0f;

    private ViewDragHelper viewDragHelper;

    private void setupViewDragHelper() {
        viewDragHelper = ViewDragHelper.create(SwipeRelativeLayout.this, SENSITIVITY, new ViewDragHelper.Callback() {
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                return true;
            }

            // 上下
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return top;
            }

            // 左右
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dy) {
                return left;
            }

            @Override
            public int getViewHorizontalDragRange(View child) {
                int measuredWidth = child.getMeasuredWidth();
                Log.d(TAG, "measuredWidth :" + measuredWidth);
                return measuredWidth;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        final int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                viewDragHelper.cancel();
                return false;
            default:
                break;
        }
        return viewDragHelper.shouldInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);
        return true;
    }
}
        

■ 実装の解説

1. ViewDragHelper.Callback

Viewの動きは、ViewDragHelper.Callbackを実装してコントロールします。

@Override
public int clampViewPositionVertical(View child, int top, int dy) {
    return top;
}
        

clampViewPositionVerticalメソッドは、垂直軸のドラッグの動きを実装します。デフォルトの実装では垂直の動きは許可されていません。
なので、垂直のドラッグを許可する場合は、オーバーライドして実装する必要があります。

@Override
public int clampViewPositionHorizontal(View child, int left, int dy) {
    return left;
}
        

clampViewPositionHorizontalメソッドは、水平軸のドラッグの動きを実装します。デフォルトの実装では水平の動きは許可されていません。
なので、水平のドラッグを許可する場合は、オーバーライドして実装する必要があります。

レイアウトの作成

上記で作成したViewクラスは、layout.xmlで利用できます。

{project_folder}/res/activity_sample.java
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.java_lang_programming.android_material_design_demo.ui.ViewDragHelperDemoActivity">

    <com.java_lang_programming.android_material_design_demo.view.SwipeRelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/cat"/>

    </com.java_lang_programming.android_material_design_demo.view.SwipeRelativeLayout>

</RelativeLayout>
        

ImageViewを囲むことで、ImageViewをスワイプで動かすことができます。

ビルドと実行

実装を終えたら、ビルドしてアプリを実行します。

draggable View

ドラッグでImageViewが上下左右に動くようになりました。

まとめ

ViewDragHelperを使うと、簡単に動くViewを実装することができます。
非常に便利ですが、実装するときはViewGroupを継承したクラスを使うことに注意してください。

関連記事

タグ検索で調べてみよう

Android7.0 UI