EP31-BottomNavigation的重新设计

BottomNavigation的重新设计

今天写完了上周说要适用在印尼钱包中的「改进的」底部导航条SDK。
不仅是内部实现变得简洁高效,使用方法也有改进。
特性有:

  • 从以前的只支持2~5个tab到现在支持任意个数tab了
  • 对于5.0以上机型适配ripple effect特效,点击放大/缩小的数值严格按照MD的规范
  • 可以设置title文字大小和颜色

今天偶然听到刘炎说,「实现麻烦可以,用起来简单就行」,觉得很有道理,可以作为sdk的准则,当然,实现的「麻烦」不能是运行时时间/空间复杂度高的那种重复性劳动的麻烦。
有两个麻烦的细节需要注意:

  1. View的构造函数
    它的三个构造函数分别是在使用**new**创建实例的时候/在xml中使用的时候/在xml中使用并且有自定义Attr的时候 被用到。所以,如果只是在xml中用到,那么会发现只有第二个构造函数里的initView()会执行!
//继承LinearLayout后覆写的方法
public BottomNav(Context context) {
        super(context);
        initView();
    }

    public BottomNav(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public BottomNav(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

另外,我们发现父类的三个构造函数会一个个嵌套,最终调用的是参数最多的那个构造函数。

  1. 是否真的需要inflate
    initView()中我写的是LayoutInflaterinflate操作,inflate有多种方式。
    需要理解inflate的参数:
public View inflate(int resource, ViewGroup root)
public View inflate(int resource, ViewGroup root, boolean attachToRoot)
public View inflate(XmlPullParser parser, ViewGroup root)
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)

resource是布局资源id没问题,root是填充的根视图(指定的父view),attachToRoot代表 是否将载入的视图绑定到根视图中。

当我们给view传进来的root不是null,并且第三个参数是false的时候,这个view就被加入到了root中,并且把root当作最终的返回值返回了。而当我们设置root为空的时候,没有设置LayoutParams参数的temp对象,作为返回值返回了。

举个例子,比如对于listView/recyclerView的单个item的布局,若才去这种方式填充视图,item布局中的根视图的layout_width之类的属性会被忽略掉,被设置成默认的包裹内容方式:

convertView = inflater.inflate(R.layout.item_list,null);

它的布局:

<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="60dp" android:background="@android:color/holo_orange_light" android:gravity="center" android:orientation="vertical">
    <textview android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="11" android:textcolor="@android:color/black" android:textsize="22sp">
 
</textview></linearlayout>

所以,对于我现在用的把tab单独加入到线性布局的addView的方法,不需要设置parent view,因为我们addView进的view已经是最外层view了。


这个底部导航条的具体实现我不提了,可以到我的github上看,还是比较巧妙的,关键代码:

    /**
     * set up the selected and unselected tab's style
     *
     * @param tag tagName of the tab
     */
    public void setCurrentSelectedTabByTag(String tag) {

        for (ViewHolder holder : mViewHolderList) {
            //traverse
            if (tag.equals(holder.bottomNavItem.mTabTag)) {
                holder.tabIcon.setImageResource(holder.bottomNavItem.mDrawableSelected);
                holder.tabTitle.setTextColor(mSelectedTabTextColor);
                mOnTabSelectedListener.onTabSelected(holder.bottomNavItem.mText);

                holder.tabLinearLayout.setPadding(dp12, dp6, dp12, dp10);
                holder.tabTitle.setTextSize(14);
            } else {
                holder.tabIcon.setImageResource(holder.bottomNavItem.mDrawableUnselected);
                holder.tabTitle.setTextColor(mDefaultTabTextColor);

                holder.tabLinearLayout.setPadding(dp12, dp8, dp12, dp10);
                holder.tabTitle.setTextSize(12);
            }
        }
    }

-Jan 4th

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容