@adakodaさんが面白い事をしていらっしゃったのでインスパイア。
[Android] アクションバーを画面下側から表示させてみました
http://www.adakoda.com/adakoda/2012/02/android-47.html
アプリからでも出来るのでは?
アプリケーションではアプリを初期化する際にsetContentView()するんで、setContentView()で出来たView群が画面上の全てだと思いがちです。しかーし画面上に存在する以上タイトルバーやActionBarなども当然Viewの一種なわけです。ちゅーことはアプリケーションのトップレベルのViewを取れたらタイトルバーやActionBarも操作出来るのでは無いでしょうか!?
そもそもまずトップレベルのViewをアプリケーション側から取得する事が出来るのか。出来ます。ActicvityからWindowを取り出してgetDecorView()するだけ。
View root = activity.getWindow().getDecorView()
ではこのViewどういう構造になっているか。Viewツリーをダンプしてみましょう。ViewツリーのダンプはViewの階層構造をダンプするスニペットを参考に。
View v = getWindow().getDecorView(); Util.dumpViewTree(v, "");
吐かれたのがこれ。Android4.0.2のGalaxy Nexusで、プロジェクトはEclipse+ADTで生成して出来たものを全く触らずに利用。ターゲットは4.0です。
Util D com.android.internal.policy.impl.PhoneWindow$DecorView Util D android.widget.LinearLayout Util D com.android.internal.widget.ActionBarContainer Util D com.android.internal.widget.ActionBarView Util D android.widget.LinearLayout Util D android.widget.ImageView Util D android.widget.LinearLayout Util D android.widget.TextView Util D android.widget.TextView Util D com.android.internal.widget.ActionBarView$HomeView Util D android.widget.ImageView Util D android.widget.ImageView Util D com.android.internal.widget.ActionBarContextView Util D android.widget.FrameLayout Util D android.widget.LinearLayout Util D android.widget.TextView Util D com.android.internal.widget.ActionBarContainer
"com.android.internal.widget.ActionBarContainer"てのが居ますね。露骨ですね。なんで二個あるのかはちょっとわかりません。
findViewsWithClass()を拡張
じゃあ"com.android.internal.widget.ActionBarContainer"を取り出して操作したらいいんじゃまいか?どうやって取り出すの。ああ、何かそういうエントリを昨日見たよ。あった。List<T> findViewsWithClass(View v, Class<T>)。助かるわー。#ステマ
しかしどうもList<T> findViewsWithClass(View v, Class<T>)ではClass<T>を使っています。com.android.internal.widget.ActionBarContainerは名前しか判らないのでちょっと拡張する必要がありそうですね。
こうなった
public static <T extends View> List<T> findViewsWithClass(View v, Class<T> clazz) {
List<T> views = new ArrayList<T>();
findViewsWithClass(v, clazz.getName(), views);
return views;
}
public static List<View> findViewsWithClassName(View v, String className) {
List<View> views = new ArrayList<View>();
findViewsWithClass(v, className, views);
return views;
}
private static <T extends View> void findViewsWithClass(View v, String clazz, List<T> views) {
if (v.getClass().getName().equals(clazz)) {
views.add((T) v);
}
if (v instanceof ViewGroup) {
ViewGroup g = (ViewGroup) v;
for (int i = 0; i < g.getChildCount(); i++) {
findViewsWithClass(g.getChildAt(i), clazz, views);
}
}
}
これでcom.android.internal.widget.ActionBarContainerを簡単に取り出せます。
View root = activity.getWindow().getDecorView(); List<View> views = Util.findViewsWithClassName(root, "com.android.internal.widget.ActionBarContainer");
試しにsetVisibility(View.GONE)してみる
では試しに取り出したcom.android.internal.widget.ActionBarContainerをView.GONEで消してみましょう。
View root = activity.getWindow().getDecorView();
List<View>l views = Util.findViewsWithClassName(root, "com.android.internal.widget.ActionBarContainer");
for(View v : views){
v.setVisibility(View.GONE);
}
消えたー!操作出来る。当たり前だけど。
actionBarUpsideDown(Activity activity)
Viewツリーのダンプを見ると、事実上ルートのコンテナはcom.android.internal.policy.impl.PhoneWindow$DecorView直下のLinearLayout。多分Vertical。つまり、この人にいるcom.android.internal.widget.ActionBarContainerをremoveView()で消して、addView()で足すとケツに移動するのではないか!?
という事でメソッドを作成。
public final static void actionBarUpsideDown(Activity activity) {
View root = activity.getWindow().getDecorView();
View firstChild = ((ViewGroup) root).getChildAt(0);
if (firstChild instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) firstChild;
List<View> views = Util.findViewsWithClassName(root, "com.android.internal.widget.ActionBarContainer");
if (!views.isEmpty()) {
for (View vv : views) {
viewGroup.removeView(vv);
}
for (View vv : views) {
viewGroup.addView(vv);
}
}
}
else{
Log.e(TAG, "first child is not ViewGroup.");
}
}
試す
メソッドにしたので試すのは簡単ですね
setContentView(R.layout.main); Util.actionBarUpsideDown(this);
キタワァ.*・゜゚・*:.。..。.:*・゜(n‘∀‘)η゚・*:.。. .。.:*・゜゚・*!!!!!☆
まとめ
ICS以外で呼ぶとどうなるか試してないので適宜何とかして下さい。
ActionBarが上に居るのは個人的に良く思っていないので、これ使って下に表示させる様にしていきたい。



0 件のコメント:
コメントを投稿