2015年3月23日月曜日

イトナブ開発合宿in滝沢市を開催しました。


こんにちは、イトナブ石巻のフィッシュ(津田恭平)です。

岩手県の滝沢市で開発合宿、その名もイトナブ開発合宿を開催しました。

今回はイトナブ開発合宿のレポートを紹介していきます。

イトナブ開発合宿とは?
我々イトナブ石巻が主催する開発合宿です。イトナブ開発合宿は普段の活動拠点である石巻以外で開催し、プログラミングをする人であれば何方でも参加可能となっております。

具体的にどんな事をするの?
1人1つテーマを決めプログラミングを行います。開発のプラットフォームやプログラミング言語は自由です。普段触れているプログラミング言語でも、いつかやってみたいと思っていたプログラミングでも、選択は自由です。但し選択するテーマは他人と違ったものを選んでもらいます。そしてなるべく深く掘り下げて開発を行っていきます。
例:
A君「マテリアルデザインを使ったAndroidアプリを開発したい。」
B君「Unityをやってみたかったので、Unityのチュートリアルをしてみたい。」

ハッカソンとの違いは?
1つのテーマに対して深い知識を得ることを目的としています。ハッカソンなどのイベントだと、プロトタイプまでの完成を求められるので、どうしても浅く広い開発になってしまいます。また非エンジニアにも分かりやすく説明しないといけないため、どうしてもデザイン面(アプリの見た目)やプレゼンに力を入れるので、なかなか腰を据えて開発をすることができません。イトナブ開発合宿では気になる部分をとことん開発していきます。
※ここで定義する浅く広くは、例えばエラー処理のコードをきちんと書かなかったり、リファレンスをきちんと読まずに違う分野の開発にどんどん進んで開発をすることです。

目的は?
新しい技術やリファンレスの奥底に眠る便利な機能を発見を目的としています。そして合宿の最終日に技術を共有することで、個々人がどのような開発が出来るようになったのかを知ることができます。そして非エンジニアが新しい技術を見た時、新たなアイディアが出るきっかけとなったり、個々人の能力を知ることで仕事を依頼する可能性もでてきます。

イトナブ開発合宿in滝沢市では以下9名で開発を行いました。

一般社団法人イトナブ石巻のメンバー
津田 恭平(フィッシュ) 
谷口 泰大(とみぎ)   
佐々木 唯(ポーカー) 
白出 達彦(紅白)    
武山 将己(日出)  

ゲストのみなさん
遠藤 拓也        岩手県立大学
関村 涼         岩手県立大学
溝渕   俊樹        岩手県立大学
佐々木 知洋       盛岡工業高校

開発記録は膨大なため、個別投稿とさせていただきました。
予めご了承ください。

イトナブ開発合宿in滝沢市の全体まとめ
遠藤 匠(高菜)

Android Location APIを使ってみよう!
津田 恭平(フィッシュ)

Unityに触れてみよう。
佐々木 唯(ポーカー)

Canvasとmatrixの組み合わせの応用
白出 達彦(紅白)

AndroidのAnimationクラスを使ってみる
武山 将己(日出) (準備中です。)

AndroidのToolbarに触れてみよう。
遠藤 拓也 岩手県立大学

Javaによる画像処理
溝渕 俊樹 岩手県立大学












2015年3月19日木曜日

AndroidのToolbarに触れてみよう。

この記事はイトナブ開発合宿にて作成されました。
イトナブ開発合宿を知らない方はまずこちらを御覧ください。
イトナブ開発合宿in滝沢市を開催しました。


【自己紹介】
はじめまして。「えんた」こと、遠藤拓也といいます。
岩手県立大学の2年で、普段は小・中・高生にプログラミングを教えたり、
AndroidアプリやWebサービスの開発を勉強していたりします。

イトナブ開発合宿はとても和やかな感じで開発ができて、分からない所や参考になりそうな
ところを教えてくださったり、ハッカソンとは違い徹夜して切羽詰まり…ということなく、
自分のペースで開発を進めていくことが出来ました。


【開発テーマ】
Android 5.0から使えるようになった、Toolbarとそのまわりをいじってみようと思います!


【Toolbarとは?】
Android 5.0 (Lollipop)と同時に追加されたActionBarの代替となるものです。
ビュー階層内に記述するため、他のビューとの共存や、アニメーション、スクロールイベントへの反応などが簡単にでき、
Activity の Action Bar として設定することもできるので、通常のオプション メニューのアクションをその内部に表示させることも可能です。


【開発環境
・Mac OS X (10.10.2)
・Android Studio(1.0.1)
・Android(5.0.1)


【試してみたこと】

・Toolbar
・Tab(Actionbar.Tabが非推奨になったため)
Navigation Drawer


 


【準備】
build.gradle(Module: app)
忘れないように、最初に追加しておきましょう。

dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     // Toolbarを使うために必要
     compile 'com.android.support:appcompat-v7:21.0.0'
     // PagerSlidingTabStripを使うのに必要
     compile 'com.jpardogo.materialtabstrip:library:1.0.6'
}


================================================================================
styles.xml(v21)
Toolbarの色やステータスバーの色などはここで指定します。
parentはTheme.AppCompat…を使う必要があるみたいです。

<? xml version = "1.0" encoding = "utf-8" ?>
< resources >
     < style name = "AppTheme" parent ="Theme.AppCompat.Light.NoActionBar" >
         <!-- Customize your theme here. -->
         <!-- Toolbarの背景色 -->
         < item name = "colorPrimary" >#FFBB33</ item >
         <!-- ステータスバーの背景色 -->
         < item name = "colorPrimaryDark" >#FFFF8800</ item >
         <!-- ActionModeを使うのに必要 -->
         < item name = "windowActionModeOverlay" >true</ item >
     </ style >
</ resources >



================================================================================
activity_main.xml
メインのレイアウト部分です。

<!-- Drawer start-->
< android.support.v4.widget.DrawerLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     android:id = "@+id/drawer_layout"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent" >
     < RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
         xmlns:app = "http://schemas.android.com/apk/res-auto"
         xmlns:tools = "http://schemas.android.com/tools"
         android:layout_width = "match_parent"
         android:layout_height = "match_parent"
         android:padding = "0dp"
         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" >
         <!-- Tab -->
         < com.astuetz.PagerSlidingTabStrip
             android:id = "@+id/tabs"
             android:layout_width = "match_parent"
             android:layout_height = "48dp"
             android:layout_alignParentStart = "true"
             android:layout_below = "@+id/tool_bar"
             android:background = "?attr/colorPrimary" />
         < android.support.v4.view.ViewPager xmlns:android = "http://schemas.android.com/apk/res/android"
             android:id = "@+id/pager"
             android:layout_width = "match_parent"
             android:layout_height = "match_parent"
             android:layout_alignParentEnd = "false"
             android:layout_alignParentStart = "false"
             android:layout_below = "@+id/tool_bar"
             android:focusable = "false"
             android:nestedScrollingEnabled = "false"
             android:outlineProvider = "paddedBounds" >
             < android.support.v4.view.PagerTabStrip
                 android:id = "@+id/strip"
                 android:layout_width = "match_parent"
                 android:layout_height = "wrap_content"
                 android:background = "#FFBB33"
                 android:focusable = "false"
                 android:paddingBottom = "12dp"
                 android:paddingEnd = "15dp"
                 android:paddingStart = "15dp"
                 android:paddingTop = "12dp"
                 android:textColor = "#000"
                 android:touchscreenBlocksFocus = "true" />
         </ android.support.v4.view.ViewPager >
         <!-- ToolBar start -->
         < android.support.v7.widget.Toolbar
             android:id = "@+id/tool_bar"
             android:layout_width = "match_parent"
             android:layout_height = "wrap_content"
             android:layout_alignParentLeft = "true"
             android:layout_alignParentStart = "true"
             android:layout_alignParentTop = "true"
             android:background = "?attr/colorPrimary"
             android:minHeight = "?attr/actionBarSize"
             app:theme = "@style/ThemeOverlay.AppCompat.ActionBar" >
         </ android.support.v7.widget.Toolbar >
         <!-- ToolBar end -->
     </ RelativeLayout >
     <!-- Drawer 表示部分 -->
     < LinearLayout
         android:layout_width = "280dp"
         android:layout_height = "match_parent"
         android:layout_gravity = "start"
         android:background = "#fff" >
         < ListView
             android:id = "@+id/listview"
             android:layout_width = "fill_parent"
             android:layout_height = "match_parent" />
     </ LinearLayout >
     <!-- Drawer 表示部分 end -->
</ android.support.v4.widget.DrawerLayout >
<!-- Drawer end-->


?attrはstyles.xmlで付けた名前を使用しますよって意味


================================================================================
menu_main.xml
Toolbar右に表示されているメニューボタンです

< menu xmlns:android = "http://schemas.android.com/apk/res/android"
     xmlns:tools = "http://schemas.android.com/tools"
     xmlns:app = "http://schemas.android.com/apk/res-auto"
     tools:context = ".MainActivity" >
     < item android:id = "@+id/mbtn"
         android:title = "menu-button"
         android:icon = "@drawable/ic_launcher2” //顔マーク
         android:orderInCategory = "100"
         app:showAsAction = "ifRoom" />
</ menu >


================================================================================
activity_fragment(0〜2).xml
Tabで管理される画面です。今回は同様の画面を3つ用意しましした。

< 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" >
     < TextView
         android:layout_width = "match_parent"
         android:layout_height = "wrap_content"
         android:text = "グー"
         android:textSize = "30sp"
         android:padding = "50dp"
         android:layout_gravity = "center_vertical"
         android:gravity = "center" />
