Androidアプリを開発してみた


##Twitter for mukeeda
ツイート機能とタイムライン表示までを実装した．
基本的には
[Android再入門 - Twitterクライアントを作ってみよう - ](http://qiita.com/gabu/items/70689560618f8e67e726)
を見てプログラミングしたが，追加で

- Toolbar
- SwipeRefreshLayout

を実装した．

##コード
https://github.com/mkeeda/Twitter-for-mukeeda

##OAuth認証でコケた
OAuth認証後にアプリにコールバックさせる部分は，gabuさんのqiitaの通りにやるとアプリに戻ってこれなかった．
原因は事前にAndroidManifest.xmlで設定したコールバックURLだったっぽい
以下は正常に機能したコード

```xml:AndroidManifest.xml
<activity
    android:name=".TwitterOAuthActivity"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data
            android:host="twitter"
            android:scheme="twittercallback" />
        //scheme="mk_mkee"だと戻ってこれなかった
    </intent-filter>
</activity>
```

###解決策？
```
host="mk_mkee"
scheme="twittercallback"
```
これならコールバックできたので，``twittercallback://自由なhost名``ならばコールバックは成功しそう．

##Toolbar
Android Studioのバージョンアップのせいかわからないが，MainActivityでListActivityを継承していたら，
ActionBarが表示されなかった．

なのでToolbarというものを使ってみた．

アプリのテーマはNoActionBarにしておく

```xml:style.xml
<resources> 
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>
```

```xml:tool_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:elevation="4dp">

</android.support.v7.widget.Toolbar>
```

activity_main.xmlに追加

```xml:activity_main.xml
    <include
        android:id="@+id/tool_bar"
        layout="@layout/tool_bar"></include>
```

```xml:menu_main.xml
<menu 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"
    tools:context=".MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never" />

    <item
        android:id="@+id/send"
        android:orderInCategory="200"
        android:title="tweet send"
        android:icon="@drawable/ic_send_white"
        app:showAsAction="ifRoom"
        />
</menu>
```

MainActivity.javaでToolbarをセットして，onCreateOptionsMenuとonOptionsItemSelectedを追加
###onCreateOptionsMenu
Toolbarにオプションメニューを追加
###onOptionsItemSelected
Toolbarに配置したアイテムが押された時にイベントが飛んで来る
押されたアイテムのidを見て処理を分ける


```java:MainActivity.java
public class MainActivity extends AppCompatActivity {

    private ListView mListView;
    private TweetAdapter mAdapter;
    private Twitter mTwitter;
    private SwipeRefreshLayout mSwipeRefreshLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ツールバーをアクションバーとしてセット
        Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);

//中略

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @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;
        }
        //sendボタン
        else if(id == R.id.send){
            Intent intent = new Intent(this, TweetActivity.class);
            startActivity(intent);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
```

##SwipeRefreshLayout
gabuさんのはActionBarのボタンでTLを更新していた．
Twitter公式アプリなどは下方向にスワイプしてTLを更新するんで，それを実装した．
[SwipeRefreshLayout で Pull to Refresh を実装する](http://dev.classmethod.jp/smartphone/swiperefreshlayout/)を見れば全部出来た．

activity_main.xmlのListViewを<android.support.v4.widget.SwipeRefreshLayout>タグの中に入れ子にする．
入れ子にするListViewは一つだけ

```xml:activity_main.xml
<?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"
    tools:context="com.example.mk_mkee.testtwitter1.MainActivity">

    <include
        android:id="@+id/tool_bar"
        layout="@layout/tool_bar"></include>

    <android.support.v4.widget.SwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swipelayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tool_bar">

        <ListView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/myList"
            />
    </android.support.v4.widget.SwipeRefreshLayout>


</RelativeLayout>
```

スワイプするとonRefreshが実行されるので，今回はreloadtimelineを呼んでTLを更新する

```java:MainActivity.java
public class MainActivity extends AppCompatActivity {

    private ListView mListView;
    private TweetAdapter mAdapter;
    private Twitter mTwitter;
    private SwipeRefreshLayout mSwipeRefreshLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ツールバーをアクションバーとしてセット
        Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);

        //認証してなければ認証画面へ
        if(!TwitterUtils.hasAccessToken(this)){
            Intent intent = new Intent(this, TwitterOAuthActivity.class);
            startActivity(intent);
            finish();
        }
        else{
//----------------ここから追加---------------------
            //SwipeRefreshLayoutの設定
            mSwipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipelayout);
            mSwipeRefreshLayout.setOnRefreshListener(mOnRefreshListener);
            mSwipeRefreshLayout.setColorSchemeResources(
                    R.color.swipe_color_1, R.color.swipe_color_2,
                    R.color.swipe_color_3, R.color.swipe_color_4);
//中略
        }

    }

    private SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = new SwipeRefreshLayout.OnRefreshListener(){
        @Override
        public void onRefresh(){
            reloadTimeLine();
            mSwipeRefreshLayout.setRefreshing(false);
        }
    };
```
##アイコン
アイコンはGoogle先生が提供してるものを使用


##参考  
- [Android再入門 - Twitterクライアントを作ってみよう - ](http://qiita.com/gabu/items/70689560618f8e67e726)
- [Google androidプログラミング入門](http://libro.tuyano.com/index2?id=1005)
- [How To Make Material Design App Bar/ActionBar and Style It](http://www.android4devs.com/2014/12/how-to-make-material-design-app.html)
- [SwipeRefreshLayout で Pull to Refresh を実装する](http://dev.classmethod.jp/smartphone/swiperefreshlayout/)
- [Material icons](https://design.google.com/icons/index.html)