MyTraks ソース読み (2)

昨日の続き。もう 1h は続行可能かな。
昨日は TabHost なオブジェクトを取得して、そいつの addTab してくソレな部分で中断してます。

    final TabHost tabHost = getTabHost();
    tabHost.addTab(tabHost.newTabSpec("tab1")
        .setIndicator("Map", res.getDrawable(android.R.drawable.ic_menu_mapmode))
        .setContent(new Intent(this, MyTracksMap.class)));

tab indicator なるソレにラベルとアイコンをセットしつつ、Activity を起動するための Intent を設定している模様。

再開

1730 にもくもくな場所から退散。2000 過ぎに再開。以下から。

    // Hide the tab widget itself. We'll use overlayed prev/next buttons to
    // switch between the tabs:
    tabHost.getTabWidget().setVisibility(View.GONE);

tabHost なナニは見せない、という設定。確かにタップしないと出てきません。タップしたら出てきますよ、なソレはどこでヤッてるんでしょうね。
と思ったら直下でヤッてる模様。

    RelativeLayout layout = new RelativeLayout(this);
    LayoutParams params =
        new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    layout.setLayoutParams(params);
    navControls = new NavControls(this, layout, prevActivity, nextActivity);
    navControls.setLeftIcon(icons[NUM_TABS - 1]);
    navControls.setRightIcon(icons[1]);
    navControls.show();
    tabHost.addView(layout);
    layout.setOnTouchListener(this);

ええと、width と height が fill_parent な相対レイアウトを作って NavControls なオブジェクトを生成しております。NavControls って何だろ。てかここは異様に濃ゆいな。
NavControls クラスのコンストラクタですが、順に掘ってみます。

  public NavControls(Context context, ViewGroup container,
      Runnable prevRunnable, Runnable nextRunnable) {
    this.context = context;
    this.prevRunnable = prevRunnable;
    this.nextRunnable = nextRunnable;

それぞれの属性は全部 final な修飾子が付いてるな。

  private final Context context;
  private final Runnable prevRunnable;
  private final Runnable nextRunnable;

ええと、MyTracks.java で定義されてる prevActivity とか nectActivity の定義は、というと以下ッス。

  private final Runnable nextActivity = new Runnable() {
    public void run() {
      currentTab = (currentTab + 1) % NUM_TABS;
      navControls.setLeftIcon(icons[(currentTab + NUM_TABS - 1) % NUM_TABS]);
      navControls.setRightIcon(icons[(currentTab + NUM_TABS + 1) % NUM_TABS]);
      getTabHost().setCurrentTab(currentTab);
      navControls.show();
    }
  };

  private final Runnable prevActivity = new Runnable() {
    public void run() {
      currentTab--;
      if (currentTab < 0) {
        currentTab = NUM_TABS - 1;
      }
      navControls.setLeftIcon(icons[(currentTab + NUM_TABS - 1) % NUM_TABS]);
      navControls.setRightIcon(icons[(currentTab + NUM_TABS + 1) % NUM_TABS]);
      getTabHost().setCurrentTab(currentTab);
      navControls.show();
    }
  };

タブの切り替えに対応する形で書いてある模様。それぞれ右左の切り替えに対応する形で書いてありますな。それぞれがタブ切り替えなアイコンをタップされた時点で呼び出されると類推。
ええと、NavControls なコンストラクタの続きです。以下。

    LayoutParams prevParams = new LayoutParams(
        LayoutParams.WRAP_CONTENT,
        LayoutParams.WRAP_CONTENT);
    prevParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    prevParams.addRule(RelativeLayout.CENTER_VERTICAL);
    prevImage = new TouchLayout(context, true);
    prevImage.setLayoutParams(prevParams);
    prevImage.setVisibility(View.INVISIBLE);
    container.addView(prevImage);

prev と next でほぼ同じ処理をしてます。ネストし杉でナニ。container 属性は RelativeLayout なオブジェクトを指してるんですが、prev と next の差分な

    prevImage = new TouchLayout(context, true);

の意味合いの違いはチェック必要か。てか、TouchLayout って何だば。ググッても出ないって事はローカル定義なのか。

NavControls.java にて定義されてた件

コンストラクタが以下。

    public TouchLayout(Context context, boolean isLeft) {
      super(context);
      arrow = new ImageView(context);
      arrow.setImageDrawable(context.getResources().getDrawable(
          isLeft ? R.drawable.btn_arrow_left : R.drawable.btn_arrow_right));
      icon = new ImageView(context);
      icon.setVisibility(View.GONE);
      addView(arrow);
      addView(icon);
      icon.setPadding((isLeft ? 15 : 10), 27, 15, 0);
    }

TouchLayout は RelativeLayout を継承してる模様。アイコンが右もしくは左な矢印 (てか三角) の中にはいってる形なソレをナニするものだろう、とざっくり理解。(を
true か false かで右向き左向きなナニ。なんつーか凄いワザが詰まってるカンジ。一連のソレは若干スルー気味としていっちゃん最後の

    layout.setOnTouchListener(this);

は確認必要。onTouchListener インターフェースな abstract method は以下かな。

  @Override
  public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      navControls.show();
    }
    return false;
  }

show() のソースは別途見るって事でスルーしようと思いますが、コンストラクタで show() されてる、って事は最初は表示されてる模様なんですが、実装の挙動を確認してみたら表示されてました。時間が経ったら非表示になるソレはどこに書いてあるんだろうな。

と思ったら

show() で呼び出される keepVisible() にて以下な記述あり。

      handler.postDelayed(dismissControls, KEEP_VISIBLE_MILLIS);

dismissControls は NavControls クラスの属性で定義が以下。

  private final Runnable dismissControls = new Runnable() {
    public void run() {
      hide();
    }
  };

成程。この手法も参考になりますな。とりあえず今日はここで一時停止。