u-ryo's blog

various information for coding...

Dream of Deth

| Comments

自分でもどういうわけかわかりませんが、 殺される夢を見ました。 realな夢です。 おかげで、2時半過ぎに寝たばかりなのに、5時頃起きてしまいました。 確かに今は締切に追われて、というか過ぎちゃってて憔悴してますが、 だからといって...

夢なので整合性は無いでしょうけど。 場所は中東。 ナントカ師がナントカしちゃって、 その辺りは記憶の欠損がありますが、 何かその宗派がナントカ師を自派で殺すことに決めてしまい、 でもナントカ師は一日差で逃れてて、 ぼくはその玄関前にいて、 何だかよくわかんないけど殺し合いは嫌だから、 逃げ延びてくれるといいなぁ、とか少し思ったりしてたら、 右上のちょっとした階段の上から、 迷彩服を着たヒゲむくの若い男、 真田太平記の樋口角兵衛(榎木孝明)に似た感じで、でも外国人で。 なので言葉が通じなくて。 何かライフルのように長い銃口を向けてきたから、 違う! 違うよ! 殺さないで! 撃たないで! と思って手を上にあげて、顔を覆ってあーとか思ったら、 後頭部から頭頂部へ2〜3発、 音は聞こえなかったけど頭の後ろ上の方が破裂する感じがして。 えー治るかなこれ、とか思いつつ、 急速に意識が低下して行く... というところで逆に気が付きました。 死を諦観・受容する暇もなく、 何で?! ぼくこんなことで死んでっちゃうの!? という感じでしたね振り返ってみると。 殺される理由なんて、殺される方にはわかる筈もなく、 何となく間違って、もしくは念の為殺されただけのような。 でも向こうは「いや、向かってきたから」とか「怪しい素振りがあったから」 とか言えば済む程度で。 死の直前のぼくの態度は、生に執着し、命を乞うようなとても情けない感じで、 こういう時でも毅然としているためには、 普段余程達観してないとならないのだな、 というのがわかりました。

何でこんな夢、見たんだろう? 前世? でも自動小銃で撃たれてるから現代ですよ。 輪廻転生なんて信じられないですし。 どこかで見たような景色でもないし、何で?? 普段も夢、見てるんでしょうけど、 ぼくはいつも殆ど覚えてないですし、 しかもこれで目が覚めるなんて。 虫の知らせ??

後日

元同僚に話したら、
「ぼくも体調悪い時には見ます。ビルから突き落とされる夢とか」
なるほど! 確かに、ぼくも朝その時から悪寒はしてた感じなので、 悪寒の説明をつけるために、脳が勝手な物語を紡いだ、のかな。 だから単に体調が悪いというsignだったんでしょう。

Rx as Stream API

| Comments

周知のように、Androidではlambdaは書けるようになりましたが Stream APIのようにCollectionsを扱えません。 折角Java8で覚えたのに。 ですが、RxJavaを使うとほぼStream APIのように書けるんですねーへーーー。 非同期や並列処理にも役立つRxJavaの使い方 おかげでloopを回さず一文になったので、 ifの条件節に直接書けるようになりました。 Optionalも出来るんですね。 書いてありますが、キモはtoBlocking().single()でしょうか。

CheckBox.checked Drawable Not Shown

| Comments

ListViewで、各行にcheckboxを表示させるような話があって。 暗い背景なので、defaultのdesignだと見にくいんですね。 なのでcustomの白っぽいのに差し替えようとしたんですが、 なかなかうまく行かなかったのです。 基本的には、res/drawable/に、

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:drawable="@drawable/ic_check_disabled"/>
    <item android:state_checked="true" android:state_pressed="false" android:drawable="@drawable/ic_check_on"/>
    <item android:state_checked="false" android:state_pressed="false" android:drawable="@drawable/ic_check_off"/>
    <item android:state_checked="true" android:state_pressed="true" android:drawable="@drawable/ic_check_on_pressed"/>
    <item android:state_checked="false" android:state_pressed="true" android:drawable="@drawable/ic_check_off_pressed" />
</selector>

と書いて(状態判定は上の行から順番になされる模様)、layoutで、

1
2
3
4
5
<CheckBox
  android:id="@+id/historySelected"
  style="@style/historyListCheckBox"
  android:button="@drawable/selector_checkbox"
/>

というように参照すればいいんです。 が、それだとcheckしても絵が変わらなかったんですね。 別途OnClickListenerに、

1
checkbox.setButtonDrawable(checkbox.isChecked() ? R.drawable.ic_check_on : R.drawable.ic_check_off);

が必要でした、というのはまだわかるんですが、 これを書いてもic_check_onの絵にならなかったんですね(ic_check_offの絵のまま)。 なんでだろ~、1日程悩みました。

結局、 stackoverflowのCan't create custom arrayadapter with appcompat elements inside of itに書いてあったんですけど、 ListViewのAdapterを作る時のContextが、 getApplicationContext()で得られたものであったこと、 が敗因でした。getApplication()でもダメでした。 thisでないと、ic_check_onがdrawされませんでした。

1
adapter = new SimpleAdapter(this, someList, R.layout.some_listview, new String[]{...}, new int[]{R.id.someId,...});

thisで引き回すと、使ってるfieldとか色々引きずるから なるべくgetApplicationContext()にしましょうね、 というのを聞いたことがあるのですが、 なるほどと思ってそうすると、 結構色んな箇所で出るべきものが出なくなるんですよね。 気を付けないとなりません。

CheckBox on ListView

| Comments

