2012年7月15日日曜日

MacでInkscapeを使う(日本語化編)

Inkscapeの言語設定を変えるだけなんですが、ぱっと見でどこから設定を行うのか分からなかったのでメモしておく。


設定方法

1. Inkscape Preferencesを開く([shift] + [control] + [P])
2. Interfaceを選択する
3. LanguageでJapanese (ja) を選択する
4. Inkscapeを再起動する

日本語に切り替えると、こんな感じです。


MacでInkscapeを使う(Altキー編)

デフォルトの設定(X11)ではAltキーが使えないので、Altキーを使えるようにする方法をメモしておく。
設定方法

1. Inkscapeを起動する
2. [command] + [ , ]でX11の環境設定を開く
3. 「OptionキーでAlt_LとAlt_Rを送信」にチェックを入れる
以上の設定で、OptionキーがAltキーの代用になります。

Altキーの用途ですが、重なっている要素の下にあるものを選択するときによく使いますね。
※ アイコンの最下層に配置した影を微調整したい場合など

[alt] + [左クリック]で重なっている要素を上から順に選択できます。


Mac OS X Lion Git導入メモ

はじめに

この手順はXcodeをインストールする前提です。
Xcodeが不要な方は、本家のDownloadページからdmgファイルを落としてインストールするのが王道なんでしょうか?
ちょっと、この辺り確認していないのですみません...

手順

1. App StoreからXcodeをインストールする ※要Apple ID
2. Xcodeを起動
3. [command] + [ , ]でPreferences...を開く
4. Downloadsタブにある「Command Line Tools」をインストールする
以上です。

PATHの設定は不要で、上記の手順のみでターミナルからGitのコマンドが使えるようになります。

2012年7月14日土曜日

実機で解像度を変更してデバッグする方法

am display-size コマンドを使ってみたメモです。

情報源は@yanzmさんのブログから。
Y.A.M の雑記帳
Google I/O 2012 セッションまとめ : So You've Read the Design Guide; Now What?
http://y-anz-m.blogspot.jp/2012/07/google-io-2012-so-youve-read-design.html

注意
アプリの強制終了が発生する場合がありました。
コマンドの実行は自己責任でお願いします。

コマンド

解像度の指定
adb shell am display-size <解像度>

解像度を元に戻す
adb shell am display-size reset

※画面の回転とかアプリ起動とかやると解像度の変更が反映されます。

動作確認

次の3機種で動作確認を行いました。
・Nexus S
・ICONIA TAB A500
・IS11LG

Nexus SとICONIA TAB A500はコマンドが使えることを確認しました。
IS11LGではコマンド無くて使えずです。
3.xからなのかな?
※Nexus S、ICONIA TAB A500両機ともに、コマンド実行時にSecurityExceptionが発生

下記は、ICONIA TAB A500で
adb shell am display-size 1024x600
を実行したスクリーンショットです。(ICONIA TAB A500の本来の解像度は1280x800)
スクリーンショットで黒く表示されている部分までが、本来の表示領域です。

因にDensityの変更は出来ないそうです。
Nexus S(high density)でWQVGA(low density)とかやると画面がむちゃくちゃになるのでご注意を。

Mac OS X Lion キーボードショートカット メモ

スクリーンショット

全画面
[command] + [shift] + [3]
矩形選択
[command] + [shift] + [4]
ウィンドウ
矩形選択モードで[space]

スクリーンショットを撮ったときの、シャッター音の演出が良いですね。

Finder ファイルのカット&ペースト(移動)

[command] + [C] でファイルを選択して
[command] + [option] + [V]

※使えるのはMac OS X Lionからのようです。

Finder 指定したディレクトリに移動

[command] + [shift] + [G]

Finder 新規フォルダの作成

[command] + [shift] + [N]

アプリケーションの強制終了

[command] + [option] + [esc]

2012年7月9日月曜日

DialogFragmentメモ(2)

前回の結論として、DialogFragmentのonCreateView()よりonCreateDialog()をOverrideした方が良さそうだったのでやってみたメモ。

注意(2012/07/09追記)
ダイアログ表示状態で画面を回転してダイアログのボタンを押すとNullPointerExceptionで落ちることに気付きました...
落ちる場所はDialogButtonClickListenerの65行目からのif文でどちらのダイアログか判別している部分です。
修正してブログ更新する予定。。

DialogFragmentメモ
http://neta-abc.blogspot.jp/2012/06/dialogfragment.html




ただ、DialogFragmentのonCreateDialog()の中で表示内容を設定してしまうとダイアログの数だけDialogFragmentを継承したクラスを作らないといけないので、今回はDialogFragmentを継承したクラスを1つ作り、それを使い回せるようにすることを目標にやってみました。

方針(ざっくり)
(1) DialogFragmentを継承したAlertDialogFragmentクラスを作成する
(2) ダイアログ表示内容の設定はダイアログの呼び出し元で行う
(3) (2)で作成したダイアログ表示内容をsetArguments()でFragmentに設定する
(4) AlertDialogFragmentのonCreateDialog()をOverrideして、(3)で設定したダイアログの表示内容をAlertDialogFragmentに反映する

といったところです。

ただし、setArguments()を使ってFragmentに渡せる引数はBundle型なので、AlertDialog.Builderを継承したクラスを作成してSerializableインターフェースを実装しています。※BundleのputSerializable()を使うためです。

