「Dribbbleのぬるぬる動くメニューUIのアイデア10選」からDelivery Card(FoldingCell)を試してみる
Dribbbleのぬるぬる動くメニューUIのアイデア10選という記事を見たので、実際に試してみました。
今回はこの記事の中で紹介されている「Delivery Card」を実現するためのFoldingCellを実装します。
セットアップ
Dribbbleのサイトで「Delivery Card」で検索するとトップに出てきました。
ページ内にあるAndroidのリンクを押すとGithubに飛びますので、READMEを見ながらセットアップします。
と言っても、build.gradle(app)を見ながらdependenciesに一行追加してSyncするだけです。
android { defaultConfig { applicationId "techium.com.foldingcellsample" minSdkVersion 17 targetSdkVersion 23 versionCode 1 versionName "1.0" } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.ramotion.foldingcell:folding-cell:1.0.1' // 追加 }
ちなみに、minSDKを17以上にしておかないと怒られます。
レイアウトファイル作成
レイアウトファイルを作成していきます。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:clipChildren="false" ・・・6行目 android:clipToPadding="false" ・・・7行目 android:orientation="vertical" 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=".MainActivity" android:background="@android:color/darker_gray"> <com.ramotion.foldingcell.FoldingCell xmlns:folding-cell="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/folding_cell" android:layout_width="match_parent" android:layout_height="wrap_content" folding-cell:animationDuration="2000" folding-cell:backSideColor="@android:color/holo_blue_dark"> <200b> <!-- ①FoldingCellの1つ目の子Viewは展開後のコンテンツ部分になる --> <LinearLayout android:id="@+id/content_group" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFF" android:orientation="vertical" android:visibility="gone"> <!-- ②最初は隠しておく --> <!-- ③高さの合計がタイトル部分の2倍以上ないといけない --> <ImageView android:id="@+id/content_img" android:src="@drawable/icon" android:layout_marginBottom="6dp" android:layout_marginTop="6dp" android:layout_width="wrap_content" android:layout_height="48dp" /> <!-- line --> <ImageView android:layout_width="match_parent" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_height="1dp" android:src="@android:color/darker_gray" /> <TextView android:id="@+id/content_text1" android:text="Acount : seit" android:gravity="center_vertical" android:layout_marginLeft="6dp" android:layout_width="match_parent" android:layout_height="29dp"/> <!-- line --> <ImageView android:layout_width="match_parent" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_height="1dp" android:src="@android:color/darker_gray" /> <TextView android:id="@+id/content_text2" android:text="自己紹介 : 米屋の息子だよ" android:gravity="center_vertical" android:layout_marginLeft="6dp" android:layout_width="match_parent" android:layout_height="29dp"/> </LinearLayout> <!-- ④FoldingCellの2つ目の子Viewは折りたたまれてる時のView(タイトル) --> <200b> <FrameLayout android:id="@+id/title_group" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- ⑤子Viewのheightはwrap_conentでなくてはならない --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@android:color/holo_blue_dark"> <ImageView android:src="@drawable/icon" android:layout_width="30dp" android:layout_height="30dp" /> <!-- ⑥コンテンツ部はこのheightの2倍以上にしなければいけない --> <TextView android:text="seit" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_marginLeft="6dp" android:layout_height="30dp" android:textColor="#FFFFFF" /> </LinearLayout> </FrameLayout> <200b> </com.ramotion.foldingcell.FoldingCell> </LinearLayout>
実装にはいくつかルールがあります。
1. まず、FoldingCellの1つ目の子Viewがコンテンツ部(展開時のレイアウト)、2つ目の子Viewがタイトル部(折りたたんでいる時のレイアウト)になります。・・(①、④)
また、それぞれの子View(content_group及びtitle_group)の高さにはwrap_contentを指定しておく必要があります。
2. 画面表示時、コンテンツ部は必要ないため、android:visibility="gone"を指定しておく必要があります。・・②
3. コンテンツ部の高さの合計値は、タイトル部の高さの合計値の2倍以上に設定する必要があります。・・(③、⑥)
4. 正常にアニメーションをさせるために、6行目、7行目にそれぞれ以下の通り属性を指定しておく必要があります。
android:clipChildren="false" android:clipToPadding="false"
またこのサンプルでは、折りたたみの谷となる部分にに示すような区切り線を配置していますが、
綺麗に折り目の部分に線を配置するのは知っておかないと少し面倒です。
まず1回目の展開は以下のような高さ配分になります。
図. 1回展開された状態
2回目以降の展開回数(ここでは2回)は以下の式にしたがって自動で計算されます。
(コンテンツ部の高さ(120) - タイトル部の高さ(30dp) * 2) / タイトル部の高さ(30dp)
高さはタイトル部の高さ(30dp)となります。
もし割り切れない場合は、さらにもう一回折りたたみ回数が追加となり、余った数値分の高さで展開となります。
図. 2回展開された状態
図. 3回展開された状態
といったようなことを考慮して、コンテンツ部の各Viewの高さ調整とを配置をしています。
また、以下のような属性値もあるので、必要に応じて設定します。
folding-cell:animationDuration="1000" ・・・展開速度の調整 folding-cell:backSideColor="@color/bgBackSideColor" ・・・展開中のアニメーションの色 folding-cell:additionalFlipsCount="2" ・・・自動計算の展開回数を増やしたい場合は指定
Activity側の実装
次に、Activity側の実装を見ていきます。
package techium.com.foldingcellsample; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import com.ramotion.foldingcell.FoldingCell; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final FoldingCell fc = (FoldingCell) findViewById(R.id.folding_cell); fc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { fc.toggle(false); // 展開する } }); } }
シンプルに、FoldingCellでonClickイベントを取得し、その中で展開を行うためのFoldingCell#toggleメソッドにfalse(展開)を引数として渡しています。
今回はこんなところでしょうか。 また他のものも試してみたいと思います。