Androidでパンくずリストを配置するカスタムビューを作ってみた

まんまです。

どこかで見たことのあるリモコンアプリで仮実装中の産物です。
HorizontalScrollViewを拡張して作りました。なんかコレベースって多いな。
とりあえず標準ボタンを使った実装で見た目はこんな感じ。



機能
・push("hogehoge")でどんどん右へリスト(ボタン)を伸ばしていける
・popで1つ減らせる
・ボタンをタップすると、タップしたボタンより右のものを消した上でクリックイベントを上位に飛ばす
・セパレータの「>」マークの画像を変更できます
・ボタンを追加すると一番右へ自動でスクロールします

あとは、ボタンの画像をセパレータ使ってカスタマイズしたりできるようにしたりいろいろ使えるのではと思います。
本当はボタンを右に追加していってはみ出た時点で折返しとか考えてたんですけどWebみたいに簡単にはいかなかったので断念。
いまいちスマートな方法はないっぽい。



ソースは「GoogleCode relog」にも保存されてますのでよければどうぞ。



リソース画像
セパレータの画像はこんなのを今回は用意しました。
ファイル名:「im_breadcrumblist_separator.png」

サンプルxml
<jp.xii.relog.customlibrary.widget.BreadCrumbList
		android:id="@+id/Select_BreadCrumbList"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		/>

サンプルソース
package jp.xii.relog.customlibrary.widget;

import java.util.ArrayList;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;


public class BreadCrumbList extends HorizontalScrollView
	implements OnClickListener{

	private LinearLayout _buttonArea = null;				//リストを配置するレイアウト
	private ArrayList<LinearLayout> _buttonList = null;		//パンくずリストのボタン
	private OnClickListener _onClickListener = null;		//リスナー
	private Drawable _separatorDrawable = null;				//セパレータ
	
	/**
	 * リストを配置するレイアウト
	 * @return
	 */
	public LinearLayout getButtonArea(){
		if(_buttonArea == null){
			_buttonArea = new LinearLayout(getContext());
		}
		return _buttonArea;
	}
	
	/**
	 * パンくずリストのボタン
	 * @return the _buttonList
	 */
	public ArrayList<LinearLayout> getButtonList() {
		if(_buttonList == null){
			_buttonList = new ArrayList<LinearLayout>();
		}
		return _buttonList;
	}

	/**
	 * リスナーの登録
	 * @param listner
	 */
	public void setOnClickListener(OnClickListener listner){
		_onClickListener = listner;
	}

	/**
	 * セパレータ
	 * @param _separatorDrawable the _separatorDrawable to set
	 */
	public void setSeparatorDrawable(Drawable _separatorDrawable) {
		this._separatorDrawable = _separatorDrawable;
	}

	/**
	 * セパレータ
	 * @return the _separatorDrawable
	 */
	public Drawable getSeparatorDrawable() {
		return _separatorDrawable;
	}

	/**
	 * コンストラクタ
	 * @param context
	 * @param attrs
	 */
	public BreadCrumbList(Context context, AttributeSet attrs) {
		super(context, attrs);

		
		//セパレータを指定する
		setSeparatorDrawable(getResources().getDrawable(jp.xii.relog.customlibrary.R.drawable.im_breadcrumblist_separator));
		
		//ボタンの配置用の一番親のレイアウトを追加する
		addView(getButtonArea());

		//上側の隙間調節
		getButtonArea().setPadding(getButtonArea().getPaddingLeft()
				, getHorizontalScrollbarHeight()
				, getButtonArea().getPaddingRight()
				, getButtonArea().getPaddingBottom());

	}
	
	/**
	 * レイアウトを確定させる
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);


		//一番右へ移動
		fullScroll(FOCUS_RIGHT);
	}
	
	/**
	 * アイテムを追加する
	 * @param name
	 */
	public void push(String name){
		//レイアウト作成
		LinearLayout layout = new LinearLayout(getContext());
		
		//セパレータが指定されていた場合は追加
		if(getButtonList().size() == 0){
		}else if(getSeparatorDrawable() == null){
		}else{
			ImageView image = new ImageView(getContext());
			image.setBackgroundDrawable(getSeparatorDrawable());
			layout.addView(image);
		}

		//ボタン作成
		Button button = new Button(getContext());
		button.setText(name);
		button.setOnClickListener(this);
		button.setId(1);
		layout.addView(button);

		//真ん中寄せにする
		layout.setGravity(Gravity.CENTER);

		//親に追加
		getButtonList().add(layout);
		getButtonArea().addView(layout);
	}

	/**
	 * アイテムを1つ外す
	 */
	public LinearLayout pop(){
		int del_index = getButtonList().size() - 1;
		LinearLayout ret = getButtonList().get(del_index);
		//リストから削除
		getButtonList().remove(del_index);
		//レイアウトから削除
		getButtonArea().removeView(ret);
		
		return ret;
	}


	/**
	 * クリックイベント
	 */
	@Override
	public void onClick(View v) {
		//押したボタンをリストの中から探す
		for(int i=0; i<getButtonList().size(); i++){
			if(getButtonList().get(i).findViewById(1).equals(v)){
				//見つかったらそれより後ろのボタンを消す
				while((i+1) < getButtonList().size()){
					pop();
				}
				
				//イベントを呼ぶ
				if(_onClickListener != null){
					_onClickListener.onClick(v, i);
				}
				break;
			}
		}
	}
	
	/**
	 * クリックリスナー
	 * @author Iori
	 *
	 */
	public interface OnClickListener{
		void onClick(View v, int position);
	}
}