ラベル android開発メモ の投稿を表示しています。 すべての投稿を表示
ラベル android開発メモ の投稿を表示しています。 すべての投稿を表示

2011年6月29日水曜日

ショートカットへの登録方法

今まで、ショートカットの存在を忘れておりました。
通話履歴で、発信・着信のボタンをわざわざウィジェットで用意していましたが・・・ただのボタンなんで、ショートカットで十分でした(アセアセ

と、いうことでアプリに起動用のショートカットを作成する方法を書いておきます。

Manifest部分

    
        
        
    

Manifest部分は、ホーム画面長押し → ホーム画面に追加 ダイアログ → ショートカット で表示されるショートカットを選択するダイアログでの表示を設定しています。
android:name ・・・ ショートカットの内容を定義したクラス名
android:label ・・・ ダイアログ内でのラベル名
android:icon ・・・ ダイアログ内でのアイコン
label,iconは設定しなければアプリ自体のアイコンとアプリ名になります。

IncomingShortcut.Class部分(Activityで実装)
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;

public class IncomingShortcut extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        // ショートカットの内容 インテントを発行
        Intent shortcutIntent = new Intent(getApplicationContext(), "実行するClass(***.class)を記述");
        // 何か渡したい場合は、putExtraで渡す(起動したいタブIDとか
        shortcutIntent.putExtra("****", *);

        // ホーム画面に設置した場合のショートカットの登録内容
        Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        Parcelable iconResource = Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.drawable.call_incoming);
        // ホーム画面に設置した場合に表示されるアイコンの設定
        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
        // ホーム画面に設置した場合に表示されるラベル名の設定
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.incoming));
  
        setResult(RESULT_OK, intent);
        finish();
    }

}
Class部分は、実際にホームに置いた場合の内容を書くみたいです。通話履歴では 発信履歴ボタンと着信履歴ボタンの2つを置いて、表示するタブを変えるためshortcutIntent.putExtraで表示するタブのIDをわたしてます。あと、Activityですので、finish()を呼び出してすぐに終了させてます。

これで、ホーム画面に設置できるショートカットができます。ショートカットにすることで ドックを変更できるホームランチャーなら ドックへの設置も行えるようになります。

(追記)
上のコードだとホームランチャーによっては、ドックへショートカットを置いたときにアイコンがアプリアイコンに変わってしまうことがあるみたいです。
なんで、最初にショートカット作成かどうかを判断するようにして、作成以外の場合は新しいIntentでAvitityを呼び出すようにしました。

2011年6月12日日曜日

android カラーピッカー?カラーセレクター? ダイアログ

