地球ウォーカー2

Scala, Python の勉強日記

画面のwidthが足りないとAdMobの広告(AdView)が表示されない

タイトルの通り画面の幅が足りないとAdViewが表示されないらしいので、
Rootの要素にpaddingを設定してしまうと広告が表示されない*1

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dip"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
        <TextView />
        <FrameLayout />
    </LinearLayout>
    <com.google.ads.AdView android:id="@+id/adView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        ads:adUnitId="xxxxxxxxxxxxxxxxxxx"
        ads:adSize="BANNER"
        ads:loadAdOnCreate="true" />
</LinearLayout>

paddingを子要素で指定すると正しく表示される。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:padding="10dip"
        >
        <TextView />
        <FrameLayout />
    </LinearLayout>
    <com.google.ads.AdView android:id="@+id/adView"
                      android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                       ads:adUnitId="xxxxxxxxxxxxxxxxxxx"
                       ads:adSize="BANNER"
                       ads:loadAdOnCreate="true" />
</LinearLayout>

*1:ads:adSize="BANNER"、android:screenOrientation="portrait"の場合

Android XMLファイルのエラーを解消する方法

備忘録として。

Eclipseでmain.xmlやstrings.xmlなどのAndroid XMLファイルを直接編集すると、
xmlとしてはvalidなのに何故かビルドエラーが発生してmain.out.xmlのような空のファイルができることがある。


Error in an XML file: aborting build.

そのときは以下のようにすればエラーを解消できる。

  1. main.out.xmlを消す
  2. main.xmlを退避
  3. 新規 > Android XML ファイルで同じ名前のファイル(main.xml)を作成する。
  4. 退避したファイルの内容をすべてコピーし、新規作成したファイルのxmlに貼り付ける

<code>$.extend (jQuery.extend)</code> のよくある使い方

function内の変数の初期化で使う。
次のコードではoptionsに渡しているプロパティのみ上書きされる。

function f(options) {
    var defaults = {
        str1: 'default str1',
        str2 : 'default str2',
        bool : true
    };

    var settings = jQuery.extend({}, defaults, options); // ここで初期化する

    console.dir(settings);
    // 出力は以下の通り
    // bool   false
    // str1   "custom str1"
    // str2   "default str2"
}

f({
    str1 : 'custom str1',
    bool : false
});

ちなみに

$.extend を使わない場合は次のように少し面倒。

function f(options) {
    var defaults = {
        str1: 'default str1',
        str2 : 'default str2',
        bool : true
    };

    // ここで初期化する
    var settings = {
        str1 : options.str1 || defaults.str1,
        str2 : options.str2 || defaults.str2,
        // デフォルトがtrueなので、options.bool || defaults.bool ではうまく動かない
        bool : typeof options.bool !== 'undefined' ? options.bool : defaults.bool
    };

    console.dir(settings);
    // 出力は以下の通り
    // bool   false
    // str1   "custom str1"
    // str2   "default str2"
}

f({
    str1 : 'custom str1',
    bool : false
});

jQueryを使ってkeydownイベントを呼び出す方法

最近やり方を知った。
用途は$('input')に設定されているkeydownイベントのテストをしたいときなど。

var evt = $.Event('keydown');
evt.keyCode = 13;    // エンターキー入力時のテスト
$('input').trigger(evt);

keydownの部分を変更すれば、他のイベントも作ることができる。
デモも作ってみた。

YouTubeをリピート再生するGreasemonkey (&Bookmarklet)

既にあるかもしれないけど作ってみた。
とりあえずdocument.getElementById('movie_player')さえすればYouTube JavaScript Player APIを使えるということがわかった。

機能

  • ビデオの再生が終わったら勝手にリピート再生する。
  • 右上のボタン(AutoPagerizeのパクリ)でリピート再生のON/OFFを切り替えられる。

Greasemonkey

スクリプトをサーバーにおいた。
Youtube Repeat
ソースは以下の通り。

// ==UserScript==
// @name Youtube Repeat
// @description Repeat Youtube playing
// @namespace http://d.hatena.ne.jp/hysa/
// @include http://www.youtube.com/*
// ==/UserScript==
(function() {
  var p = document.getElementById('movie_player').wrappedJSObject;
  if (p === null) return;

  var on = GM_getValue('repeat', true);

  setInterval(
    /**
     * Repeat the video.
     * if the video is ended, play the video again.
     *
     * @param {number} state the state of the player.
     */
    function repeat() {
      if (p.getPlayerState() === State.ENDED && on) {
        p.playVideo();
      }
    }

  , 1000);

  /**
   * Enum for the state of the player 
   *
   * @enum {number}
   */
  var State = {

    UNSTARTED: -1,

    ENDED: 0,

    PLAYING: 1,

    PAUSED: 2,

    BUFFERING: 3,

    VIDEO_CUED: 5
  };


  /**
   * Create a button.
   *
   */
  (function createButton() {
    var button = document.createElement('div');
    var style = button.style;
    
    /**
     * Set style on the button.
     */
    function setStyle() {
      style.background = 'none repeat scroll 0 0 #0F0';
      style.color = '#FFF';
      style.fontSize = '12px';
      style.height = '10px';
      style.position = 'fixed';
      style.right = '3px';
      style.top = '3px';
      style.width = '10px';
      style.zIndex = '255';
      if (!on) {
        style.backgroundColor = '#CCC';
      }
    }

    button.addEventListener(
      'click',

      /**
       * Toggle switch.
       *
       */
      function() {
        if (on) {
          style.backgroundColor = '#CCC';
        } else {
          style.backgroundColor = '#0F0';
        }
        on = !on;
        GM_setValue('repeat', on);
      },
      false
    );

    setStyle();
    document.body.appendChild(button);
  })();

})();

Bookmarklet

IE8、FirefoxGoogle Chromeのみ確認。

javascript:(function(s){ s.src = 'http://hysa.main.jp/public/gm/YoutubeRepeat.js';document.body.appendChild(s);})(document.createElement('script'));