2011年01月19日

Viewの高さを動的に変更したい!

あまり見かけないような気がする設定ですが、最初画面の向きが切り替わった時ListViewの高さをコードで制御したいと思っていましたが、やり方が分からず断念してました。
しかし、突如追加機能として、ListViewの高さを可変にしたいと思いつき、それにともなってViewの高さをコードで制御することに再挑戦。

いくつかのサイトを参考にさせていただくと、画面を傾けた時protected void onSaveInstanceState(Bundle outState){}で設定を保存し、onCreate(){}のsavedInstanceStateで設定を戻すとか、onPauseで事前に設定を保存するとか違う情報があり、少々錯綜していました。

そこで自分のプログラムのログを観察すると、(少なくとも実機では)画面が縦または横に切り替わった後public void onConfigurationChanged(Configuration newConfig){}が呼ばれており、事前にonPause(){}やonSaveInstanceState(){}は呼ばれてはいないようでした。
そして、結局onCreate(){}で設定が初期化されてしまうので、思った通りに動作しませんでした。

うーん。
また、しばらく試行錯誤……

最終的に、JavaDrive様で見つけたLayoutParamsで高さと幅を返すメソッドを利用し、onCreate(){}とonConfigurationChanged(){}で呼び出すことで成功しました。
以下が成功したメソッドの列挙抜粋。


LinearLayout linearLayout;

public void onCreate(Bundle savedInstanceState) {
linearLayout = (LinearLayout)findViewById(R.id.lvll); // ListViewの高さを設定するためのレイアウト
listView = (ListView)findViewById(R.id.lv); // リスト表示用ListView lv

linearLayout.setLayoutParams(createParam());
}

private LinearLayout.LayoutParams createParam(){
WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
Display disp = wm.getDefaultDisplay();
int w = disp.getWidth();
int h = disp.getHeight() / 2;

return new LinearLayout.LayoutParams(w, h);
}

@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);

linearLayout.setLayoutParams(createParam());
}


// main.xmlの抜粋

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:id="@+id/lvll"
   >
   <ListView
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:id="@+id/lv"
   />
</LinearLayout>


まあ、なんのためにこんな設定が必要か分からないと思いますし、あまり参考にならないと思いますが、ListViewに限った話ではないと思うので、一応。
(しかし、別途あるTextViewの高さやシステムの通知エリアの大きさを取得できない問題が残ったままなのでした。(涙))
posted by 白虹 at 00:10| Comment(0) | TrackBack(1) | Android開発

2011年01月17日

ハマった、ハマった

いやあ、この数日またハマりまくりました。
全体的な動作を再び、いや三度、じゃない、四度かな?変更したこともありましたが、今回ハマったのはプログレスダイアログ。
まあ、普通の人はハマらないと思うんですけどね。

今回のハマりどころ。

1.構造的にどこにプログレスダイアログを設定すればいいか分からなかった。
2.ようやく設定したと思ったらプログレスダイアログがでない。(実際は動作実績があったはずの裏で動かす作業の方だった)

まず1番目の問題については、参考書を見ても、ググってみても、出てくる情報としてはProgressDialogをどのように出すかというサンプルで、分かりやすいようにProgressDialogのみに絞って解説されているので、どのように呼び出せばいいのか分からなかったところ。
RunnableをimplementsしたActivityのonCreate()でProgressDialogのインスタンスをつくり、そのままボタンを設置して、クリックすると時間のかかる処理が動くというのが典型的なものでしたが、メインのクラスのonCreate()にProgressDialogのインスタンスを作ったらアプリ起動と同時に表示されてしまうし、できれば2000行くらいに長くなったメインのクラスからは分離したいところでした。
そこで長〜らく試行錯誤した結果public class SampleProgress extends Activity implements Runnable {}なので、Intentで呼び出すことにしました。
本当に合っているのか分からないけど、一応ActivityだからIntentかな、と。
そして、アプリのタイトルを非表示(requestWindowFeature(Window.FEATURE_NO_TITLE))にし、よく見かけるような元の画面と重なって表示するためにActivityの背景を透明にする方法をググって参考とさせていただき、なんとか表示はできるようになりました。

しかし、第2の問題。
実際の処理を動かしてみると、デバッグモードだとできる(ことがある)のに、そのまま動かすと何も起こらないという珍妙な現象。
ステップバイステップで動かして見ても動作が追えない。(途中で終わってしまう)
これがどーしても分からず、デバッグモードで追えない現象なんて自分には解決不能!と絶望してしまいました。

しかし、それは翌日あっさり解決。
先に値を設定してからThreadをstartさせるべきところを、Threadの後に設定していたケアレスミスでした。
なぜ、デバッグモードだとできることがあったのかは不明。

それにしてもケアレスミスが多くて困ります。
一番多いのはToastの最後に.show()を付け忘れること!
なんとかなりませんかね?
posted by 白虹 at 22:01| Comment(0) | TrackBack(0) | Android開発

2011年01月11日

適当過ぎるぞ!プラグラマー(選択項目によってContextMenuの内容を変える)

ListViewにコンテキストメニューを適用するというのは頻繁に使いたくなるものですが、リストの項目の内容に応じてメニューの内容を変化させたかったのです。
具体的にはListViewの最上段にはリストのヒエラルキーを変えるための記号を置いて、そこではコンテキストメニューを表示させたくなかったのです。
しかし、ググっても適切な解説が見つかりませんでした。
そんな中参考にさせていただいたのは

yusukezzzの日記 様
http://yusukezzz.net/blog/archives/1897

てなことで、「ContextMenuInfoをAdapterContextMenuInfoにキャスト」という情報だけで理論的なことは何も考えずに、プラグラマーの本領発揮?により、onCreateContextMenuを以下のように記載。

    public void onCreateContextMenu(ContextMenu menu,View v,ContextMenuInfo info){
     super.onCreateContextMenu(menu,v,info);
     AdapterContextMenuInfo acmi = (AdapterContextMenuInfo)info;

     ListView list = (ListView)v;
ListData ld = (ListData)list.getItemAtPosition(acmi.position); // 以下2行はListViewをカスタマイズしているため
String selectedItem = ld.getTitle(); // 通常は(多分)コメント行のようになると思います。
     // ListView list = (ListView)v;
     // String selectItem = (String)list.getItemAtPosition(position);

if(! selectItem.equals(CHG_MARK)){
menu.add(0,ITEM_COPY,0,"コピー");
     menu.add(0,ITEM_EDIT,0,"編集");
    menu.add(0,ITEM_DEL,0,"削除");
}
    }

思った通り、動いた!
素晴らしい!
ありがとう、yusukezzz様。
しかし、やはり理論はまったく理解できていないのでした。
本当にこれでいいのか?適当過ぎるぞ!

それでもとりあえず前に進むのでした。

posted by 白虹 at 23:37| Comment(0) | TrackBack(0) | Android開発