</ LinearLayout >


================================================================================
MainActivity.java
メイン部分です。

public class MainActivity extends ActionBarActivity {
     private DrawerLayout vDrawerLayout;
     private ActionBarDrawerToggle vDrawerToggle;
     private ListView vListView;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         settoolbar();
         PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
         ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
         mViewPager.setAdapter( newMyFragmentStatePagerAdapter(getSupportFragmentManager()));
         tabs.setViewPager(mViewPager);
         PagerTabStrip strip = (PagerTabStrip)findViewById(R.id.strip);
         strip.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20 );
         vDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
         initDrawer();
         vListView = (ListView) findViewById(R.id.listview);
         vListView.setAdapter( new ArrayAdapter<String>(
                 this , android.R.layout.simple_list_item_1, new String[]{ "menu 1" ,"menu 2" , "menu 3" , "menu 4" , "menu 5" }));
     }
     protected void settoolbar(){
         //  toolbar定義
         Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
         //  タイトル
         toolbar.setTitle( "ActionBar Title" );
         //  タイトルの色
         toolbar.setTitleTextColor(Color.parseColor( "#000000" ));
        //  ActionBarと同等にToolbarを使う  
      setSupportActionBar(toolbar);
     }
     private void initDrawer() {
         vDrawerToggle = new ActionBarDrawerToggle( this , vDrawerLayout, R.string.app_name, R.string.app_name);
         vDrawerToggle.setDrawerIndicatorEnabled( true );
         vDrawerLayout.setDrawerListener(vDrawerToggle);
         getSupportActionBar().setDisplayHomeAsUpEnabled( true );
         getSupportActionBar().setDisplayShowHomeEnabled( true );
     }
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.menu_main, menu);
         return true ;
     }
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         int id = item.getItemId();
         if (id == R.id.mbtn) {
             Toast.makeText(MainActivity. this , "Menu click" , Toast.LENGTH_SHORT).show();
             return true ;
         }
         return vDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
     }
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super .onPostCreate(savedInstanceState);
         vDrawerToggle.syncState();
     }
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
         super .onConfigurationChanged(newConfig);
         vDrawerToggle.onConfigurationChanged(newConfig);
     }
}


================================================================================
MyFragmentStatePagerAdapter.java
FragmentStatePagerAdapterでFragmentを管理します。

public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
     public MyFragmentStatePagerAdapter(FragmentManager fm) {
         super (fm);
     }
     @Override
     public Fragment getItem( int i) {
         switch (i){
             case 0 :
                 return new Fragment0();
             case 1 :
                 return new Fragment1();
             default :
                 return new Fragment2();
         }
     }
     @Override
     public int getCount() {
         return 3 ;
     }
     @Override
     public CharSequence getPageTitle( int position) {
         switch (position){
             case 0 :
                 return "First" ;
             case 1 :
                 return "Second" ;
             default :
                 return "Third" ;
         }
     }
}


================================================================================
Fragment(0〜2).java
Tabでスワイプして表示させる画面です。

public class Fragment0 extends Fragment {
     @Override
     public View onCreateView(LayoutInflater inflater,
                              ViewGroup container,
                              Bundle savedInstanceState) {
         return inflater.inflate(R.layout.activity_fragment0, null );
     }

    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         // Handle action bar item clicks here. The action bar will
         // automatically handle clicks on the Home/Up button, so long
         // as you specify a parent activity in AndroidManifest.xml.
         int id = item.getItemId();
         //noinspection SimplifiableIfStatement
         if (id == R.id.action_settings) {
             return true ;
         }
         return super .onOptionsItemSelected(item);
     }
}

長くなりましたが、これで
Toolbar、Tab、Navigation Drawerが実装出来たと思います。

【可能性】
ちょっと調べただけでもたくさんのサンプルが出てきました。
xmlでレイアウトを組むことが好きな私にとってはとても
使いやすいという印象がありました。
Actionbarの代わりとして扱え、さらにサイズや位置も自由に変えられるため、
Actionbar以外の使い道もアイディア次第になりそうです。
ただ、setSupportActionBarするとsetNavigationOnClickListenerやsetOnMenuItemClickListenerは
使えなくなるので注意。


【最後に】
普段は調べる→コピペ→動けばOK、という感じでしたが、
今回は『狭く、深く』ということだったので公式リファレンスを見たり、
実際にいろいろ試してみたり、英語とも格闘しました。すると、
点と点が繋がったようなことがあったり、今後の開発に活かせそうなことも
発見出来たりと、とても充実した時間を過ごすことができました。
今後も新しいことにどんどんチャレンジしていきたいと思います。


【Github】
コピペの量が多すぎ!って人はこちらをどうぞ


【参考】
Google Japan Developer Relations Blog

AndroidのToolBar(新しいActionBar)メモ