Blog
http://three-thread.sakura.ne.jp/tt/modules/d3blog/index.php
ThreeThread-Android and iphone Developer
ja
XOOPS Cube
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=44
2018-01-31T15:23:00+09:00
NickQ
買いました!
アンドロイドの開発環境は日々変わっていてついていくのは大変ですが。
設計の勘所さえ押さえてしまえば、良いアプリを生み出すこそが出来ます。
活躍している方のノウハウがつまった本、買わずにはいられないです。
Android アプリ設計パターン入門
著者:日高 正博,小西裕介,藤原聖,吉岡 毅,今井 智章,
製本版,電子版
PEAKSで購入する
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=43
2013-01-24T09:45:13+09:00
NickQ
画面の解像度毎にランチャアイコンや通知アイコンを用意しますが
少し前のAndroidならそれほど解像度がずば抜けているという事は無かったんですが
最近のタブレットや4.0搭載している物などは今までの余り気に留めなかったサイズがもろに
出てしまいますそこで意外と忘れがち、な各解像度で必要なサイズをまとめました
(若干サイズが違うのは私の主観もあります)
drawable-hdpi
drawable-mdpi
drawable-ldpi
drawable-xhdpi
ランチャー
72*72
48*48
32*32
98*98
通知
38*38
25*25
19*19
50*50
drawable-nodpi はそれぞれ解像度判断されない画像を格納する(ただしストレッチさせると画面に合わせて縮小拡大する)
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=42
2013-01-17T16:21:57+09:00
NickQ
Google Cloud Messaging for Android (GCM)今更ながら調査の為、触ってみた。
ついでにGoogle App Engine(GAE)での開発にも少し手を入れようと考えてサーバ側の環境は
GAEで作ってみる事にした。
アプリの概要はこんな感じ
簡単に言うとオンラインのクリップボードを考えていて
Androidアプリにて端末からGAEのサーバアプリにGCMのIDを登録する。
PC側からコピー動作を行ったらGAEサーバへPOSTして
GAEサーバで受けたPOSTにて対象Android端末へ通知を行う。
URLやMailアドレスなどだった場合、Android側で即表示可能にする。
通常受信したデータはAndroid端末のクリップボードに張り付けて利用可能にする。
その際に、PCからショートカット(Ctrl + Alt + C)で一発で飛ばしたい!(Winに限る)
ブラウザからも同じ事がしたい。
どこに使うのか?
PCで見ていたアドレスをAndroid端末に渡してみたい場合
・自分の場合は、技術文献など隣に置いたタブレットに飛ばしてPCで開発、タブレットで読む
Androidにしか設定していないメールアカウントで長文メールを打ちたいけど面倒な場合
・PCで長文打ってAndroid端末のクリップボードでペーストする(誤字脱字軽減)
PCで受信してしまったメールにヤマト伝票番号が有ってそれを端末に飛ばしたい場合
・メールでも可能ですが、ショートカットで一発で送りたい
などなど。
そして作りました。
PC側は流石に、VisualStudioで作りこんでいます。
なかなか快適にオンラインクリップボード出来ますが
GAEが重量課金の為、リリース無料でやるのはちょっと厳しい。
月額にして使ってくれるんだろうか、悩むところ。
寄付もまた微妙だし。
こんな追加機能付けたら行けるだろうか
・特定のパスワードをコピーすると、振動や音で居場所を知らせてくれる(無くした時の発見対策)
GPS起動して座標特定するとか。
・特定のコマンドをコピーすると、写真を撮るとか(画像送信未対応ですが)
・画像のやり取りに対応するとか。
アプリは出来てるんだけど、これは身内で使うかな。
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=41
2013-01-07T13:54:31+09:00
NickQ
以前、自作ArrayAdapterをListViewにセットして
onListItemClickが発生しない場合の方法を投稿していたがそれでも発生しない場合
(ListActivityで無い場合など)
の対策方法として
ArrayAdapter側のgetViewでView自体にOnClickListenerを設定すると
Activity側のsetOnItemClickListenerが呼ばれる様になる方法を紹介します。
Activity側
onCreateなどで
mListView = (ListView) findViewById(R.id.list);
list = new ArrayList();
list = dataSet(this); //<-データをセットする
adapter = new CustomAdapter(this, R.layout.item, list);
mListView .setAdapter(adapter);
registerForContextMenu(mListView );
//アイテムクリック
mListView .setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView arg0, View arg1,int position, long arg3) {
Toast.makeText(getBaseContext(), list.get(position).getPointLocation(), Toast.LENGTH_SHORT).show();
return;
}
});
ArrayAdapterのgetViewで
public View getView(final int position, View convertView, final ViewGroup parent) {
view = inflater.inflate(R.layout.list_item, parent, false);
view.setOnClickListener(new OnClickListener(){
public void onClick(View v){
((ListView) parent).performItemClick(v, position, (long)0);
}
});
}
とすると発生する様になります。
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=40
2012-10-15T14:38:09+09:00
NickQ
TextViewで便利なのはEllipsizingです。
文字列が長ければ末尾に...を付けたり、中間を...に置き換えたりと
いろいろ自動でやってくれますが、これはSingleLineに限っての事
複数行の最後を...に置き換える事は出来ません、検索してもバグなのか仕様なのか
実現する必要性が有ったので、とりあえずTextViewをExtendsして作ってみた
(外国のサイトを参考に修正)
※動作を保障する物ではありません。
public class EllipsizingTextView extends TextView { private static final String ELLIPSIS = "…"; private static final Pattern DEFAULT_END_PUNCTUATION = Pattern.compile("[\\.,…;\\:\\s]*$", Pattern.DOTALL);
public interface EllipsizeListener { void ellipsizeStateChanged(boolean ellipsized); }
private final List<EllipsizeListener> ellipsizeListeners = new ArrayList<EllipsizeListener>(); private boolean isEllipsized; private boolean isStale; private boolean programmaticChange; private String fullText; private int maxLines; private float lineSpacingMultiplier = 1.0f; private float lineAdditionalVerticalPadding = 0.0f; /** * The end punctuation which will be removed when appending #ELLIPSIS. */ //private Pattern endPunctuationPattern;
public EllipsizingTextView(Context context) { this(context, null); }
public EllipsizingTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); }
public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); super.setEllipsize(null); TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.maxLines }); setMaxLines(a.getInt(0, Integer.MAX_VALUE)); setEndPunctuationPattern(DEFAULT_END_PUNCTUATION); }
public void setEndPunctuationPattern(Pattern pattern) { //this.endPunctuationPattern = pattern; }
public void addEllipsizeListener(EllipsizeListener listener) { if (listener == null) { throw new NullPointerException(); } ellipsizeListeners.add(listener); }
public void removeEllipsizeListener(EllipsizeListener listener) { ellipsizeListeners.remove(listener); }
public boolean isEllipsized() { return isEllipsized; }
@Override public void setMaxLines(int maxLines) { super.setMaxLines(maxLines); this.maxLines = maxLines; isStale = true; }
public int getMaxLines() { return maxLines; }
public boolean ellipsizingLastFullyVisibleLine() { return maxLines == Integer.MAX_VALUE; }
@Override public void setLineSpacing(float add, float mult) { this.lineAdditionalVerticalPadding = add; this.lineSpacingMultiplier = mult; super.setLineSpacing(add, mult); }
@Override protected void onTextChanged(CharSequence text, int start, int before, int after) { super.onTextChanged(text, start, before, after); if (!programmaticChange) { fullText = text.toString(); isStale = true; } }
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (ellipsizingLastFullyVisibleLine()) { isStale = true; } }
public void setPadding(int left, int top, int right, int bottom) { super.setPadding(left, top, right, bottom); if (ellipsizingLastFullyVisibleLine()) { isStale = true; } }
@Override protected void onDraw(Canvas canvas) { if (isStale) { resetText(); } super.onDraw(canvas); }
private void resetText() { //String workingText = fullText; StringBuilder workingText = new StringBuilder(fullText); boolean ellipsized = false; Layout layout = createWorkingLayout(fullText); //Layout layout = createWorkingLayout(workingText); int linesCount = getLinesCount(); if (layout.getLineCount() > linesCount) { // We have more lines of text than we are allowed to display. //workingText = fullText.substring(0, layout.getLineEnd(linesCount - 1)).trim(); workingText = new StringBuilder(fullText.substring(0, layout.getLineEnd(linesCount - 1))); //workingText = fullText.substring(0, layout.getLineEnd(linesCount - 1)); while (createWorkingLayout(workingText.toString() + ELLIPSIS).getLineCount() > linesCount) { //int lastSpace = workingText.lastIndexOf(' '); // int lastSpace = workingText.length() - 1; //if (lastSpace == -1) { if ((workingText.length() - 1) == -1) { break; } //workingText = workingText.substring(0, lastSpace - 1); workingText.delete(workingText.length() - 1, workingText.length()); } // We should do this in the loop above, but it's cheaper this way. if(workingText.length() > 2){ //workingText = workingText.substring(0, workingText.length() - 2); workingText.delete(workingText.length() - 2,workingText.length()); } //workingText = endPunctuationPattern.matcher(workingText).replaceFirst(""); //workingText = workingText + ELLIPSIS; //workingText = new StringBuilder(endPunctuationPattern.matcher(workingText.toString()).replaceFirst("")); workingText.append(ELLIPSIS); ellipsized = true; } if (!workingText.equals(getText())) { programmaticChange = true; try { setText(workingText); } finally { programmaticChange = false; } } isStale = false; if (ellipsized != isEllipsized) { isEllipsized = ellipsized; for (EllipsizeListener listener : ellipsizeListeners) { listener.ellipsizeStateChanged(ellipsized); } } }
/** * Get how many lines of text we are allowed to display. */ private int getLinesCount() { if (ellipsizingLastFullyVisibleLine()) { int fullyVisibleLinesCount = getFullyVisibleLinesCount(); if (fullyVisibleLinesCount == -1) { return 1; } else { return fullyVisibleLinesCount; } } else { return maxLines; } }
/** * Get how many lines of text we can display so their full height is visible. */ private int getFullyVisibleLinesCount() { Layout layout = createWorkingLayout(""); int height = getHeight() - getPaddingTop() - getPaddingBottom(); int lineHeight = layout.getLineBottom(0); return height / lineHeight; }
private Layout createWorkingLayout(String workingText) { return new StaticLayout(workingText, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(), Alignment.ALIGN_NORMAL, lineSpacingMultiplier, lineAdditionalVerticalPadding, false /* includepad */); }
@Override public void setEllipsize(TruncateAt where) { // Ellipsize settings are not respected }}
resetText()では表示時に表示対象の文字列を抜き出して後ろに...を足しています。
ただ、正確には日本語の場合フォントで比率などの計算をしないとずれるので2文字分引いている。
とりあえず動いたが、処理が遅いのでリファクタリングが必要かな。
※ご利用は自己責任で。
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=39
2012-08-28T13:59:20+09:00
NickQ
コーディングしていると普通に
if(str != null){
}
if(str.length() > 0){
}
などで文字列を判断していますが、上記だと””が引っかからないなど
if文を二重にしたりしていませんか?(null判断とlengthは同じifにかけられません)
そこで便利なのが
TextUtils.isEmpty(str)
Nullもlength 0も同時に判断してくれます、もちろんnullもしくはlength=0ならtrueが返ります。
もう少し早く気付けば良かった。。。
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=38
2012-06-08T10:47:11+09:00
NickQ
Androidで開発していると何かとListActivityを使いますが、画像を入れたり
ちょっとカッコよく表示したり、自作のLayoutを使いたくなります。
そこで、ArrayAdapterを作ってListActivityにセットしてさあと思いきやいくらクリックしても
onListItemClickが発生しないという事態になる方も多いはず。
原因は、ListActivityのItemにArrayAdapterが紐づいている訳ですので
ArrayAdapterで発生しない限り、ListActivityには通知されません。
そこで、発生させる方法として・・・
ArrayAdapter側に「OnClickListener」をインプリメントして「onClick」メソッドを追加します。
すると、ListActivityの「onListItemClick」が発生するようになります。
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=37
2012-02-22T15:53:37+09:00
NickQ
CM4IS01にBluetoothのデバイスを実装しようと思って、CyanogenModを取得しようと考えた。
ソースを取得するのにgitサーバが落ちたままなの気づかなくてかなり苦労してしまった。
repo syncを実行すると
android.git.kernel.org[0:149.20.77]:error=Connection refused ...
fatal:unable to connect a socket(Connection refused)
が発生して進まない、ポート9418が開いてないのかと思い調べるが問題無し、いろいろ調べるとサーバが落ちたままだそうで。
ocdeaurowa.orgが非公式ミラーをしているのそちらを利用させてもらう。
repoで取得したManifest.xmlを編集して
fetch="git://android.git.kernel.org/" の行を
fetch="git://codeaurowa.org" にして更新して無事取得
取得には時間がかかりますけどね〜 さて、どうやってビルドしようか。
-
Android OS
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=36
2011-12-02T16:52:43+09:00
NickQ
最近の端末は、2.2以降もが搭載されているのかな?
まだ、2.1以前はあるのかな
IS01は別として、Xperiaは2.1だったかないずれにせよどこから作るかちょっと悩むが
タブレットが多い昨今、レイアウト系の話を考えると2.2以降が良いのかなと考える。
-
http://three-thread.sakura.ne.jp/tt/modules/d3blog/details.php?bid=35
2011-12-01T12:05:01+09:00
NickQ
いろいろと開発案件が乱立していて、こちらに時間を割けませんでしたが少し落ち着いたので。
MediaSwitch系列のバージョンアップ
Bluetooth系の新アプリ
のプロジェクトを開始します。