カラーピッカーと言うのか、カラーセレクターと言うのかわからないけど、まあカラーが選択できるダイアログのコードを公開します。SSは、2.2バージョンのエミュレーターです。バージョンによってダイアログの色とか変わるんですねぇ(知らなかったですわ

※マーケットに上げているのは色選択数を変更しています。

独自で作っているので 変な書き方してる部分は多めに見てください。なんせ、動けばいいわ程度でかいてますから・・・
■/drawable(各シークバーのスタイル定義)
color_picker_seekbar_r.xml(赤色のシークバースタイル)
color_picker_seekbar_g.xml(緑色のシークバースタイル)
color_picker_seekbar_b.xml(青色のシークバースタイル)
■/layout(各レイアウト)
main.xml(適当なメイン画面)
dialog_picker.xml(シークバーがあるダイアログ)
dialog_selecter.xml(カラーパレットがあるダイアログ)
■/values(文字)
strings.xml
■/src(ソース)
ColorSelectDialog.java
■マーケットURI
https://market.android.com/details?id=jp.hiro711.ColorSelectDialog&feature=more_from_developer
マーケットに上げておきますんで、DLして使ってみてください。

まったくコメントないですが・・・そんなに大変なコードじゃないので大丈夫だと思います。
カラーセレクトダイアログも、AlertDialog.Builderで作りたかったんですがGridViewを使ったら選択後すぐにダイアログを破棄できなかったんで、こんな作りになってしまいました。
普通のListViewで、16色くらいからの選択ならArrayAdapterでアダプターを作ってgetViewをオーバーライドして背景を変えてやって、AlertDialog.BuilderのsetAdapterでやればリストのXMLを作らなくても簡単にできます。注意するところは、setAdapterのOnClickListener実装時にDialogInterface.OnClickListenerを実装してやって、onClick時の最後にdialog.dismiss()でダイアログ破棄してやるくらいかな。

color_picker_seekbar_r.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
    <shape>     
        <corners android:radius="5dip" />      
            <gradient          
                android:startColor="#ff000000"         
                android:centerY="0.5"         
                android:endColor="#ffff0000"         
                android:angle="0"     
            />    
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
         <shape>
          <corners android:radius="5dip" />
          <gradient
           android:startColor="#ff000000"
           android:centerY="0.5"         
           android:endColor="#ffff0000"         
           android:angle="0"       
          />      
         </shape>    
        </clip>  
    </item>
</layer-list>


color_picker_seekbar_g.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:id="@android:id/background">
     <shape>     
         <corners android:radius="5dip" />      
            <gradient          
             android:startColor="#ff000000"         
             android:centerY="0.5"         
             android:endColor="#ff00ff00"         
             android:angle="0"     
            />    
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
         <shape>
          <corners android:radius="5dip" />
          <gradient
           android:startColor="#ff000000"
           android:centerY="0.5"         
           android:endColor="#ff00ff00"         
           android:angle="0"       
          />      
         </shape>    
        </clip>  
    </item>
</layer-list>
color_picker_seekbar_b.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:id="@android:id/background">
     <shape>     
         <corners android:radius="5dip" />      
            <gradient          
             android:startColor="#ff000000"         
             android:centerY="0.5"         
             android:endColor="#ff0000ff"         
             android:angle="0"     
            />    
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
         <shape>
          <corners android:radius="5dip" />
          <gradient
           android:startColor="#ff000000"
           android:centerY="0.5"         
           android:endColor="#ff0000ff"         
           android:angle="0"       
          />      
         </shape>    
        </clip>  
    </item>
</layer-list>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 <Button android:id="@+id/changeTextColorButton"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="Change Text Color"
  />
 <Button android:id="@+id/changeBackgroundColorButton"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="Change Background Color"
  />
 <TextView android:id="@+id/sampleTextView1"
  android:layout_width="fill_parent"
  android:layout_height="40dp"
  android:gravity="center_vertical|center_horizontal"
  android:textSize="20dp"
  android:text="Sample1"/>
</LinearLayout>
dialog_picker.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
     android:padding="4dp"
   android:orientation="vertical">
    <TextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"
     android:paddingRight="5dp"
     android:text="@string/color_picker_viewer"/>
    <TextView android:id="@+id/colorPickerViewer"
     android:layout_width="fill_parent"
     android:layout_height="40dp"
     android:layout_marginLeft="5dp"
     android:layout_marginRight="5dp"/>
    <TextView android:id="@+id/colorPickerTextR"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"
     android:paddingTop="5dp"/>
    <SeekBar android:id="@+id/colorPickerSeekBarR"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:max="255"
     android:padding="8dp"
     android:progressDrawable="@drawable/color_picker_seekbar_r"/>
    <TextView android:id="@+id/colorPickerTextG"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"/>
    <SeekBar android:id="@+id/colorPickerSeekBarG"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:max="255"
     android:padding="8dp"
     android:progressDrawable="@drawable/color_picker_seekbar_g"/>
    <TextView android:id="@+id/colorPickerTextB"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"/>
    <SeekBar android:id="@+id/colorPickerSeekBarB"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:max="255"
     android:padding="8dp"
     android:progressDrawable="@drawable/color_picker_seekbar_b" />
</LinearLayout>
dialog_selecter.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical"
 >
    <GridView android:id="@+id/colorSelectGridView"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent"
     android:verticalSpacing="6dp"
     android:horizontalSpacing="6dp"
     android:numColumns="4"/>
</LinearLayout>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, ColorSelectDialog!</string>
    <string name="app_name">Color Select Dialog</string>
    <string name="color_picker_viewer">Color Viewer(Click to select 16Color)</string>
    <string name="color_picker_red">RED</string>
    <string name="color_picker_green">GREEN</string>
    <string name="color_picker_blue">BLUE</string>
</resources>
ColorSelectDialog.java
package jp.hiro711.ColorSelectDialog;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class ColorSelectDialog extends Activity {
    final int CHANGE_TEXT = 0;
    final int CHANGE_BACKGROUND = 1;

    final int COLOR_TABLE[] = {
        0xffffffff, 0xffc0c0c0, 0xff808080, 0xff000000,
        0xffffc0c0, 0xffff6060, 0xffff0000, 0xff800000,
        0xffffe0c0, 0xffffb060, 0xffff8000, 0xff804000,
        0xffffffc0, 0xffffff60, 0xffffff00, 0xff808000,
        0xffe0ffc0, 0xffb0ff60, 0xff80ff00, 0xff408000,
        0xffc0ffc0, 0xff60ff60, 0xff00ff00, 0xff008000,
        0xffc0ffe0, 0xff60ffb0, 0xff00ff80, 0xff008040,
        0xffc0ffff, 0xff60ffff, 0xff00ffff, 0xff008080,
        0xffc0e0ff, 0xff60b0ff, 0xff0080ff, 0xff004480,
        0xffc0c0ff, 0xff6060ff, 0xff0000ff, 0xff000080,
        0xffe0c0ff, 0xffb060ff, 0xff8000ff, 0xff400080,
        0xffffc0ff, 0xffff60ff, 0xffff00ff, 0xff800080,
        0xffffc0e0, 0xffff60b0, 0xffff0080, 0xff800040
    };

    int mColor = 0xffffffff;
    int mTextColor = 0xffc0c0c0;
    int mBackgroundColor = 0xff000000;

    LayoutInflater inflater;  
    View dialogView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        final Button button1 = (Button)findViewById(R.id.changeTextColorButton);
        button1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mColor = mTextColor;
                colorDialog(CHANGE_TEXT);
            }
        });
        final Button button2 = (Button)findViewById(R.id.changeBackgroundColorButton);
        button2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mColor = mBackgroundColor;
                colorDialog(CHANGE_BACKGROUND);
            }
        });
    }
   
    private void colorDialog(final int where) {
        final String rString = getResources().getString(R.string.color_picker_red);
        final String gString = getResources().getString(R.string.color_picker_green);
        final String bString = getResources().getString(R.string.color_picker_blue);

        inflater = LayoutInflater.from(this);  
        dialogView = inflater.inflate(R.layout.dialog_picker, null);
       
        final TextView textR = (TextView)dialogView.findViewById(R.id.colorPickerTextR);
        textR.setText(String.format("%s(%02X)", rString, (mColor & 0x00ff0000) >> 16));
        final TextView textG = (TextView)dialogView.findViewById(R.id.colorPickerTextG);
        textG.setText(String.format("%s(%02X)", gString, (mColor & 0x0000ff00) >> 8));
        final TextView textB = (TextView)dialogView.findViewById(R.id.colorPickerTextB);
        textB.setText(String.format("%s(%02X)", bString, (mColor & 0x000000ff)));
        final TextView viewer = (TextView)dialogView.findViewById(R.id.colorPickerViewer);
        viewer.setBackgroundColor(mColor);
        viewer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog(0);
            }
        });
       
        final SeekBar seekBarR = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarR);
        seekBarR.setProgress((mColor & 0x00ff0000) >>16);
        seekBarR.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textR.setText(String.format("%s(%02X)", rString, value));
            mColor = (mColor & 0xff00ffff) | value << 16;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textR.setText(String.format("%s(%02X)", rString, value));
            mColor = (mColor & 0xff00ffff) | value << 16;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            int value = seekBar.getProgress();
            textR.setText(String.format("%s(%02X)", rString, value));
            mColor = (mColor & 0xff00ffff) | value << 16;
            viewer.setBackgroundColor(mColor);
        }
    });
    final SeekBar seekBarG = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarG);
    seekBarG.setProgress((mColor & 0x0000ff00) >> 8);
    seekBarG.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textG.setText(String.format("%s(%02X)", gString, value));
            mColor = (mColor & 0xffff00ff) | value << 8;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textG.setText(String.format("%s(%02X)", gString, value));
            mColor = (mColor & 0xffff00ff) | value << 8;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            int value = seekBar.getProgress();
            textG.setText(String.format("%s(%02X)", gString, value));
            mColor = (mColor & 0xffff00ff) | value << 8;
            viewer.setBackgroundColor(mColor);
        }
    });
    final SeekBar seekBarB = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarB);
    seekBarB.setProgress((mColor & 0x000000ff));
    seekBarB.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
                int value = seekBar.getProgress();
            textB.setText(String.format("%s(%02X)", bString, value));
            mColor = (mColor & 0xffffff00) | value;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            int value = seekBar.getProgress();
            textB.setText(String.format("%s(%02X)", bString, value));
            mColor = (mColor & 0xffffff00) | value;
            viewer.setBackgroundColor(mColor);
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            int value = seekBar.getProgress();
            textB.setText(String.format("%s(%02X)", bString, value));
            mColor = (mColor & 0xffffff00) | value;
            viewer.setBackgroundColor(mColor);
        }
    });
    final AlertDialog.Builder alert = new AlertDialog.Builder(this);  
    alert.setView(dialogView);     
    alert.setPositiveButton("OK", new DialogInterface.OnClickListener(){  
        @Override 
        public void onClick(DialogInterface dialog, int idx) {
            switch(where) {
            case CHANGE_TEXT:
                mTextColor = mColor;
                final TextView textView0 = (TextView)findViewById(R.id.sampleTextView1);
                textView0.setTextColor(mTextColor);
                break;
            case CHANGE_BACKGROUND:
                mBackgroundColor = mColor;
                final TextView textView1 = (TextView)findViewById(R.id.sampleTextView1);
                textView1.setBackgroundColor(mBackgroundColor);
                break;
            }
        }
    });  
    alert.show();
}

