Learn to Live and Live to Learn

IT(たまにビジネス)に関する記事を読んで、考えて、使ってみたことをまとめる場。

Material Design 1.マテリアルデザインとは何か

同期のデザイナーの子にマテリアルデザインのことを聞かれた時、答えられなくて悔しかったのでw
公式ドキュメントを読みつつ、マテリアルデザインについてまとめていきたいと思います。(全10回くらいの予定)

デザインの歴史

スキューモーフィズムからマテリアルデザインに到るまでの流れを追っていきます。

スキューモーフィズム(1890年頃〜)

現実世界の視覚のルールをデザインに落とし込んだものです。

f:id:A_01:20170419233400p:plain 図1:スキューモーフィズムの例。紙のノートのような質感を持つ立体的なデザイン。

フラットデザイン(1920年頃〜)

装飾性を抑えたシンプルで平面的なデザインです。

f:id:A_01:20170419235107j:plain 図2:フラットデザインの例

こんなこと言うとなんですが、私は洗練されていて結構好きですw

メトロUI(2010年頃〜)

過剰な装飾を削ぎ落とした点において、フラットデザインの一種と言えます。
しかし、完全なフラットデザインではなく、もちろん完全なスキューモーフィズムでもなく、中間的な立ち位置(フラットデザイン寄り)です。

f:id:A_01:20170419235127p:plain 図3:メトロUIの例

マテリアルデザイン(2014年頃〜)

フラットデザイン及びメトロUIの持つ以下の課題を解決するものとして、マテリアルデザインが登場しました。

  • 立体的な表現をなくしたため、どこを押すことができるのか、あるいはどこに文字を入力できるのかわからない。
  • 無駄な装飾をなくしたため重要度が分かりづらい。

マテリアルデザインは

マテリアル(物質)のメタファー(比喩)

です。現実世界のルールをデザインに落とし込むことで、いつの時代でも、誰にでも、どんなデバイスでも通じるデザインを目指しています。
具体的には光と影、奥行きの概念を取り入れることで、現実世界の質量を表現し、直感的に分かりやすくしています。 ( →マテリアルは3D)

また、ユーザの操作に対しアニメーションで反応するなど触覚を大事にしている点でスキューモーフィズムと異なります。 (→意味のあるアニメーション)

マテリアル環境は3D

マテリアルデザインについて

「紙」と「インク」で構成されており、印刷物を意識した作り

という表現をよく見かけますが、つまり画面の縦横だけでなく、高さ(奥行き)も意識しているということです。

f:id:A_01:20170420000759j:plain 図4:x軸y軸に加えz軸が存在する

f:id:A_01:20170420000440j:plain 図5:パーツはそれぞれ3次元上に存在する。あるパーツがあるパーツを突き抜けるような現実にあり得ないデザインはない。

意味のあるアニメーション

ユーザの操作に対し、アニメーションでレスポンスを返すことによって、ユーザは自分の操作がどう伝わったのか、理解しやすくなります。

www.youtube.com 映像:マテリアルデザインの説明動画。「慣性」が意識されていることがよく分かる。

参考

エンジニアが武器にするMaterial Design // Speaker Deck
 ーエンジニアがマテリアルデザインを学ぶことの大切さが語られています。

マテリアル – 日本語
 ー公式ドキュメント。これは最低限読んでおくべきだと思います。(読んでいる途中だけどw)

マテリアルデザインについて少し調べる - Qiita
Googleマテリアルデザインとフラットデザインって結局何が違うの?[UI/UX] - NAVER まとめ
マテリアルデザインとは〜基本概念と実務で使える無料フレームワーク6選 |ferret [フェレット]
 ーマテリアルデザインって何?フラットデザインとどう違うの?という疑問に端的に答えてくれるサイトたちです。

AtomでMarkdown記法時に普通に改行する(Atom v1.14.1)

概要

最近メモとしてAtomを使っています。
Control + Shift + Mを押すと、左カラムに入力しつつ右カラムでリアルタイムプレビューできてとても便利です。
しかし半角スペース2つ打たないと改行できないのは不便。。他に改行を使う予定もないし、普通に改行されてほしい。。

解決方法

バージョン1.14.1で検証したところ、一部手順が変わっていたのでメモします。

①Packages > Setting View > Openと押していく
Markdown Previewを選択
③Break On Single Newlineにチェックを入れる

参考

blog.3streamer.net

fatal: Commit <コミットID> is a merge but no -m option was given.

git revert <コミットID>ができない

こんなエラーが出ました。

$ git revert f780e4d
fatal: Commit f780e4d is a merge but no -m option was given.
# コミット「f780e4d」はマージされてるけど、`-m`オプションが付与されてないよ。

マージコミットをリバートしようとしているのが原因

マージコミット(例、プルリクエストのマージボタンを押したときにできるコミット)はgit revertだけではリバートできません。
今回はテストのため、意図的にマージコミットを作りました。やり方はこちらです。

$ git branch
* master
$ git checkout -b a
$ touch a.tsv
$ git add a
$ git commit

$ git checkout -b b
$ touch b.tsv
$ git add b.tsv
$ git commit

$ git checkout master
$ git merge a b

対応方法

①本線を確認する

git rever -mには親番号を指定する必要があります。
コミット履歴をグラフ化すると一目瞭然なのですが、マージコミットには2つ以上の線が存在します(その線がマージされてコミットとなっています)。
今回は「30cc2f4」に「beb91c3」がマージされているので、「30cc2f4」が本線と分かります。

