GitHub
使用:
-
添加依赖
1.项目gradle添加一下配置:allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
2.module中的gradle添加依赖:
dependencies { implementation 'com.github.truemi:bottomBar:v1.1' }
-
xml中添加view:
-
activity中初始化:
BottomBar bottomBar = findViewById(R.id.bottom_bar); bottomBar.init(getSupportFragmentManager(),R.id.fl_home)//.setRippleColor(R.drawable.bottom_bar_bg)//水波纹效果 .addItem("消息", getResources().getDrawable(R.drawable.bottom_bar_selected_01), new MessageFragment(), true) .addItem("首页", getResources().getDrawable(R.drawable.bottom_bar_selected_02), new HomeFragment(), false) .addItem("我的", getResources().getDrawable(R.drawable.bottom_bar_selected_03), new MyFragment(), true) .create(1);//默认显示第几个界面从0开始 bottomBar.setOnBottomBarOnClick(this);//设置点击监听
自定义属性:
属性 | 值 | 描述 |
---|---|---|
mTextNormalColor | #999999 | 标题的默认(未选中状态)颜色 |
mTextSelectColor | #FF0000 | 标题选中状态颜色 |
mtextSize | 10dp | 标题的文字大小 |
mIconSize | 20dp | 图片的大小(不设置,使用图片的实际大小) |
公开方法:
- setOnBottomBarOnClick(this);//设置点击监听
- showRedPoint(1,0,0);//只有初始化时设置可显示小红点为true时,设置显示才有效
- showRed(2);//显示小红点,从0开始,从左到右
- hideRed(0);//隐藏小红点,从0开始,从左到右
- showSubPage(1);//显示第几个界面,从0开始,从左到右
需求
- 每个按钮包括文字,图标,以及消息小红点,并且有状态选择器
- 可以动态添加按钮
- 按钮与Fragment绑定,点击按钮切换到对应的Fragment
思路
- 自定义View 继承自LinearLayout,设置横向布局
- 代码动态设置Item,设置权重为 1 ,然后添加到View中.
- 处理点击事件与fragment绑定
步骤
- 自定义属性,在attrs.xml中设置自定义属性
- 自定义View初始化
public BottomAppBar(Context context) {
this(context, null);
}
public BottomAppBar(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, -1);
}
public BottomAppBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
init(attrs);
//设置ViewId,为了避免重复,这里使用时间戳,
TEXTVIEW_ID = (int) (System.currentTimeMillis()%100*10000);
IMAGEVIEW_ID = (int) (System.currentTimeMillis()%100*1000);
ITEM_ID = (int) (System.currentTimeMillis()%100*100);
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.BottomAppBar);
float dimension = typedArray.getDimension(R.styleable.BottomAppBar_mtextSize, 0);
textSize = Uiutils.px2sp(context,dimension);
textNormalColor = typedArray.getColor(R.styleable.BottomAppBar_mTextNormalColor, 0);
textSelectColor = typedArray.getColor(R.styleable.BottomAppBar_mTextSelectColor, 0);
typedArray.recycle();
}
setOrientation(LinearLayout.HORIZONTAL);//设置布局为横向布局
}
- 初始化item,Item的根布局使用RelativeLayout,包含一个TextView和一个ImageView(小红点),textView的文字上面添加一个Drawable显示图标,这一部分的重点就是,在代码中把控件放到指定位置上(其实很简单)
首先new出TextView
TextView textView = new TextView(context,null);
textView.setText(title);//设置Item名称
textView.setTextSize(textSize);//文字大小
textView.setTextColor(textNormalColor);//默认颜色
textView.setId(TEXTVIEW_ID);//textView id
itemTextViews.add(textView);//添加到集合中
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());测量Item图标大小
textView.setCompoundDrawables(null, drawable, null, null);//设置Item图标
把TextView放到RelativeLayout的中间位置
RelativeLayout relativeLayout = new RelativeLayout(context);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);//textView居中
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
textView.setGravity(Gravity.CENTER_HORIZONTAL);//文字居中
relativeLayout.addView(textView, layoutParams);
设置小红点
if (haveRedPoint) {
ImageView imageView = new ImageView(context);
int imageId = IMAGEVIEW_ID + items.size();
imageView.setId(imageId);设置id
Drawable redPoint = context.getResources().getDrawable(R.drawable.red_dot_circle_14px);
imageView.setImageDrawable(redPoint);
RelativeLayout.LayoutParams layoutParamsDot = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParamsDot.addRule(RelativeLayout.ALIGN_RIGHT, TEXTVIEW_ID);
layoutParamsDot.addRule(RelativeLayout.ALIGN_TOP, TEXTVIEW_ID);
relativeLayout.addView(imageView, layoutParamsDot);
imageView.setVisibility(View.GONE);
itemImageViews.put(itemTextViews.size(),imageView);
}
- 点击按钮显示指定fragment
private void showFragment(int viewId) {//viewId为Item的id
Fragment selectedFragment = null;
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
for (Map.Entry viewFragmentEntry : itemFragment.entrySet()) {
Fragment fragment = viewFragmentEntry.getValue();
if (!fragment.isAdded()) {
fragmentTransaction.add(layoutFragment, fragment);
}
RelativeLayout view = (RelativeLayout) viewFragmentEntry.getKey();
int id = view.getId();
if (viewId == id) {//是所当前点击的view
selectedFragment = fragment;
view.setSelected(true);
} else {
fragmentTransaction.hide(fragment);//隐藏其他fragment
view.setSelected(false);
}
}
if (selectedFragment != null) {
fragmentTransaction.show(selectedFragment);//显示当前fragment
}
fragmentTransaction.commit();
}
完整代码
public class BottomAppBar extends LinearLayout {
private float textSize;
private int TEXTVIEW_ID ;
private int IMAGEVIEW_ID ;
private int ITEM_ID ;
private ArrayList items = new ArrayList<>();
private ArrayList itemTextViews = new ArrayList<>();
private HashMap itemFragment = new HashMap<>();
private HashMap itemImageViews = new HashMap<>();
private Context context;
private FragmentManager supportFragmentManager;
private int layoutFragment;
private BottomBarOnClick onClick;
private ColorStateList colorStateList;
private int textNormalColor;
private int textSelectColor;
private int itemRippleColor =-1;
public BottomAppBar(Context context) {
this(context, null);
}
public BottomAppBar(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, -1);
}
public BottomAppBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
init(attrs);
TEXTVIEW_ID = (int) (System.currentTimeMillis()%100*10000);
IMAGEVIEW_ID = (int) (System.currentTimeMillis()%100*1000);
ITEM_ID = (int) (System.currentTimeMillis()%100*100);
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.BottomAppBar);
float dimension = typedArray.getDimension(R.styleable.BottomAppBar_mtextSize, 0);
textSize = Uiutils.px2sp(context,dimension);
textNormalColor = typedArray.getColor(R.styleable.BottomAppBar_mTextNormalColor, 0);
textSelectColor = typedArray.getColor(R.styleable.BottomAppBar_mTextSelectColor, 0);
typedArray.recycle();
}
setOrientation(LinearLayout.HORIZONTAL);
}
/**
* 初始化的第一步
*
* @param Manager FragmentManager
* @param layout Fragment将要显示的容器控件 ViewGroup...
* @return
*/
public BottomAppBar init(FragmentManager Manager, @IdRes int layout) {
this.supportFragmentManager = Manager;
this.layoutFragment = layout;
return this;
}
/**
* 设置Item
*
* @param title item标题
* @param drawable 图标选择器
* @param fragment fragment
* @param redPoint Item是否有小红点
* @return
*/
public BottomAppBar addItem(String title, Drawable drawable, Fragment fragment, boolean redPoint) {
RelativeLayout relativeLayout = initItem(title, drawable, redPoint);
relativeLayout.setId(items.size() + ITEM_ID);
LinearLayout.LayoutParams lp = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);//设置权重为1
relativeLayout.setLayoutParams(lp);
relativeLayout.setTag(items.size());
relativeLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
showFragment(view.getId());
RelativeLayout view1 = (RelativeLayout) view;
view1.setSelected(true);
onClick.onClickBar(view);
}
});
items.add(relativeLayout);
itemFragment.put(relativeLayout, fragment);
return this;
}
/**
* 初始化Item数据
*
* @param title
* @param drawable
* @param haveRedPoint
* @return
*/
private RelativeLayout initItem(String title, Drawable drawable, boolean haveRedPoint) {
TextView textView = new TextView(context,null);
textView.setText(title);
textView.setTextSize(textSize);
textView.setTextColor(textNormalColor);
textView.setId(TEXTVIEW_ID);
itemTextViews.add(textView);
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
textView.setCompoundDrawables(null, drawable, null, null);
RelativeLayout relativeLayout = new RelativeLayout(context);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
relativeLayout.addView(textView, layoutParams);
if (haveRedPoint) {
ImageView imageView = new ImageView(context);
int imageId = IMAGEVIEW_ID + items.size();
imageView.setId(imageId);
Drawable redPoint = context.getResources().getDrawable(R.drawable.red_dot_circle_14px);
imageView.setImageDrawable(redPoint);
RelativeLayout.LayoutParams layoutParamsDot = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParamsDot.addRule(RelativeLayout.ALIGN_RIGHT, TEXTVIEW_ID);
layoutParamsDot.addRule(RelativeLayout.ALIGN_TOP, TEXTVIEW_ID);
relativeLayout.addView(imageView, layoutParamsDot);
imageView.setVisibility(View.GONE);
itemImageViews.put(itemTextViews.size(),imageView);
}
TEXTVIEW_ID++;
return relativeLayout;
}
/**
* 显示fragment
*
* @param viewId
*/
private void showFragment(int viewId) {
Fragment selectedFragment = null;
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
for (Map.Entry viewFragmentEntry : itemFragment.entrySet()) {
Fragment fragment = viewFragmentEntry.getValue();
if (!fragment.isAdded()) {
fragmentTransaction.add(layoutFragment, fragment);
}
RelativeLayout view = (RelativeLayout) viewFragmentEntry.getKey();
int id = view.getId();
TextView childAt = (TextView) view.getChildAt(0);
if (viewId == id) {
selectedFragment = fragment;
view.setSelected(true);
if (childAt!=null){
childAt.setTextColor(textSelectColor);
}
} else {
fragmentTransaction.hide(fragment);
view.setSelected(false);
if (childAt!=null){
childAt.setTextColor(textNormalColor);
}
}
}
if (selectedFragment != null) {
fragmentTransaction.show(selectedFragment);
}
fragmentTransaction.commit();
}
/**
* 设置标题大小
*
* @param sp
* @return
*/
public BottomAppBar setTextSize(float sp) {
this.textSize = sp;
for (TextView itemTextView : itemTextViews) {
itemTextView.setTextSize(textSize);
}
return this;
}
/**
* 设置text颜色选择器
*
* @param resColor
* @return
*/
public BottomAppBar setTextColor(int resColor) {
colorStateList = getResources().getColorStateList(resColor);
for (TextView itemTextView : itemTextViews) {
itemTextView.setTextColor(colorStateList);
}
return this;
}
/**
* 设置item水波纹颜色,apis>21
*
* @param rippleColorRes
* @return
*/
public BottomAppBar setRippleColor(int rippleColorRes) {
itemRippleColor =rippleColorRes;
if (Build.VERSION.SDK_INT>=21) {
for (RelativeLayout item : items) {
Drawable itemBg = context.getResources().getDrawable(rippleColorRes);//R.drawable.bottom_bar_bg
item.setBackground(itemBg);
}
}
return this;
}
/**
* 显示小红点
* @param pointPlace 从左到右第几个小红点,从 1 开始
*
*/
public void showRed(int pointPlace) {
ImageView imageView = itemImageViews.get(pointPlace);
if (imageView!=null) {
imageView.setVisibility(View.VISIBLE);
}
}
/**
* 隐藏小红点
* @param pointPlace 从左到右第几个小红点,从 1 开始
*
*/
public void hideRed(int pointPlace) {
ImageView imageView = itemImageViews.get(pointPlace);
if (imageView!=null) {
imageView.setVisibility(View.GONE);
}
}
/**
* 设置全部的小红点, setRedPoint(1,0,0) 表示从左到右第一个小红点显示,后面两个不显示
* @param show 当前位置的小红点是否显示
*/
public void setRedPoint(int... show) {
for (int i = 0; i < show.length; i++) {
int point = show[i];
ImageView imageView = itemImageViews.get(i+1);
if (imageView!=null) {
if (point > 0) {
imageView.setVisibility(View.VISIBLE);
} else {
imageView.setVisibility(View.GONE);
}
}else{
Log.e("BottomBar","Not founded fragment");
}
}
}
/**
* 把Item添加到bottomBar中
* @param defshow 默认显示第几个fragment,从 1 开始
*/
public void carete(int defshow) {
for (int i = 0; i < items.size(); i++) {
RelativeLayout relativeLayout = (RelativeLayout) items.get(i);
if (itemRippleColor!=-1&&Build.VERSION.SDK_INT>=21) {
Drawable itemBg = context.getResources().getDrawable(itemRippleColor);//R.drawable.bottom_bar_bg
relativeLayout.setBackground(itemBg);
}
addView(relativeLayout);
}
RelativeLayout relativeLayout =null;
try {
relativeLayout = items.get(defshow-1);
}catch (Exception e){
Log.e("BottomBar","Not founded fragment");
}
int id = relativeLayout.getId();
showFragment(id);
}
/**
* 公开的外地调用方法,跳转到指定fragment
* @param page 为导航栏从左到右Item的位置,最左边Item为1
*/
public void showSubPage(int page){
RelativeLayout relativeLayout =null;
try {
relativeLayout = items.get(page-1);
}catch (Exception e){
Log.e("BottomBar","Not founded fragment");
}
int viewId = relativeLayout.getId();
Fragment selectedFragment = null;
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
for (Map.Entry viewFragmentEntry : itemFragment.entrySet()) {
Fragment fragment = viewFragmentEntry.getValue();
RelativeLayout view = (RelativeLayout) viewFragmentEntry.getKey();
int id = view.getId();
TextView childAt = (TextView) view.getChildAt(0);
if (viewId == id) {
selectedFragment = fragment;
view.setSelected(true);
if (childAt!=null){
childAt.setTextColor(textSelectColor);
}
} else {
fragmentTransaction.hide(fragment);
view.setSelected(false);
if (childAt!=null){
childAt.setTextColor(textNormalColor);
}
}
}
if (selectedFragment != null) {
fragmentTransaction.show(selectedFragment);
}
fragmentTransaction.commit();
}
public void setOnBottomBarOnClick(BottomBarOnClick click) {
this.onClick = click;
}
}
总结
看到你的赞,我从天台走了下来!