【Android】Fragment内での子Fragmentを管理する方法

今まではFragmentの管理はActivity単位が基本でしたが、getChildFragmentManagerを使用することでFragment内での子Fragmentを管理することができます。

使用例


Fragment childFragment = new ChildFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.child_fragment, childFragment).commit();

参考サイト:

Fragmentをネストする際の注意点 - Just for Fun

FragmentでタブUIを簡単にできるライブラリ作った - ほげほげ(仮)

【Android】画面をスクロールさせる方法

ScrollViewを使用することで、スクロールバーを実現することができます。

スクロールバーの作成


レイアウトファイル(.xml)に以下を追加します。

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:weightSum="1">

        <EditText
             />

        <EditText
             />

        <Button
             />

        .
        .
        .

    </LinearLayout>
</ScrollView>

ここで注意が必要なのは、ScrollViewのなかに、子要素を一つ入れる必要があるということです。

LinearLayoutがここでいう子要素になります。

子要素がないとScrollView can host only one direct childというエラーがでるので注意して下さい。


参考サイト:

Androidアプリで画面の一部をスクロールさせる - Qiita

ScrollView can host only one direct child -でじうぃき

【Atom】Vimのキーバインドを使用する方法

AtomVimキーバインドを使えるプラグインvim-modeというものがあります。

保存(:wq)のキーバインドは使えなかったですが、ほとんどVimキーバインドは設定することで使用できます。

vim-modeのインストール方法


  1. [Ctrl] + [Shift] + [P]を入力して、入力欄にsettings ...と入力します。

  2. 最初の3文字くらい入力すると補完でSettings Viewr: Openとプルダウンに表示されるので、それを選択します。

  3. SettingsのInstall Packagesの画面に移動するので、vim-modeを検索欄に入力してプラグインをインストールします。

  4. インストールが完了したら、画面上のメニューにある[View]→[Relode]をクリックして再読み込みをします。

  5. 最後に、SettingsのPackagesの画面にvim-modeがInstalld Packagesに表示されているので、vim-mode欄のSettingsをクリックし、vim-modeの詳細画面に移動したあと、Settingsにある4つのチェックボックスにチェックを入れます。


参考サイト:

生粋のvimmerがAtomにのりかえる話 | Utage Blog

【Android】FragmentTabHostを使用したタブの作成

FragmentTabHostはFragmentをタブで切り替えるためのViewです。

タブの作成は以前TabActivityを使っていましたが、現在は非推奨になっているのでFragmentTabHostの使用をおすすめします。

また、Android 1.6から利用することができるものとなっています。

今回はFragmentにタブを表示する方法と、Fragment内での子Fragmentにタブを表示する方法を書きます。

Fragmentにタブを表示


レイアウトの作成

<android.support.v4.app.FragmentTabHost
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TabWidget
        android:id="@android:id/tabs"
        android:layout_alignParentBottom="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

        <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="0dp"
        android:layout_height="0dp"/>

        <FrameLayout
        android:id="@+id/content"
        android:layout_alignParentTop="true"
        android:layout_above="@android:id/tabs"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>
    </RelativeLayout>
</android.support.v4.app.FragmentTabHost>

Activityの追加

public class MainActivity extends FragmentActivity {

    .
    .
    .

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

        /* ---------- START 追加部分 ----------  */
        FragmentTabHost host = (FragmentTabHost) findViewById(android.R.id.tabhost);
        host.setup(this, getSupportFragmentManager(), R.id.content);
 
        TabSpec tabSpec1 = host.newTabSpec("tab1");
        Button button1 = new Button(this);
        button1.setBackgroundResource(R.drawable.tab_left);
        tabSpec1.setIndicator(button1);
        Bundle bundle1 = new Bundle();
        bundle1.putString("name", "Tab1");
        host.addTab(tabSpec1, SampleFragment.class, bundle1);
         