コード
MainActivity.java
package com.example.alertdialogfragment;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements OnClickListener {

    private AlertDialogFragment mDialogFragment1;
    private AlertDialogFragment mDialogFragment2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
    }

    public void onClick(View view) {
        DialogButtonClickListener listener = new DialogButtonClickListener();
        AlertDialogFragment.Builder builder = new AlertDialogFragment.Builder(this);
        Bundle params = new Bundle();

        switch (view.getId()) {
            case R.id.button1:
                builder.setTitle("Title1");
                builder.setMessage("Message1");
                builder.setPositiveButton("POSITIVE", listener);
                builder.setNeutralButton("NEUTRAL", listener);
                builder.setNegativeButton("NEGATIVE", listener);

                params.putSerializable("builder", builder);

                mDialogFragment1 = new AlertDialogFragment();
                mDialogFragment1.setArguments(params);
                mDialogFragment1.setCancelable(false);
                mDialogFragment1.show(getSupportFragmentManager(), "dialog1");
                break;
            case R.id.button2:
                builder.setTitle("Title2");
                builder.setMessage("Message2");
                builder.setPositiveButton("POSITIVE", listener);
                builder.setNeutralButton("NEUTRAL", listener);
                builder.setNegativeButton("NEGATIVE", listener);

                params.putSerializable("builder", builder);

                mDialogFragment2 = new AlertDialogFragment();
                mDialogFragment2.setArguments(params);
                mDialogFragment2.setCancelable(false);
                mDialogFragment2.show(getSupportFragmentManager(), "dialog2");
                break;
        }
    }

    private class DialogButtonClickListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            String dialogName = "";
            if (dialog.equals(mDialogFragment1.getDialog())) {
                dialogName = "ダイアログ1";
            } else if (dialog.equals(mDialogFragment2.getDialog())) {
                dialogName = "ダイアログ2";
            }
            switch (which) {
                case DialogInterface.BUTTON_POSITIVE:
                    Toast.makeText(getApplicationContext(), dialogName + ":POSITIVE",
                            Toast.LENGTH_SHORT).show();
                    break;
                case DialogInterface.BUTTON_NEUTRAL:
                    Toast.makeText(getApplicationContext(), dialogName + ":NEUTRAL",
                            Toast.LENGTH_SHORT).show();
                    break;
                case DialogInterface.BUTTON_NEGATIVE:
                    Toast.makeText(getApplicationContext(), dialogName + ":NEGATIVE",
                            Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
}
AlertDialogFragment.java
package com.example.alertdialogfragment;

import java.io.Serializable;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;

public class AlertDialogFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Bundle params = getArguments();
        AlertDialog.Builder builder = (AlertDialog.Builder) params.getSerializable("builder");
        return builder.create();
    }

    public static class Builder extends AlertDialog.Builder implements Serializable {

        private static final long serialVersionUID = 1L;

        public Builder(Context context) {
            super(context);
        }

        public Builder(Context context, int theme) {
            super(context, theme);
        }

    }

}

Cancelableの設定はAlertDialog.Bulderではなく、DialogFragmentのsetCancelabre()を使うので注意です。ちょっとはまりました...
DialogFragmentを使うと画面を回転したときにダイアログを再表示してくれるので良いですね。

FragmentのsetArguments()については、ここを参考にしました。
Y.A.M の 雑記帳
Fragment で setArguments() してるサンプルが多いのはなぜ?
http://y-anz-m.blogspot.jp/2012/04/androidfragment-setarguments.html

2012年7月1日日曜日

PagerTabStripの使い方

Support Package rev.9で追加されたPagerTabStripを使ってみたのでメモしておく。


PagerTabStripはViewPagerにタブの表示を追加するものです。
スクリーンショット上部のPage1~3の部分がPagerTabStripです。
後述しますが下部に配置することもできます。
類似のものにPagerTitleStripがありますが、相違点はPagerTabStripではタブの部分をタップしてページ切り替えが可能なところです。

使い方
・ViewPagerの子要素としてPagerTabStripを配置
・layout_gravity="top"で上、"bottom"で下に表示
・PagerTabStrip#setDrawFullUnderline(true)で下線を表示
・PagerTabStrip#setTabIndicatorColor()でインディケーターと下線の色を指定

コード
activity_main.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
    <android.support.v4.view.PagerTabStrip
        android:id="@+id/pager_tab_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33B5E5"
        android:textColor="#FFFFFF"
        android:paddingTop="10dp"
        android:paddingBottom="10dp" />
</android.support.v4.view.ViewPager>
MainActivity.java
package com.example.pagertabstripsample;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;

public class MainActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_tab_strip);
        FragmentPagerAdapter fragmentPagerAdapter = new MyFragmentPagerAdapter(
                getSupportFragmentManager());

        viewPager.setAdapter(fragmentPagerAdapter);
        pagerTabStrip.setDrawFullUnderline(true);
        pagerTabStrip.setTabIndicatorColor(Color.DKGRAY);
    }

}
MyFragmentPagerAdapter.java
package com.example.pagertabstripsample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    private String[] pageTitle = {
            "Page1", "Page2", "Page3"
    };

    public MyFragmentPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = new PageFragment();
        Bundle arguments = new Bundle();
        arguments.putString("pageIndex", Integer.toString(position + 1));
        fragment.setArguments(arguments);
        return fragment;
    }

    @Override
    public int getCount() {
        return pageTitle.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return pageTitle[position];
    }

}
PagerFragment.java
package com.example.pagertabstripsample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class PageFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_page, null);
        TextView textView = (TextView) view.findViewById(R.id.textview);
        textView.setText(getArguments().getString("pageIndex"));
        return view;
    }

}

レイアウトファイル(fragment_page.xml)のコードは割愛。
これまではViewPagerIndicatorというライブラリを使っていましたが、今後はPagerTabStripを使ってみようかなと思ってます。

ViewPagerIndicator
http://viewpagerindicator.com/