@Override
protected Dialog onCreateDialog(int id) {
    if(id == 0) {
        final String rString = getResources().getString(R.string.color_picker_red);
        final String gString = getResources().getString(R.string.color_picker_green);
        final String bString = getResources().getString(R.string.color_picker_blue);

        LayoutInflater inflater1 = LayoutInflater.from(this);  
        final View dialogView1 = inflater1.inflate(R.layout.dialog_selecter, null);
        
        final GridView gridView = (GridView)dialogView1.findViewById(R.id.colorSelectGridView);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,   android.R.layout.simple_list_item_1) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                view.setBackgroundColor(COLOR_TABLE[position]);
                return view;
            }
       };
       for(int i = 0; i<COLOR_TABLE.length; i++) {
           adapter.add("");
       }
       gridView.setAdapter(adapter);
       gridView.setOnItemClickListener(new OnItemClickListener() {
           @Override
           public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
               mColor = COLOR_TABLE[arg2];
               final TextView textR = (TextView)dialogView.findViewById(R.id.colorPickerTextR);
               textR.setText(String.format("%s(%02X)", rString, (mColor & 0x00ff0000) >> 16));
               final TextView textG = (TextView)dialogView.findViewById(R.id.colorPickerTextG);
               textG.setText(String.format("%s(%02X)", gString, (mColor & 0x0000ff00) >> 8));
               final TextView textB = (TextView)dialogView.findViewById(R.id.colorPickerTextB);
               textB.setText(String.format("%s(%02X)", bString, (mColor & 0x000000ff)));
               final TextView viewer = (TextView)dialogView.findViewById(R.id.colorPickerViewer);
               viewer.setBackgroundColor(mColor);
               final SeekBar seekBarR = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarR);
               seekBarR.setProgress((mColor & 0x00ff0000) >>16);
               final SeekBar seekBarG = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarG);
               seekBarG.setProgress((mColor & 0x0000ff00) >> 8);
               final SeekBar seekBarB = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarB);
               seekBarB.setProgress((mColor & 0x000000ff));
               dismissDialog(0);
           }
       });

       return new AlertDialog.Builder(this)
            .setView(dialogView1)
            .setNegativeButton("Cancel", null)
            .create();
       }
       return super.onCreateDialog(id);
    }
}

