Rubotoを使い、Androidで動的にTextViewなどを追加・削除する

Rubotoで画面を作る方法は分かったものの、あとからTextViewなどを追加・削除する方法が分からなかったため、いろいろと調べた時のメモ。

■環境

Platform JDK ant Ruby ruboto jruby-jars Device API level
Windows7 x64 1.7.0_25 1.9.1 RubyInstaller 1.9.3-p448 0.13.0 1.7.4 Nexus7 2012 android-17

■アプリの動き

画面の追加・削除ボタンをおすことで、TextViewが表示されたり消えたりします。



■アプリの生成

以下で生成します。Windowsなので、生成後にはメモリの設定変更も忘れずに行います。

ruboto gen app --package com.example.dynamic_gui --target android-17 --with-jruby

■調べたこと

コードによる画面の配置

今回はxmlではなく、コードで画面の配置などを行うようにします。
Rubotoにおけるコードでの設定方法は、以下のRuboto公式ドキュメントやソースに書かれていました。


なお、公式ドキュメントを読むと、Buttonのon_click_listenerの指定方法として以下の2つがあったため、両方とも試してみました。

  • 別クラスを指定して、onClickを実装する方法
  • ローカル変数を指定して、ブロックで処理内容を渡す
日本語の利用

TextViewやtoastで日本語を利用するため、dynamic_gui_activity.rbの先頭にマジックコメントを入れました。
参考:多言語化

# encoding: utf-8
Viewへの追加・削除

Android公式情報では、addViewとremoveViewで追加・削除ができるとのことでした。


Javaでのやり方については、以下が参考になりました。


addViewやremoveViewでは対象のViewが必要になるため、Rubotoではどうやるか悩みましたが、今回はインスタンス変数にViewを入れておいて使うことにしました(正しいやり方かどうかは、今のところ分かりません)。


ActivityのonCreateの中で、viewを作ってインスタンス変数に入れ、self.content_viewに設定します。

@view = linear_layout orientation: :vertical do
  @text_view = text_view text: 'ボタンを押してね', text_size: 20
  @button_view = button text: '追加', on_click_listener: ClickListener.new(self)
  @toast_view = button text: 'Add with toast', on_click_listener: addition_click
end

self.content_view = @view


あとはButtonのonClickイベント内で、viewの追加や削除を行います。

if @display_view.nil?
  @display_view = text_view text: 'Hello World !', text_size: 48
  @view.addView(@display_view)
else
  @view.removeView(@display_view)
  @display_view = nil
end

スクリーンショット

起動時

追加ボタンを押した時

削除ボタンを押した時

Add with toastボタンを押した時

Remove with toastボタンを押した時



■ソース

dynamic_gui_activity.rb

# encoding: utf-8

require 'ruboto/widget'
require 'ruboto/util/toast'

ruboto_import_widgets :Button, :LinearLayout, :TextView

java_import 'android.util.Log'


class DynamicGuiActivity
  def onCreate(bundle)
    super
    Log.v "LOG", "onCreate"

    addition_click = proc do
      change(toast: true)
    end

    @view = linear_layout orientation: :vertical do
      @text_view = text_view text: 'ボタンを押してね', text_size: 20
      @button_view = button text: '追加', on_click_listener: ClickListener.new(self)
      @toast_view = button text: 'Add with toast', on_click_listener: addition_click
    end

    self.content_view = @view
  end


  def change(args)
    if @display_view.nil?
      @display_view = text_view text: 'Hello World !', text_size: 48
      @view.addView(@display_view)

      @button_view.text = '削除'
      @toast_view.text = 'Remove with toast'
      toast '追加しました' if args[:toast]

    else
      @view.removeView(@display_view)
      @display_view = nil

      @button_view.text = '追加'
      @toast_view.text = 'Add with toast'
      toast '削除しました' if args[:toast]
    end
  end
end


class ClickListener
  def initialize(activity)
    @activity = activity
  end

  def onClick(view)
    Log.v "LOG", "onClick"
    @activity.change(toast: false)
  end
end


Gistは以下になります。
Rubotoで動的にTextViewを追加・削除するサンプル