        TabSpec tabSpec2 = host.newTabSpec("tab2");
        Button button2 = new Button(this);
        button2.setBackgroundResource(R.drawable.tab_center);
        tabSpec2.setIndicator(button2);
        Bundle bundle2 = new Bundle();
        bundle2.putString("name", "Tab2");
        host.addTab(tabSpec2, SampleFragment.class, bundle2);
         
        TabSpec tabSpec3 = host.newTabSpec("tab3");
        Button button3 = new Button(this);
        button3.setBackgroundResource(R.drawable.tab_right);
        tabSpec3.setIndicator(button3);
        Bundle bundle3 = new Bundle();
        bundle3.putString("name", "Tab3");
        host.addTab(tabSpec3, SampleFragment.class, bundle3);
        /* ---------- END 追加部分 ----------  */
    }

    .
    .
    .

}

Fragment内での子Fragmentにタブを表示


レイアウトは上記のものと変わらないのですが、Fragmentに追加するコードのhost.setup( ... );の部分一行を変更する必要があります。

getActivity()getChildFragmentManager()を使用します。

Fragmentの追加

public class BlankFragment extends Fragment {
    
    .
    .
    .

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_blank, container, false);

        /* ---------- START 追加部分 ----------  */
        FragmentTabHost host = (FragmentTabHost) view.findViewById(android.R.id.tabhost);
        // 「getActivity()」、「getChildFragmentManager()」を使用
        host.setup(getActivity(), getChildFragmentManager(), R.id.content);

        TabSpec tabSpec1 = host.newTabSpec("tab1");
        Button button1 = new Button(this);
        button1.setBackgroundResource(R.drawable.tab_left);
        tabSpec1.setIndicator(button1);
        Bundle bundle1 = new Bundle();
        bundle1.putString("name", "Tab1");
        host.addTab(tabSpec1, SampleFragment.class, bundle1);
         
        TabSpec tabSpec2 = host.newTabSpec("tab2");
        Button button2 = new Button(this);
        button2.setBackgroundResource(R.drawable.tab_center);
        tabSpec2.setIndicator(button2);
        Bundle bundle2 = new Bundle();
        bundle2.putString("name", "Tab2");
        host.addTab(tabSpec2, SampleFragment.class, bundle2);
         
        TabSpec tabSpec3 = host.newTabSpec("tab3");
        Button button3 = new Button(this);
        button3.setBackgroundResource(R.drawable.tab_right);
        tabSpec3.setIndicator(button3);
        Bundle bundle3 = new Bundle();
        bundle3.putString("name", "Tab3");
        host.addTab(tabSpec3, SampleFragment.class, bundle3);
        /* ---------- END 追加部分 ----------  */

        return view;
    }

    .
    .
    .

}

参考サイト:

Android Tips #38 FragmentTabHost を使って Fragment をタブで切り替える | Developers.IO

【PHP】JSONとXMLのパースの方法

PHPJSONXMLをパースする方法です。

JSON


<?php
    $url = "jsonを取得するURL";
    $json = file_get_contents($url);//ファイルの内容を全て文字列に読み込む
    $obj = json_decode($json);//取得したJSON文字列を解読して、PHPで利用できるよう配列化

XML


<?php
    $url = "xmlを取得するURL";
    $xml = simplexml_load_file($url);//指定したファイルの中の整形式XMLドキュメントをオブジェクトに変換

【Android】HTTP通信でGET/POSTをする方法

HTTP通信でデータをGET/POSTをする場合の処理です。

HTTP通信をする場合、非同期処理をしないといけないので注意して下さい。

GET


HttpClient client = new DefaultHttpClient();

// パラメータの設定
ArrayList<NameValuePair> value = new ArrayList<NameValuePair>();
value.add( new BasicNameValuePair("key1", "value1"));
value.add( new BasicNameValuePair("key2", "value2"));
value.add( new BasicNameValuePair("key3", "value3"));

