Android:简易路径导航条

本文要实现的是如图所示的路径导航条, 类似于文件管理器的效果。
这里写图片描述’>

该导航条包含三个功能:
1. 支持追加任意个子路径(文字一行写不下时可左右滑动);
2. 支持返回到上一个路径;
3. 支持点击中间的某个路径回到指定位置。

代码很简单,已封装成自定义View, 如下:

PathTextView.java


/**
 * 显示路径的View,支持返回上一级,支持点击某个位置回到指定层级。
 */

public class PathTextView extends LinearLayout {
    private TextView mTextView;
    private HorizontalScrollView hsView;

    private OnItemClickListener mListener;
    //保存每一个路径的id和名称
    private LinkedList<PathItem> pathItemList;

    //可点击部门文本颜色
    private static final int TEXT_COLOR = Color.parseColor("#48a0c7");
    //分隔符
    private static final String DIV_STR = " - ";

    public PathTextView(Context context) {
        super(context);
    }

    public PathTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        View root = LayoutInflater.from(context).inflate(R.layout.simple_tv, this, true);

        hsView = (HorizontalScrollView) root.findViewById(R.id.path_hs);
        mTextView = (TextView) root.findViewById(R.id.path_tv);
        mTextView.setMovementMethod(LinkMovementMethod.getInstance());
        mTextView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return true;
            }
        });

        pathItemList = new LinkedList<>();
    }

    /**
     * 初始化根路径名称。
     */
    public void initRoot(String text) {
        mTextView.append(createSpannableString(-1, text));
        pathItemList.addLast(new PathItem(-1, text));
    }

    /**
     * 继续拼接一个路径。
     */
    public void append(long id, String text) {
        mTextView.append(DIV_STR);
        mTextView.append(createSpannableString(id, text));
        pathItemList.addLast(new PathItem(id, text));

        //HorizontalScrollView滑动到最右边
        hsView.postDelayed(new Runnable() {
            @Override
            public void run() {
                hsView.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
            }
        }, 100);
    }

    /**
     * 返回父级路径,一般用户点击“返回”时调用。
     */
    public void backParent() {
        int lastItemLength = pathItemList.removeLast().text.length();
        CharSequence oldCs = mTextView.getText();
        mTextView.setText(oldCs.subSequence(0, oldCs.length() - lastItemLength - DIV_STR.length()));
    }

    private SpannableString createSpannableString(long id, String text) {
        SpannableString spStr = new SpannableString(text);
        ClickableSpan clickSpan = new MyClickableSpan(id);
        spStr.setSpan(clickSpan, 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spStr.setSpan(new ForegroundColorSpan(TEXT_COLOR), 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

        return spStr;
    }

    private class MyClickableSpan extends ClickableSpan {
        private long id;

        MyClickableSpan(long id) {
            super();
            this.id = id;
        }

        @Override
        public void onClick(View widget) {
            //更新当前路径
            int backCount = 0;
            while (pathItemList.getLast().id != id) {
                backParent();
                backCount++;
            }

            //回调
            if (mListener != null && backCount > 0) {
                mListener.onClick(id, backCount);
            }
        }
    }

    private class PathItem {
        private long id;
        private String text;

        private PathItem(long id, String text) {
            this.id = id;
            this.text = text;
        }
    }

    public interface OnItemClickListener {
        /**
         * @param currentId 返回后目录的id.
         * @param backCount 返回层级的数量.
         */
        void onClick(long currentId, int backCount);
    }

    /**
     * 设置点击某个中间路径时的回调。
     */
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mListener = listener;
    }
}

布局文件,其实就是一个TextView:
simple_tv.xml

<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/path_hs"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/light_gray2"
    android:scrollbars="none">

    <TextView
        android:id="@+id/path_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/light_gray2"
        android:paddingBottom="12dp"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:paddingTop="12dp"
        android:textSize="15sp" />

</HorizontalScrollView>

使用方法也很简单:
1. 初始化时,调用 initRoot(String text) 方法,传入根路径名称;
2. 点击列表项进入下一级时,调用 append(long id, String text) 方法,传递当前项的id(用于唯一性区分)和名称;
3. 返回上一级时,调用 backParent() 方法;
4. 点击某个中间路径时, OnItemClickListener.onClick(long currentId, int backCount) 方法将会被回调,并返回点击项的id和返回的层级数量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值