2011年5月23日月曜日

Eclipse ProGuardで最適化

最近知ったのですが、Javaコンパイラは、Cと違って最適化をしてくれないそうです。
私が、C言語を使っていた20年前くらいでも最適化をしてくれていたのにJavaしてくれないそうです。
正確に言うと、最適化をしてくれてるみたいだけど まったく期待できない糞仕様らしいです。
じゃあ、コード段階で最適なコードを書けばいいって話ですが そうすると非常にだらだらと長くなったりと 考えるのが面倒なのでしたくありません。
そこで、最適化ツール『ProGuard』の出番です。
Javaの最適化が期待できないと知って、ProGuardって最適化ツールがあることは知ってたんですが コマンドラインから方法しかできないから面倒だなと思って手を付けておりませんでした。
しかし、android SDKのr8(android 2.3)から標準装備されていたんです!
EclipseのPackageExplorerでパッケージを展開すると、一番下にProguard.cfgなるものがありました。(毎日見ているのにまったく気がつかなかった)
だけどですね・・・勝手に作ってきているのに適応はされてません。
最適化された apkを作るには、default.propertiesの最後に

proguard.config=proguard.cfg

を書き加えて、後はいつも通りにakpを作れば ほらっ最適化された!!!というわけです。
あとは、proguardってフォルダが出来ているんで そいつをバージョン管理につっこんでやります。
(中身が、毎回上書きされるらしいんで)
詳しくは、proguardで検索して頂くと 他の人が詳しく書いてあるので呼んでください。