String responseData = null;

 try {
    String query = URLEncodedUtils.format(value, "UTF-8");
    HttpGet get = new HttpGet("URL" + "?" + query);

    // リクエスト送信
    HttpResponse response = client.execute(get);
    // 取得
    HttpEntity entity = response.getEntity();
    responseData = EntityUtils.toString(entity, "UTF-8");
} catch(IOException e) {
    e.printStackTrace();
}

POST


HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("URL");

// パラメータの設定
ArrayList<NameValuePair> value = new ArrayList<NameValuePair>();
value.add( new BasicNameValuePair("key1", "value1"));
value.add( new BasicNameValuePair("key2", "value2"));
value.add( new BasicNameValuePair("key3", "value3"));

String responseData = null;

try {
    post.setEntity(new UrlEncodedFormEntity(value, "UTF-8"));// 文字コード変換
    // リクエスト送信
    HttpResponse response = client.execute(post);
    // 取得
    HttpEntity entity = response.getEntity();
    responseData = EntityUtils.toString(entity, "UTF-8");
} catch(IOException e) {
    e.printStackTrace();
}

参考サイト:

Androidでサーバと通信する方法(Asynctaskによる非同期HTTP通信) | Tech Booster

プログラム備忘録 Android での POST 送信

Android:HTTP通信でGET, POSTする | 自転車で通勤しましょ♪ブログ

電気羊はandroidの夢を見る: HttpGet/Postにパラメータを渡す

【Android】LoaderCallbacksで使用するLoaderManagerのAPIまとめ

AsyncTaskLoaderのコールバック処理であるLoaderCallbacksですが、それに使うLoaderManagerについてよく分からなかったので、まとめてみます。

Activity.getLoaderManager

複数のLoaderを管理するLoaderManagerのインスタンスを取得


  • 各Activity/FragmentにLoaderManagerは1つ割り当てられ、何度コールしても同じLoaderManagerインスタンスが返却される
  • Activity/Fragmentのインスタンスが異なれば返却されるLoaderManagerのインスタンス は異なるため、LoaderのID重複は気にする必要はない
  • LoaderManagerはgetLoaderManagerメソッドの初回コール時に生成される
  • LoaderManagerのライフサイクルはActivity/Fragmentにより管理され、onStart時に開始される
    • ※onStart時にLoaderManagerが初期化(getLoaderManagerが呼ばれていない)されていなければLoaderManagerは正しく動作しない
  • getLoaderManagerメソッドはonStartより前にコールしないと、LoaderManagerがLoaderを正しく管理してくれない

LoaderManager.initLoader

指定したIDでLoaderを初期化・生成


  • 指定するIDはLoaderの識別子として使用され、Loaderが作成される時はonCreateLoaderがコールバックされる
  • initLoaderは指定のLoaderを初期化
    • 指定したIDに紐づくLoaderがすでに存在している場合、Loaderは初期化されない
    • Loaderへのコールバックが指定されたインスタンスでは上書きされる
      • このとき、引数のargsは無視される
  • initLoaderは関連するActivityのonCreateまたはFragmentのonCreateActivityに使用されるべきメソッド
  • LoaderManagerはconfiguration changeによって破棄・生成されず再利用される
  • LoaderManagerは既に存在するLoaderの再利用を可能としている
    • Activityがconfiguration changeにより再生成されてonCreateでinitLoaderを コールしても、対象のLoaderをLoaderManagerが既に保持しているのでLoaderを生成する onCreateLoaderが再度呼ばれることはない
  • 注意点として、Loaderが再利用される場合は引数argsは無視される

LoaderManager.restartLoader

引数のIDに関連付けられているLoaderを再生成


  • 既存のLoaderは必要に応じてキャンセル/停止/破棄される
  • 生成されるLoaderは引数argsを持つ新たなLoaderとして生成される

LoaderManager.destroyLoader

引数のIDに紐づいたLoaderを停止・破棄


  • 破棄対象のLoaderがデータをユーザへ通知していた場合は、onLoadFinishedから onLoaderResetがコールされる

参考サイト:

Yukiの枝折: LoaderManagerのAPIまとめ