androidStudioで色々とはまってしまった。WEB上の情報も色々と見たのだけど、まとめておかないと後で大変そうだったので自己ログ。
事の始まり
メインのActivityから遷移して、次のActivityに移った時に、タブ付の表示にしてみることにした。
タブの配置にするには「TabHost」を使う方法があるのだけど、新しいAPIでは推奨されていない。「TabLayout」を使い「ViewPager」と「ViewPagerAdapter」で実現する方法がいいと。
Activity遷移イメージ
ActivityとViewPagerAdapterなどの関連図
まずは、タブを実装するActivityのレイアウトファイルに、TabLayoutとViewPagerを追加
<android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" /> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" />
ViewPagerAdapterを使うために新しくクラスを作成し、FragmentPagerAdapterを継承する。
import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; public class ViewPagerAdapter extends FragmentPagerAdapter { public ViewPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { Fragment fragment = null; switch (position) { case 0: fragment = rentFragment.newInstance("rent"); break; case 1: fragment = srvFragment.newInstance("srv"); break; default: break; } return fragment; } @Override public int getCount() { return 2; } @Override public CharSequence getPageTitle(int position) { CharSequence charSequence = null; switch (position) { case 0: charSequence = "貸出"; break; case 1: charSequence = "予約"; break; default:break; } return charSequence; } }
次に、タブを追加するクラスにタブのレイアウトなどを追加する。
TabLayout tabLayout = (TabLayout)findViewById(R.id.tab_layout); tabLayout.addTab(tabLayout.newTab()); tabLayout.addTab(tabLayout.newTab()); ViewPager viewPager = (ViewPager)findViewById(R.id.view_pager); viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager())); tabLayout.setupWithViewPager(viewPager);
タブレイアウトを追加し、ViewPagerにはViewPagerAdapterもセットする。
タブレイアウトに、ViewPagerを関連付けてタブとViewPagerが連動するようになる。
次に、タブとして表示されるFragmentを用意する必要がある。ここでは、rentFragmentとsrvFragmentとして指定してある。
Fragmentを作成するには、右クリック->Fragment->Fragment(Blank) で作成することができる。
XMLファイルも同時に作られるので、名前を指定すれば別々に用意する必要はない。
ただ、要らないメソッドとかがあるので、修正をしないと動かない。ちと面倒だけど一から作るよりはいい。
まずは、表示だけのテストを行いたいので、基本のFragmentだけあればいい。ところが・・・getSupportFragmentManager()が赤くなりエラーになっている。エラー内容をみる限り、そんなメソッドねえよということらしい。
Activityではなく、v7.app.AppCompatActivityを使えということで、importに追加
import android.support.v7.app.AppCompatActivity;
さらに継承の指定を、ActivityからAppCompatActivityに変更する必要がある。ここで、エラーがなくなりBuildできるようなったので、テストしてみる。
不明なエラー
ここからが実際の迷走の始まり。実行したところで、Activityが表示される時にアプリが落ちてしまう。エラーを見ると、以下の文でエラーになっているように見える。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
ここのsuper.onCreate(savedInstanceState);でエラーになるというのだけど、Activityが表示される際にonCreateが呼ばれる。その最初の1行目なので定型のようなもの。何も実行されていない。おかしい・・・
ネットで調べてみても、なかなか情報がない。AppCompatActivityが問題だというのはあるけど、解決策はActivityに変更するという方法ばかり、これではViewPagerが使えない。
海外のサイトでは、バージョンの話がされている。バージョンね・・・
AndroidStudioのバージョン関連
バージョンと言っても、沢山存在する・・・まずは、AndroidStudioのバージョン。それから、AndroidStudioは、Gradleの上で動作しているのでGradleのバージョンとBuiledバージョンも存在する。さらに、Androidプラグインバージョンも存在する。
さらに・・・APIのバージョン。コンパイルバージョン、supportライブラリのバージョン・・・
なんなんだ・・・
まずは、GradleとAndroidプラグインバージョンを調べてみる。File->ProjectStructureで表示される画面で確認できる
これは、変更された数字で、変更前はGradle2.2.1 androidプラグイン1.2.3という数字だった。この画面でも変更が出来る。海外のサイトの情報では、プラグインを2以上にしないとダメということ。単純に2以上を指定してもエラーになる。
Buildすらされなくなってしまう。
Gradleのバージョンもサイトを見る限り新しいバージョンがあるようなのだが・・・
https://jcenter.bintray.com/com/android/tools/build/gradle/
バージョンを変えてみたり、サイトで動いたバージョンなどを指定してもダメ。ここで、かなり時間をとられた。
バージョンについては、以下のサイトを見ないとダメだった・・・
Android Plugin for Gradle Release Notes | Android Studio
プラグインバージョンと関連するGradleバージョンも書かれているので、これに従ってバージョンを指定する。
Gradle2.13 androidプラグイン2.1.2という数字で落ち着いた。
これだけでは済まなかった。次に見ないといけないのは、コンパイルなどのバージョン。
GradleScriptsの中のbuile.gradle(Module:app)の内容を確認する。
android { compileSdkVersion 25 buildToolsVersion "24.0.3" defaultConfig { applicationId "????" minSdkVersion 15 targetSdkVersion 22 versionCode 1 versionName "1.0" }
minSdkVersionは、14以上を指定する必要があるとか、元々15に指定していた。compileSdkVersionは、25と新しいバージョンを指定。buildToolsVersionが問題のようで、ここを変更した。v7.app.AppCompatActivityを使うには、API24.2.0より上という情報があったので、24.0.3を指定。
色々とバージョンを変更してみるとBuildが通るようになった。エラーもなくなったので、なんとか動くようだ。
実際には、supportライブラリーのバージョンも関係するのかもしれない。一応コピペ。
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:25.2.0' compile 'com.google.android.gms:play-services:8.3.0' compile 'com.squareup.okhttp3:okhttp:3.6.0' compile 'com.android.support:support-v4:25.2.0' compile 'com.android.support:support-v13:25.2.0' compile 'com.android.support:design:24.2.0' }
okhttp3は、http通信用なので通信しない場合は、必要なし。
さて、テストを実行してみると、エラーになってしまった・・・
エラー内容は・・・
JDKを1.8にしろと・・・
はい、すみません。してませんでした・・・
テストの再実行・・・・・・あっさり動いた・・・なんだったんだ・・・
でも、表示だけなので、Fragmentの中身を実装しないと。
AppCompatActivityを使うだけで、こんなに大変だとは。AndroidStudioに関係するバージョンは、上げてしまうと今まで作成してプロジェクトがエラーになってしまうので、意識的に変えていなかった。これで、関係性がわかったけど、APIのバージョンを上げると、使っていたメソッドが非推奨になっていたりするので、大変なのだ。なんとかならんのかな~。