ちなみに、最適化するのはapkを作るときですので、通常のデバック時(Eclipseかのら実行)では最適化できてませんので お間違いなく。

ということで、今週は最適化したバージョンをマーケットにアップします。

2011年4月15日金曜日

次なるアプリは、着発信信履歴です。

まあ、普通のタブとリストビューで簡単に作れるんじゃないかな・・・

通話ログは、getContentResolver().query()を使えば取得できるらしい。

で、今何をしてるかと言いますと通話ログの取得は無視してリストビューを ごにょごにょといじってます。

自作のMyListVIewクラスを作って、3Dぽいアニメーション付きで表示できないかなとやっております。3Dアニメーションといっても いろいろやるとごちゃごちゃでリストとして意味ないから、ちょっこちょこっとね。

リストのイメージ的には、ガラス板に文字が書かれるみたいな感じにしたいが、ガラス板を描画できませんので、それっぽく(ただ、透過しただけみたくなったが

もう少し、見れそうな感じにしあがったらUPしますね

2011年4月4日月曜日

文字の縁取り方法

テキスト文字の縁取り方法を書いておきます。
と言っても、TextViewでの書き方はわかりません。android.text.styleをざっと見たところできそうになかったけど、何か方法があるのかも知れませんね。(これを使うと、エンボス加工とか、横倍率とか部分的に背景色を変えるとかは出来るみたいです)

で、今回は文字の描画(イメージテキスト?)まあ、drawTextでの書き方です。
方法は、setStyleでStyle.STROKE(輪郭線を描く)を使うだけ・・・
縁取りはExcelみたいな感じに縁を中心に膨らんでいく感じなんで中の文字の大きさを変えたくない場合は、
Paint paint = new Paint();
paint.setAntiAlias(true);

paint.setStrokeWidth(2.0f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
canvas.drawText("テスト", xPos, yPos, paint);

paint.setStrokeWidth(0);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
canvas.drawText("テスト", xPos, yPos, paint);
setStrokeWidthで、縁取り幅を決めて
setColorで、縁取りの色を決めて
setStyle(Paint.Style.STROKE)で、図形の輪郭線のみを描くに設定して
drawTextで、一回文字を書く
setStrokeWidthで、縁取り幅を0に戻して
setColorで、文字色を決めて
setStyle(Paint.Style.FILL)で、図形の内側を塗りつぶすに設定して
drawTextで、もう一度文字を書く

と言う、なんかもったいない処理をしています。
先に内部文字を書けば、縁取り幅を広くすると内部の文字が縁取りに押しつぶされる感じですね。
setStrokeColorというメソッドがあれば、一発で済むのになぁ

もっと、いい方法がありそうだけど初心者の私にはこれしかわかりません。

そうそう、drawTextとかイメージ描画は単位がpx(ピクセル)なんで自動で画面いっぱいに書く場合、解像を考えて書かないとぼやけた文字になっちゃいます。

簡単にpx→dip計算をするなら、
getResources().getDisplayMetrics().densityで、解像度比率(?)を取得して乗算してあげるといいですよ。

2011年3月29日火曜日

なんでだろ

昨日フォントのせいで、スピナーがメモリを食って見たいないこと書いたが・・・
スピナー自体がメモリーを食ってるみたいです。

生成方法間違ってるかな とほほ

と、思ったけどスピナーとは そうゆうものなのかも知れない

2011年3月28日月曜日

外部フォントの取り込み

androidで外部フォントを取り込む場合 assetsフォルダにフォントファイルをぶち込んで、createFromAssets(getAssets(), "フォント名.拡張子")を使うんですがこいつを描画毎に呼び出すと、なぜかメモリーをどんどん食い尽くしていく。
そして、なぜかcreateFromFile("フルパス+フォント名.拡張子")で やるとメモリーを食わない。

なぜなんだろ~ getAssets()が、contextを掴んで 開放できないんだろうか・・・
う~ん わかんねぇ

とりあえず、今回のアプリはSDからも読み込むということで フォントファイルを全てfilesフォルダにコピーしてcreateFromFileで、読み込むことにした。
描画では、メモリーリークしなくなったけど、スピナーの表示でメモリーリークしてるから もう少しコードを見直しだわ

2011年3月14日月曜日

SDからのフォントファイル読み込み

SDカードの\fontsフォルダー内からフォントファイルを取得する方法
ArrayList fontFile = new ArrayList();
String stateSD;
// SDカードがマウントされてるかの確認
stateSD = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(stateSD)) {
    // フォントファイルが格納されているディレクトリを設定
    File file = new File(Environment.getExternalStorageDirectory().getPath() + "/fonts");
    // ディレクトリ内のファイルを取得
    String fileName[] = file.list();
    for(int i = 0; i < fileName.length; i++) {
        // ファイル名を取得
        File selectName = new File(file.getPath() + "/" + fileName[i]);
        // フォントファイル(ttf,otf)を選別
        if(selectName.getName().endsWith("ttf") || selectName.getName().endsWith("otf")){
            fontFile.add(file.getPath()+"/"+fileName[i]);
        }
    }
}
SDカード内の全てのフォルダー内からフォントファイルを取得する方法
ArrayList folderList = new ArrayList();
ArrayList fontFile = new ArrayList();
String stateSD;
// SDカードがマウントされてるかの確認
stateSD = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(stateSD)) {
    // ルートディレクトリを取得
    File file = Environment.getExternalStorageDirectory();
    // ルートディレクトリをfolderListに追加
    folderList.add(file.getPath());
    for(int i = 0; i < folderList.size(); i++) {
        // フォルダを設定
        File subFolder = new File(folderList.get(i));
        // フォルダ内のフォルダ・フィル名を取得
        String selectName[] = subFolder.list();
        for(int j = 0; j < selectName.length; j++) {
            // フォルダ・ファイルを1つづつ設定
            File subFile = new File(subFolder.getPath() + "/" + selectName[j]);
            // 設定された項目がフォルダか判別 フォルダならfolderListに追加/目的のファイルならファイルリストに追加
            if(subFile.isDirectory()) {
                folderList.add(subFolder.getPath() + "/" + selectName[j]);
            }
            else if(subFile.getName().endsWith("ttf") || subFile.getName().endsWith("otf")) {
                fontFile.add(subFolder.getPath() + "/" + selectName[j]);
            }
        }
    }
}
この方法だと、フォルダーに何も入ってない場合selectName.lengthで、例外が発生するかなぁ・・・
try~catchで、例外処理をした方がよさそう。