$ git log --graph --oneline
*   f780e4d Merge branches 'a' and 'b'
|\  
| * beb91c3 add b
* | 30cc2f4 add a
|/  

②親番号を確認する

「30cc2f4」の番号はgit showgit cat-file -pで確認できます。

git show <コミットID>

Mergeの左から1, 2です。

$ git show 8dcc4d7
commit xxx
Merge: 30cc2f4 beb91c3
...
git cat-file -p <コミットID>

parentの上から1, 2です。

$ git cat-file -p 8dcc4d7
tree xxx
parent 30cc2f48c07f368cd91e794865efae3b5ef5d3b3
parent beb91c34f591a1998ac59606269f60f275fc7cbf
...

③git revert -m <親番号>でリバートする

1つめのコミットID「30cc2f4」が本筋であるので、親番号は「1」です。

$ git revert -m 1 f780e4d

参考

akiyoko.hatenablog.jp qiita.com

追記

記事の整理をしているので、更新通知が飛びまくったりしていたらすみません :bow:

Android オプションを付けてコンパイルする

概要

ビルド時にオプションを付けてコンパイルしてね,というエラーが出ました.

注意:一部の入力ファイルは非推奨のAPIを使用またはオーバーライドしています。
注意:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。

解決方法

buid.gradleを修正して再コンパイルすると詳細が見られます.

{$root}/buid.gradle

// ルートプロジェクトを含む全プロジェクトに適用
allprojects { 
    // 実行フェーズ開始前
    gradle.projectsEvaluated {
        // options.encoding = 'UTF-8'とかもこのちゅうかっこの中で指定できる
        tasks.withType(JavaCompile) {
            // オプション指定.uncheckedは未チェックなもの(*1),deprecationは非推奨なものを表示する
            options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
        }
    }
}

(*1)
こういう何の型が入るか定義されてないやつ.

ArrayList list = new ArrayList<>();

型チェックされたのはこういう状態.

ArrayList<Hoge> = new ArrraList<Hoge>();

参考

ビルド時にDuplicate files copied

概要

以下のエラーでビルドが失敗しました.

Duplicate files copied in APK META-INF/LICENSE.txt

原因

依存ライブラリに指定した外部jarファイルを内部で展開した時に複数のjarファイルでリソースファイルなどのパスが競合してエラーになっているようです。(Qiitaより)

対応方法

該当ファイルをパッケージング時に除外することでビルドできます.
packagingOptionsにはAndroid Gradle プラグインの0.7.1以上が必要です.

${module_root}/build.gradle

android {
    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
    }
}

参考

qiita.com

Android N データセーバ対応

データセーバとは

Android Nで導入された機能です.

ユーザーが [Settings] でデータセーバーを有効にし、端末が従量制課金ネットワークに接続されている場合、システムはバックグラウンドでのデータ使用をブロックし、フォアグラウンドでのデータ使用をなるべく抑えるようにアプリに指示します。
( developer.android.comより)

データ通信に制限がかかって月後半に困る人(それは私)には便利な機能かもしれませんね.
ただし,アプリ開発者側はバックグランドでしていた処理ができなくなるので対応が求められます.

データセーバ設定の確認&ホワイトリストパーミッションの要求

一番使うのはこれだと思います.データセーバが有効になっているか確認し,有効な時はホワイトリストに自アプリを登録してもらう設定画面に遷移させます.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager.isActiveNetworkMetered()
        && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        // 現在の通信が測定されているか(ダウンロードにリミットが課されているか)
        switch (connectivityManager.getRestrictBackgroundStatus()) {
            case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED:
                // データセーバ有効
                // 設定画面へ遷移
                Intent intent = new Intent(Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS, "package:<package_name>");
                startActivity(intent);
            case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED:
                // ホワイトリストに登録されている
            case ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED:
                // データセーバ無効
        }
    } else {
        // WiFiとかデータセーバには関係ない
    }
}

データセーバ設定の変更の監視

BroadcastReceiverを使ってデータセーバ設定の変更を検知することもできます.
ただし,AndroidManifest.xmlに書く静的な登録ではなく,registerRecieverする動的な登録でないとこのブロードキャストは受信できません.

IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
filter.addAction(conManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
DataSaverReceiver receiver = new DataSaverReceiver();
getContext().registerReceiver(receiver, filter);
public class DataSaverReceiver extends BroadcastReceiver{
    public void onReceive(Context context, Intent intent) {
        // データセーバ設定が変更された時
    }
}

参考

developer.android.com

www.webprofessional.jp

Sources for 'Android API xx Platform' not found.

概要

Build.javaを開くとSources for 'Android API 22(1) Platform' not found.というエラーが出てきました.

インストールしても直らない🤔
(インストールされているかは,Tools > Android > SDK Manager > Show Pachage Details > Sources for Android xxがInstalledになっているかで確認できます)
Refreshを押しても反応しない🤔
(バグらしいです.泣)

という時に以下の方法で解決できたので紹介します.実行環境はAndroid2.1系と2.3系です.

解決方法

①Tools > Android > SDK Managerを開く
Android SDK LocationのEditを押す
③何もいじらず,NextをポチポチしてFinish
これでRefreshされ解決されました.

参考

kokufu.blogspot.jp