2013年7月9日火曜日

Navigation DrawerをActionBarSherlockで使ってみたい(デザインガイド非準拠)・・・コンテンツ操作用を作成

前々回記事(リンク)前回記事(リンク)の続きです。

 

前回までのあらすじ

前回のラブライブ!
ついにスクールアイドルとしてはじめてのライブに挑むことになったニクニクと(ry

以下本編

何回かに分けてNavigationDrawerを触ってきましたが、本来の目的は
  「NavigationDrawerを右だししてコンテンツ操作用にカスタマイズしたDrawerが欲しい」
でした。
今回は、そのドロワー作成をしましたという記事。

その前にナビゲーションドロワーとは?

NavigationDrawerのガイド(リンク)を見たところ、その特徴としては

  • ドロワーを出せるときはアップナビゲーションアイコンをドロワー有り表示とする
  • 画面外からの操作(左からエッジスワイプ)で表示できること
  • アップナビゲーションアイコンからドロワーを呼び出せること
  • ドロワー表示中はアイコン、アクセシビリティの表示を変更すること

などがあります。

→このあたりはテクブさんの記事(リンク)がとても参考になります!

コンテンツ操作用のドロワーとしてはどうするか?

ActionBarDrawerToggle.javaやDrawerLayout.javaを見ればわかりますが、安易に右だしするのはやめて!という意図が伝わってきます。
ユーザーを混乱させるなということですよね。
じゃぁどうするかですが、上記のNavigationDrawerの特徴をはずしていけばいいのかなということで以下の対処をしてみます。

  • アップナビゲーションアイコンの表示を変更しない
  • 画面外からの操作(エッジスワイプ)で表示させない
  • アップナビゲーションアイコンから呼び出させない
  • ドロワー表示中はアイコン表示を変更しない(アクセシビリティの表示はお好みで

 

実行時画面

ContentDrawer選択して、ボタン選択で、右だしドロワー表示まで。

image image image

 

実装サンプル

上記対応を行ったサンプルをGitHubにあっぷしておきました。
参考にどうぞ。

https://github.com/miquniqu/AbsNavigationDrawerSample

前回からの変更箇所はこちら

https://github.com/miquniqu/AbsNavigationDrawerSample/commit/94b4ebdcf929c7fd3b9c9fc21deca2f5b5cb8681

 

修正したソースの概要

ActionBarContentDrawerToggle.java
→ActionBarDrawerToggle.javaをベースにコンテンツ用にアイコン操作を削除、ドロワー呼び出しとしてpublic void toggleDrawer()追加

ContentDrawerLayout.java
→DrawerLayout.javaをベースにエッジスワイプ操作を削除(setEdgeTrackingEnabledをコメント化しただけ

ContentDrawerActivity.java
→サンプルアプリから、ドロワー呼び出し方法としてボタン追加
※FragmentからActivityのドロワー呼び出しするにはyanzmさんの記事(リンク)が参考になります。

 

NavigationDrawerがらみはこれでおわり!

2013年7月7日日曜日

Navigation DrawerをActionBarSherlockで使ってみたい(デザインガイド非準拠)・・・その後

 

前回記事(リンク)の続きです。

 

前回までのあらすじ

妖精の森エクレアで安穏と暮らしていたニクニクは、異世界でえろい人が開発した武器ナビゲーションドロアーが楽しそうといううわさを耳にした。
しかし、ニクニクの愛車アクションバーシェーロック号にはそのナビゲーションドロアーが搭載できない。
こまったニクニクはいつものように(検索)窓に向かって「ナビゲーションドロアー!ナビゲーションドロアー!」と連呼していたところ、「パッチを感じるんだ」と神の声が聞こえてきた。
ニクニクは恐れながらも声のする方向へ歩いていくと、そこには恐るべき試練が待ち受けていたのであったニク。

 

本編

前回助けてっていってた件が暫定自己解決したのでその内容をうpしときます。
よくわかってない部分だれか教えてくれたらいいと思います。

 

何を変えたか

以下、見てきてください。

API7で動作版
android:attrの利用を直接指定とする
invalidateOptionMenu→supportInvalidateOptionMenuに変更
https://github.com/miquniqu/AbsNavigationDrawerSample/commit/80aff00c0567aa2a0d371f527e0eb8bdc8aac674

 

修正箇所の説明1

DrawerActivity.java

  1:              public void onDrawerClosed(View view) {
  2:                  getSupportActionBar().setTitle(mTitle);
  3: -                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
  4: +                supportInvalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
  5:              }
  6: 

→invalidateOptionsMenuをsupportInvalidateOptionsMenuに変更しわすれてたので一応。


 


修正箇所の説明2


drawer_list_item.xml


  1: <TextView xmlns:android="http://schemas.android.com/apk/res/android"
  2:     android:id="@android:id/text1"
  3:     android:layout_width="match_parent"
  4:     android:layout_height="wrap_content"
  5:     android:textAppearance="?android:attr/textAppearanceListItemSmall"
  6:     android:gravity="center_vertical"
  7:     android:paddingLeft="16dp"
  8:     android:paddingRight="16dp"
  9:     android:textColor="#fff"
 10: -    android:background="?android:attr/activatedBackgroundIndicator"
 11: -    android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
 12: +    android:background="@drawable/abs__activated_background_holo_dark"
 13: +    android:minHeight="48dp"/>
 14: 

これが正直よくわからない。
android:attrはテーマで設定している属性値を利用するってことで、今回利用しているActionBarSherlockのテーマでも、

  1: <style name="Theme.Sherlock" parent="Sherlock.__Theme">
  2:   ~
  3:   <item name="activatedBackgroundIndicator">@drawable/abs__activated_background_holo_dark</item>
  4: 

と宣言されている。
今回の対処は、テーマ属性経由ではなく、abs__activated_background_holo_darkを直接指定するように変更したら
そのセレクターで指定しているres/drawable-hdpi/abs__ic_ab_back_holo_dark.pngが読み込めるようになったというもの。


うーん。。


ともあれ、パッチが適用されたActionBarSherlockに追加修正することなくAPI7~17で利用できたのでよしとしよう。


[2013.07.07 追記]
なんておもってたのだけれど、sdk\extras\android\support\samples\Support4Demosにあるサンプルソースでは、
android.R.layout.simple_list_item_1を利用していたのでdrawer_list_item.xmlのカスタムレイアウトはやめて、
こっちに変更することにしました。


パッチ入手先とか



Android : Navigation Drawer をActionBarSherlockで使う
http://d.hatena.ne.jp/esmasui/20130606/1370517111
https://github.com/esmasui/ActionBarSherlock/commits/ActionBarDrawerToggle
※ABS4.2.0へのぱっち


上記ブログであげられてる4.3.1のパッチ?
https://github.com/ianhanniballake/ActionBarSherlock

今回の修正をいれたサンプルアプリ
https://github.com/miquniqu/AbsNavigationDrawerSample


おわり。

2013年7月1日月曜日

Navigation DrawerをActionBarSherlockで使ってみたい(デザインガイド非準拠)

けど失敗したのでだれか助けて(*´^`*)
という話です。

参考記事

参考にしたのはこのあたりの記事です。

Android : Navigation Drawer を使う
http://y-anz-m.blogspot.jp/2013/05/android-navigation-drawer.html

Android : Navigation Drawer をActionBarSherlockで使う
http://d.hatena.ne.jp/esmasui/20130606/1370517111

[Android] Navigation Drawerを画面上側から表示させる
http://lily-light.blogspot.jp/2013/06/android-navigation-drawer.html

 

やったこと

1、yanzmさんの記事を元にしたesmasuiさんのupしてるパッチ入りActionBarSherlockをベースにサンプル作成
→API 17だとうまくいくけど、API7、10で例外

2、lilylightさんの記事、githubソース(Vertical系)も取り込んで、Horizonも追加してみた

追加ソース
src/com/actionbarsherlock/custom/app/ActionBarHorizonDrawerToggle.java←esmasuiさんのソースへlilylightさんの差分追加
src/com/actionbarsherlock/custom/app/ActionBarVerticalDrawerToggle.java←上記を参考に修正
src/com/actionbarsherlock/custom/widget/VerticalDrawerLayout.java←lilylightさんの差分追加そのまま
src/com/actionbarsherlock/custom/widget/HorizonDrawerLayout.java←上記を参考に修正

→結局一緒。

やりたかったこと

ほんとうにやりたかったことは、ActionBarのアイコンは変更せず(Navigationぽく感じるので)に、
コンテンツ操作時にそのメニューをRIGHTかBOTTOMあたりにスライド移動以外のアニメーションで
Drawer表示かつ、複数Drawer切り替えみたいなことをしたかったんだけど。。ぐぬぬ。

実装サンプル

できてない版としてGitHubにあっぷしておきました。
lilylightさんの記事にもありますが、デザインガイド非準拠なので、利用は要検討。

https://github.com/miquniqu/AbsNavigationDrawerSample

 

できてること

API Level 17 のAVDで一通り操作できる。

・メニュー/デフォルト
image image

・Horizon LEFT/Horizon RIGHT
imageimage

・Vertical TOP/Vertical BOTTOM
image image

 

できてないこと

API Level 10、7 のAVDでandroid.view.InflateException。

image 

以下LogCat

06-30 23:32:44.912: E/AndroidRuntime(219): Uncaught handler: thread main exiting due to uncaught exception
06-30 23:32:44.962: E/AndroidRuntime(219): android.view.InflateException: Binary XML file line #17: Error inflating class <unknown>
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.LayoutInflater.createView(LayoutInflater.java:513)
06-30 23:32:44.962: E/AndroidRuntime(219):     at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.LayoutInflater.inflate(LayoutInflater.java:385)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:332)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.ArrayAdapter.getView(ArrayAdapter.java:323)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.AbsListView.obtainView(AbsListView.java:1274)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.ListView.makeAndAddView(ListView.java:1668)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.ListView.fillDown(ListView.java:637)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.ListView.fillFromTop(ListView.java:694)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.ListView.layoutChildren(ListView.java:1507)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.AbsListView.onLayout(AbsListView.java:1113)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.View.layout(View.java:6830)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:672)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.View.layout(View.java:6830)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.View.layout(View.java:6830)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.View.layout(View.java:6830)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.View.layout(View.java:6830)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.View.layout(View.java:6830)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.ViewRoot.performTraversals(ViewRoot.java:996)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.os.Looper.loop(Looper.java:123)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.app.ActivityThread.main(ActivityThread.java:4363)
06-30 23:32:44.962: E/AndroidRuntime(219):     at java.lang.reflect.Method.invokeNative(Native Method)
06-30 23:32:44.962: E/AndroidRuntime(219):     at java.lang.reflect.Method.invoke(Method.java:521)
06-30 23:32:44.962: E/AndroidRuntime(219):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
06-30 23:32:44.962: E/AndroidRuntime(219):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
06-30 23:32:44.962: E/AndroidRuntime(219):     at dalvik.system.NativeStart.main(Native Method)
06-30 23:32:44.962: E/AndroidRuntime(219): Caused by: java.lang.reflect.InvocationTargetException
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.TextView.<init>(TextView.java:320)
06-30 23:32:44.962: E/AndroidRuntime(219):     at java.lang.reflect.Constructor.constructNative(Native Method)
06-30 23:32:44.962: E/AndroidRuntime(219):     at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.LayoutInflater.createView(LayoutInflater.java:500)
06-30 23:32:44.962: E/AndroidRuntime(219):     ... 35 more
06-30 23:32:44.962: E/AndroidRuntime(219): Caused by: android.content.res.Resources$NotFoundException: File res/drawable-hdpi/abs__ic_ab_back_holo_dark.png from drawable resource ID #0x0
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.content.res.Resources.loadDrawable(Resources.java:1710)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.content.res.TypedArray.getDrawable(TypedArray.java:548)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.view.View.<init>(View.java:1850)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.widget.TextView.<init>(TextView.java:326)
06-30 23:32:44.962: E/AndroidRuntime(219):     ... 39 more
06-30 23:32:44.962: E/AndroidRuntime(219): Caused by: java.io.FileNotFoundException: res/drawable-hdpi/abs__ic_ab_back_holo_dark.png
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.content.res.AssetManager.openNonAssetNative(Native Method)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.content.res.AssetManager.openNonAsset(AssetManager.java:390)
06-30 23:32:44.962: E/AndroidRuntime(219):     at android.content.res.Resources.loadDrawable(Resources.java:1702)
06-30 23:32:44.962: E/AndroidRuntime(219):     ... 42 more