2015年2月18日水曜日

android.app.Fragmentとandroid.support.v4.app.Fragmentの共存で起こるエラー

今回は、android.app.Fragmentとandroid.support.v4.app.Fragmentの共存で起こるエラーについてです。
例えば、以下のようなソースでエラーとなる場合があります。

[ソース]
public void onNavigationDrawerItemSelected(int position) {

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
   .replace(R.id.container, MyFragment.newInstance(position))
   .commit();
 
}

[エラー]
replace(int, android.support.v4.app.Fragment) in FragmentTransaction cannot be applied to (int, XXX.MyFragment)

これは、getSupportFragmentManager()で取得したFragmentManagerのreplace()メソッドに於いて、android.app.FragmentによるMyFragmentクラスのインスタンスを引数にとることは出来ないというエラーです。

対策として、
この場合、MyFragmentクラスに於けるインポートを

import android.app.Fragment;

から

import android.support.v4.app.Fragment;

に変更すれば解決します。

2015年2月14日土曜日

Android Studioのバージョンアップに伴うビルドエラー(Gradle DSL method not found:'runProguard()'...)

Android Studioをバージョンアップすると、バージョンアップ前に作成していたプロジェクトのビルドでエラーが発生することがあります。
これは、Android Studioのバージョンアップの際に、ビルドシステムのGradleもバージョンアップされているからです。

今回は、以下のようなエラーが発生した時の対処方法です。

【エラー】
■Messages Gradle Sync
Gradle DSL method not found:'runProguard()'
possible causes:

Error:(16,0)
・The project 'プロジェクト名' may be useing a version of Gradle thet does not contain the method.
・The build file may be missing a Gradle plugin.


【対処】
app>build.gradle を以下の通り修正します。

■修正前
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

■修正後
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

Android Studioのバージョンアップに伴うビルドエラー(If using the gradle wrapper, try editing the distributionUrl...)

Android Studioをバージョンアップすると、バージョンアップ前に作成していたプロジェクトのビルドでエラーが発生することがあります。
これは、Android Studioのバージョンアップの際に、ビルドシステムのGradleもバージョンアップされているからです。

今回は、以下のようなエラーが発生した時の対処方法です。

【エラー】
■Messages Gradle Sync
Failed to sync Gradle project 'プロジェクト名'
Gradle version 2.2 is required. Current version is 2.1. If using the gradle wrapper, try editing the distributionUrl in C:\パス\AndroidStudioProjects\プロジェクト名\gradle\wrapper\gradle-2.2-all.zip

Error: Please fix the project's Gradle settings.

【対処】
gradle>wrapper>gradle-wrapper.properties を以下の通り修正します。

■修正前
distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip

■修正後
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip

Android Studioのバージョンアップに伴うビルドエラー(The project is using an unsupported version...)

Android Studioをバージョンアップすると、バージョンアップ前に作成していたプロジェクトのビルドでエラーが発生することがあります。
これは、Android Studioのバージョンアップの際に、ビルドシステムのGradleもバージョンアップされているからです。

今回は、以下のようなエラーが発生した時の対処方法です。

【エラー】
■Messages Gradle Sync
Failed to sync Gradle project 'プロジェクト名'
Error:
The project is using an unsupported version of the Android Gradle plug-in(0.13.2). The recommended version is 1.0.1.


【対処】
gbuild.gradleを以下の通り修正します。

■修正前
    dependencies {
        classpath 'com.android.tools.build:gradle:0.13.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

■修正後
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

2015年2月9日月曜日

FragmentとActivityの連携について

WEB上でFragmentについて検索すると、関連する内容がたくさんヒットするのですが、残念なことに、日本語による関連サイトが余りにも少ないのが現状です。
そこで、今回は、今更の感はございますが、Fragmentについて、その中でも特に情報が少ないFragmentとActivityの連携についてまとめてみました。

■Fragmentから特定のActivityと連携する場合

①FragmentからActionBarを操作する

まず、FragmentクラスのgetActivity()メソッドによって、Fragmentが関連付けられているActivityのインスタンスを取得します。

public final Activity getActivity ()
--------------------
[Returns]
Return the Activity this fragment is currently associated with.
--------------------

次に、ActivityクラスのgetActionBar ()メソッドによって、ActionBarのインスタンスを取得します。

public ActionBar getActionBar ()
--------------------
[Returns]
The Activity's ActionBar, or null if it does not have one.
--------------------

以下のようなメソッドを用意しておくと便利です。

private ActionBar getActionBar() {
    return getActivity().getActionBar();
}

ActionBarクラスのメソッドで、以下のような操作が出来ます。

・アプリアイコンをHomeボタンとする。
actionBar.setHomeButtonEnabled(true);

・アプリアイコンの左に戻るアイコンを追加する。
actionBar.setDisplayHomeAsUpEnabled(true);

・タイトル(サブタイトル)を表示する。
actionBar.setDisplayShowTitleEnabled(true);

・タイトルを設定する。
actionBar.setTitle(int resId);

・サブタイトルを設定する。
actionBar.setSubtitle(int resId);


②FragmentからActivityのメソッドを呼び出す

onAttachメソッドで取得したインスタンスは、Fragmentが関連付けられているActivityのインスタンスなので、このインスタンスからメソッドを呼び出す。

public class MainActivity extends Activity {
   
    ---
   
    public void onSectionAttached(int number) {
        switch (number) {
            case 1:
                mTitle = getString(R.string.title_section1);
                break;
            case 2:
                mTitle = getString(R.string.title_section2);
                break;
            case 3:
                mTitle = getString(R.string.title_section3);
                break;
        }
    }

   ---

    public static class PlaceholderFragment extends Fragment {
     
       ----

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
           
            // MainActivity型でキャストして、onSectionAttachedメソッドを呼び出す
            ((MainActivity) activity).onSectionAttached(
                    getArguments().getInt(ARG_SECTION_NUMBER));
        }
       
    }

}





■Fragmentから任意のActivityと連携する場合

Activityにインタフェースでメソッドを実装して、このメソッドをFragmentから呼び出すことで連携することが出来ます。

public class HeadlinesFragment extends ListFragment {
   
    // OnHeadlineSelectedListenerインタフェース型のメンバ変数
    private OnHeadlineSelectedListener mCallback;
   
    // OnHeadlineSelectedListenerインタフェースの宣言
    public interface OnHeadlineSelectedListener {
        // onArticleSelectedメソッドの宣言
        public void onArticleSelected(int position);
    }
   
   
    ---
   
   
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
       
        try {
            // OnHeadlineSelectedListenerインタフェース型でキャスト
            mCallback = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }
   
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // 実装先のメソッドを呼び出す
        mCallback.onArticleSelected(position);
       
        // Set the item as checked to be highlighted when in two-pane layout
        getListView().setItemChecked(position, true);
    }
   
}


public class MainActivity extends FragmentActivity implements HeadlinesFragment.OnHeadlineSelectedListener {

    ---
 
    // onArticleSelectedメソッドの実装
    public void onArticleSelected(int position) {
     
       ---
     
    }

}

参考サイト:http://developer.android.com/training/basics/fragments/communicating.html