Androidでのお話です。 ListViewのそれぞれにCheckBoxをつけたら、 checkboxはcheck出来るものの、項目選択が出来なくなりました。 どうやらonItemClickが呼ばれてない様子。 調べてみると、CheckBoxがfocusを奪ってしまっているそうでした。 (カスタマイズしたListViewに設定したCheckBoxのon/offを行全体で行う)

1
2
android:clickable="false"
android:focusable="false"

が必要とのこと。

また、 background処理後、Adapterの値を変えただけではCheckBoxの見た目に変化はないんですね。 explicitにsetChecked(false)して回らないとなりません。 その際、listView.getChildCount()で取れるcountは、ListViewの全てではなく、見える範囲のListのobjectなんですね! 確かにscrollすればredrawかかってadapterの値が反映されるからいいんですけど、何かしない限りredrawされないから自分で描画しないとならないんですねー。

OnClickListener With ProgressDialog by RxAndroid

| Comments

「clickしたらbackgroundで処理して その間ProgressDialog出して 終わったらProgressDialog消して 終了/失敗dialogを表示する」のを RxAndroid(AxJava)でやる、 というのは、 using()を使うといいらしいです。 cf. RxJavaを使った通信中にProgressダイアログを出す

元々がretrofit2を使ってないので、 retrofit2を使うともうちょっと違うかも。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
@Override
public void onClick(View v) {
    LogUtil.d("診断取得結果をuploadする button");
    uploadButtonEnable(false);
    if (!activity.networkCheck()) {
        activity.genAlertDialog(activity.getString(
                R.string.no_network_connectivity_available_message),
                (dialog, which) -> {});
        uploadButtonEnable(true);
        return;
    }
    Single.using(this::showProgressDialog,
            dialog -> Single.<Boolean>create(this::setUploadSubscriber)
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread()),
            Dialog::dismiss)
            .subscribe(this::controlUploadButtonWithDialog,
                    this::showUploadFailureDialog);
}

private ProgressDialog showProgressDialog() {
    ProgressDialog dialog = new ProgressDialog(activity);
    dialog.setMessage(activity.getString(R.string.history_uploading));
    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    dialog.show();
    LogUtil.d(dialog.toString());
    return dialog;
}

private void setUploadSubscriber(SingleSubscriber<? super Boolean> subscriber) {
    View historyListView = activity.findViewById(R.id.historyListView);
    List<String> selectedList = new ArrayList<>();
    Adapter adapter = null;
    if (historyListView != null) {
        adapter = ((ListView) historyListView).getAdapter();
        for (int i = 0; i < adapter.getCount(); i++) {
            Map<String, String> historyItems = (Map<String, String>) adapter.getItem(i);
            if ("true".equals(historyItems.get("historySelected"))) {
                selectedList.add(historyItems.get("historyCatalogID"));
            }
        }

        if (selectedList.isEmpty()) {
            subscriber.onSuccess(false);
            return;
        }
    }

    try {
        ProcessUtil.callReportDataAll(commonBean.toMapFull(), activity, selectedList);
        if ((!selectedList.isEmpty()
                && !ProcessUtil.uploadSucceeded(selectedList, activity))
                || (selectedList.isEmpty()
                && !ProcessUtil.lastUploadSucceeded(activity))) {
            subscriber.onError(new RuntimeException(""));
            return;
        }
        ProcessUtil.sendTerminalUsageHistory(commonBean.toMap(), activity);
        subscriber.onSuccess(true);
        LogUtil.d(selectedList.toString());

        if (adapter != null) {
            for (int i = 0; i < adapter.getCount(); i++) {
                Map<String, String> historyItems = (Map<String, String>) adapter.getItem(i);
                if ("true".equals(historyItems.get("historySelected"))) {
                    historyItems.put("historySelected", "false");
                    historyItems.put("historySaved",
                            activity.getString(R.string.history_list_already_saved));
                }
            }
        }
    } catch (Exception e) {
        LogUtil.e(e);
        subscriber.onError(e);
    }
}

private void controlUploadButtonWithDialog(boolean hasItemSelected) {
    ListView listView = (ListView) activity.findViewById(R.id.historyListView);
    if (hasItemSelected) {
        activity.genAlertDialog(activity.getString(
                R.string.diagnosis_result_upload_success_message),
                (dialog, which) -> {});
        if (listView != null) {
            for (int i = 0; i < listView.getChildCount(); i++) {
                CheckBox checkBox = (CheckBox) listView.getChildAt(i)
                        .findViewById(R.id.historySelected);
                if (checkBox.isChecked()) {
                    checkBox.setChecked(false);
                    checkBox.setEnabled(false);
                    TextView saved = (TextView) listView.getChildAt(i)
                            .findViewById(R.id.historySaved);
                    saved.setText(activity.getString(R.string.history_list_already_saved));
                    saved.setTextColor(Color.GRAY);
                }
            }
        }
    } else {
        activity.genAlertDialog(activity.getString(R.string.history_nothing_checked),
                (dialog, which) -> {});
    }
    uploadButtonEnable(false);
}

private void showUploadFailureDialog(Throwable e) {
    uploadButtonEnable(true);
    LogUtil.e(checkStr(e.getMessage()), e);
    activity.genAlertDialog(activity.getString(
            R.string.diagnosis_result_upload_failure_message)
                    + "\n" + e.getMessage(),
            (dialog, which) -> {});
}

public void uploadButtonEnable(boolean enable) {
    uploadButton.setEnabled(enable);
    if (enable) {
        uploadButton.getBackground().setColorFilter(null);
    } else {
        uploadButton.getBackground()
                .setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
    }
}