リフレクションを屈指して切り替えるなんて、方法は、ダメである。
OSのバージョンが上がって中のTabHost 内のコードが変わったらNGだし、一見、簡単そうだけど、
結構、TabWidget の部分が、深いリフレクションになってしまう。
やはり、Tab内でのActivity切り替わることを前提とした、ActivityGroup を使うしかないと思う。
ActivityGroup を使うところまでは、皆、すぐに書けると思うが、
問題は ActivityGroup で切り替わったタブから別のタブに切り替え、また元の ActivityGroup を使用したタブに
タブを切り替えで戻った時に、初期表示させることである。
Handler を使うと簡単に実現できる。
以下、サンプルで、まずは、ActivityGroup
import android.app.ActivityGroup;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.ViewGroup;
import android.view.Window;
/**
* ParentActivityGroup
*/
public class ParentActivityGroup extends ActivityGroup{
private ViewGroup container;
public static Handler Phandler; // static で宣言
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.container);
container = (ViewGroup)findViewById(R.id.container);
// 任意の TabChild1Activity を 初期表示
showChild1();
Phandler = new Handler(){
@Override
public void handleMessage(Message msg){
Log.d("sample","# handleMessage what = "+msg.what+" obj = "+msg.obj);
Log.d("sample","# getCurrentActivity().getLocalClassName() = "+getCurrentActivity().getLocalClassName());
Log.d("sample","# getCurrentActivity().getClass().getName() = "+getCurrentActivity().getClass().getName());
removeMessages(0);
showChild1();
}
};
}
// TabChild1Activity を表示
public void showChild1(){
container.removeAllViews();
Intent intent = new Intent(this, TabChild1Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Window window = getLocalActivityManager().startActivity("child1Activity",intent);
container.addView(window.getDecorView());
}
// TabChild2Activity を表示
public void showChild2(){
container.removeAllViews();
Intent intent = new Intent(this, TabChild2Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Window window = getLocalActivityManager().startActivity("child2Activity",intent);
container.addView(window.getDecorView());
}
}
ちょっと余計に書いたログは、ActiGroup が Activity の切り替え前に表示していた Activityのクラスを示すもの。
getCurrentActivity().getLocalClassName() は、AndroidManifest.xml で定義する package を省いたクラス名
getCurrentActivity().getClass().getName() で手慣れたクラス名を取得でき違和感がない。
タブ内の Actovity 側から、
*1.showChild2();
のように呼び出して切り替えを実行する。
TabActivity の方では、OnTabChangeListener を定義
public class TabReplaceActivity extends TabActivity{
protected static String INIT_TAG = "Tab1";
private TabHost host;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabmain);
host = getTabHost();
// 1番目のタブに、ActivityGroup を指定
TabSpec tab1 = host.newTabSpec(INIT_TAG);
tab1.setIndicator("Edit", getResources().getDrawable(android.R.drawable.ic_menu_edit));
tab1.setContent(new Intent(this,ParentActivityGroup.class));
host.addTab(tab1);
TabSpec tab2 = host.newTabSpec("Tab2");
tab2.setIndicator("Help", getResources().getDrawable(android.R.drawable.ic_menu_help));
tab2.setContent(new Intent(this,HelpActivity.class));
host.addTab(tab2);
// 初期表示
host.setCurrentTabByTag(INIT_TAG);
// OnTabChangeListener で、通知
host.setOnTabChangedListener(new TabHost.OnTabChangeListener(){
@Override
public void onTabChanged(String tabId){
// ActivityGroup のタブに切り替わった時のみ、Handler でメッセージ送信
if (tabId.equals(INIT_TAG)){
ParentActivityGroup.Phandler.sendMessage(Message.obtain());
// 情報を渡すなら以下、
//Message message = TabParentActivityGroup.Phandler.obtainMessage(0,INIT_TAG);
//TabParentActivityGroup.Phandler.sendMessage(message);
}
}
});
}
}
*1:ParentActivityGroup)getParent(