底部栏android框架_android底部导航栏框架 - CSDN
  • 很多应用都用到底部菜单,微信、大众点评。 效果图 思路:  1.建立一个FrameActivity继承ActivityGroup。此FrameActivity将作为框架,布局实现v4包下viewpage。而viewpage的主要任务是实现将...

    很多应用都用到底部菜单,微信、大众点评。

    效果图



    思路:

            1.建立一个FrameActivity继承ActivityGroup。此FrameActivity将作为框架,布局实现v4包下viewpage。而viewpage的主要任务是实现将Activity放入。

                     1.1初始化控件。findviewbyid

                     1.2把viewpager里面要显示的view实例化出来,并且把相关的view添加到一个list当中。

                     1.3为pageAdapter添加适配器,此设配器注意:运行完一个,就将ViewGroup中的view删除,实现,每次只显示一个view。

                     1.4为每个菜单按钮添加监听器。

                                 1.4.1将viewpage设置到此菜单对应的栏目。

                                 1.4.2初始化底部菜单控件,使菜单初始化。

                                 1.4.3将底部菜单显示到选中状态。

                     1.5为viewpage添加滑动监听器。

                                 1.5.1在onPageSelect中,首先初始化底部菜单。

                                 1.5.2设置当前栏目菜单选中状态。


    主要代码: View view = this.getLocalActivityManager().startActivity("search",new Intent(FrameActivity.this, SearchActivity.class)).getDecorView();

    实现,将Activity转为View对象放到ViewPage中。


    public class FrameActivity extends ActivityGroup {
    
    	private LinearLayout mMyBottemSearchBtn, mMyBottemTuanBtn,
    			mMyBottemCheckinBtn, mMyBottemMyBtn, mMyBottemMoreBtn;
    	private ImageView mMyBottemSearchImg, mMyBottemTuanImg,
    			mMyBottemCheckinImg, mMyBottemMyImg, mMyBottemMoreImg;
    	private TextView mMyBottemSearchTxt, mMyBottemTuanTxt, mMyBottemCheckinTxt,
    			mMyBottemMyTxt, mMyBottemMoreTxt;
    	private List<View> list = new ArrayList<View>();// 相当于数据源
    	private View view = null;
    	private View view1 = null;
    	private View view2 = null;
    	private View view3 = null;
    	private View view4 = null;
    	private android.support.v4.view.ViewPager mViewPager;
    	private PagerAdapter pagerAdapter = null;// 数据源和viewpager之间的桥梁
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.activity_frame);
    		initView();
    	}
    
    	// 初始化控件
    	private void initView() {
    		mViewPager = (ViewPager) findViewById(R.id.FramePager);
    		// 查找以linearlayout为按钮作用的控件
    		mMyBottemSearchBtn = (LinearLayout) findViewById(R.id.MyBottemSearchBtn);
    		mMyBottemTuanBtn = (LinearLayout) findViewById(R.id.MyBottemTuanBtn);
    		mMyBottemCheckinBtn = (LinearLayout) findViewById(R.id.MyBottemCheckinBtn);
    		mMyBottemMyBtn = (LinearLayout) findViewById(R.id.MyBottemMyBtn);
    		mMyBottemMoreBtn = (LinearLayout) findViewById(R.id.MyBottemMoreBtn);
    		// 查找linearlayout中的imageview
    		mMyBottemSearchImg = (ImageView) findViewById(R.id.MyBottemSearchImg);
    		mMyBottemTuanImg = (ImageView) findViewById(R.id.MyBottemTuanImg);
    		mMyBottemCheckinImg = (ImageView) findViewById(R.id.MyBottemCheckinImg);
    		mMyBottemMyImg = (ImageView) findViewById(R.id.MyBottemMyImg);
    		mMyBottemMoreImg = (ImageView) findViewById(R.id.MyBottemMoreImg);
    		// 查找linearlayout中的textview
    		mMyBottemSearchTxt = (TextView) findViewById(R.id.MyBottemSearchTxt);
    		mMyBottemTuanTxt = (TextView) findViewById(R.id.MyBottemTuanTxt);
    		mMyBottemCheckinTxt = (TextView) findViewById(R.id.MyBottemCheckinTxt);
    		mMyBottemMyTxt = (TextView) findViewById(R.id.MyBottemMyTxt);
    		mMyBottemMoreTxt = (TextView) findViewById(R.id.MyBottemMoreTxt);
    		createView();
    		// 写一个内部类pageradapter
    		pagerAdapter = new PagerAdapter() {
    			// 判断再次添加的view和之前的view 是否是同一个view
    			// arg0新添加的view,arg1之前的
    			@Override
    			public boolean isViewFromObject(View arg0, Object arg1) {
    				return arg0 == arg1;
    			}
    
    			// 返回数据源长度
    			@Override
    			public int getCount() {
    				return list.size();
    			}
    
    			// 销毁被滑动走的view
    			/**
    			 * ViewGroup 代表了我们的viewpager 相当于activitygroup当中的view容器, 添加之前先移除。
    			 * position 第几条数据 Object 被移出的view
    			 * */
    			@Override
    			public void destroyItem(ViewGroup container, int position,
    					Object object) {
    				// 移除view
    				container.removeView(list.get(position));
    			}
    
    			/**
    			 * instantiateItem viewpager要现实的view ViewGroup viewpager position
    			 * 第几条数据
    			 * */
    			@Override
    			public Object instantiateItem(ViewGroup container, int position) {
    				// 获取view添加到容器当中,并返回
    				View v = list.get(position);
    				container.addView(v);
    				return v;
    			}
    		};
    		// 设置我们的adapter
    		mViewPager.setAdapter(pagerAdapter);
    
    		MyBtnOnclick mytouchlistener = new MyBtnOnclick();
    		mMyBottemSearchBtn.setOnClickListener(mytouchlistener);
    		mMyBottemTuanBtn.setOnClickListener(mytouchlistener);
    		mMyBottemCheckinBtn.setOnClickListener(mytouchlistener);
    		mMyBottemMyBtn.setOnClickListener(mytouchlistener);
    		mMyBottemMoreBtn.setOnClickListener(mytouchlistener);
    
    		// 设置viewpager界面切换监听,监听viewpager切换第几个界面以及滑动的
    		mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
    			// arg0 获取 viewpager里面的界面切换到第几个的
    			@Override
    			public void onPageSelected(int arg0) {
    				// 先清除按钮样式
    				initBottemBtn();
    				// 按照对应的view的tag来判断到底切换到哪个界面。
    				// 更改对应的button状态
    				int flag = (Integer) list.get((arg0)).getTag();
    				if (flag == 0) {
    					mMyBottemSearchImg
    							.setImageResource(R.drawable.main_index_search_pressed);
    					mMyBottemSearchTxt.setTextColor(Color.parseColor("#FF8C00"));
    				} else if (flag == 1) {
    					mMyBottemTuanImg
    							.setImageResource(R.drawable.main_index_tuan_pressed);
    					mMyBottemTuanTxt.setTextColor(Color.parseColor("#FF8C00"));
    				} else if (flag == 2) {
    					mMyBottemCheckinImg
    							.setImageResource(R.drawable.main_index_checkin_pressed);
    					mMyBottemCheckinTxt.setTextColor(Color
    							.parseColor("#FF8C00"));
    				} else if (flag == 3) {
    					mMyBottemMyImg
    							.setImageResource(R.drawable.main_index_my_pressed);
    					mMyBottemMyTxt.setTextColor(Color.parseColor("#FF8C00"));
    				} else if (flag == 4) {
    					mMyBottemMoreImg
    							.setImageResource(R.drawable.main_index_more_pressed);
    					mMyBottemMoreTxt.setTextColor(Color.parseColor("#FF8C00"));
    				}
    			}
    
    			/**
    			 * 监听页面滑动的 arg0 表示当前滑动的view arg1 表示滑动的百分比 arg2 表示滑动的距离
    			 * */
    			@Override
    			public void onPageScrolled(int arg0, float arg1, int arg2) {
    			}
    
    			/**
    			 * 监听滑动状态 arg0 表示我们的滑动状态 0:默认状态 1:滑动状态 2:滑动停止
    			 * */
    			@Override
    			public void onPageScrollStateChanged(int arg0) {
    			}
    		});
    
    	}
    
    	// 把viewpager里面要显示的view实例化出来,并且把相关的view添加到一个list当中
    	private void createView() {
    		<strong>view = this
    				.getLocalActivityManager()
    				.startActivity("search",
    						new Intent(FrameActivity.this, SearchActivity.class))
    				.getDecorView();</strong>
    		// 用来更改下面button的样式的标志
    		view.setTag(0);
    		list.add(view);
    		view1 = FrameActivity.this
    				.getLocalActivityManager()
    				.startActivity("tuan",
    						new Intent(FrameActivity.this, TuanActivity.class))
    				.getDecorView();
    		view1.setTag(1);
    		list.add(view1);
    		view2 = FrameActivity.this
    				.getLocalActivityManager()
    				.startActivity("sign",
    						new Intent(FrameActivity.this, CheckinActivity.class))
    				.getDecorView();
    		view2.setTag(2);
    		list.add(view2);
    		view3 = FrameActivity.this
    				.getLocalActivityManager()
    				.startActivity("my",
    						new Intent(FrameActivity.this, MyActivity.class))
    				.getDecorView();
    		view3.setTag(3);
    		list.add(view3);
    		view4 = FrameActivity.this
    				.getLocalActivityManager()
    				.startActivity("more",
    						new Intent(FrameActivity.this, MoreActivity.class))
    				.getDecorView();
    		view4.setTag(4);
    		list.add(view4);
    	}
    
    	/**
    	 * 用linearlayout作为按钮的监听事件
    	 * */
    	private class MyBtnOnclick implements View.OnClickListener {
    
    		@Override
    		public void onClick(View arg0) {
    			int mBtnid = arg0.getId();
    			switch (mBtnid) {
    			case R.id.MyBottemSearchBtn:
    				// //设置我们的viewpager跳转那个界面0这个参数和我们的list相关,相当于list里面的下标
    				mViewPager.setCurrentItem(0);
    				initBottemBtn();
    				mMyBottemSearchImg
    						.setImageResource(R.drawable.main_index_search_pressed);
    				mMyBottemSearchTxt.setTextColor(Color.parseColor("#FF8C00"));
    				break;
    			case R.id.MyBottemTuanBtn:
    				mViewPager.setCurrentItem(1);
    				initBottemBtn();
    				mMyBottemTuanImg
    						.setImageResource(R.drawable.main_index_tuan_pressed);
    				mMyBottemTuanTxt.setTextColor(Color.parseColor("#FF8C00"));
    				break;
    			case R.id.MyBottemCheckinBtn:
    				mViewPager.setCurrentItem(2);
    				initBottemBtn();
    				mMyBottemCheckinImg
    						.setImageResource(R.drawable.main_index_checkin_pressed);
    				mMyBottemCheckinTxt.setTextColor(Color.parseColor("#FF8C00"));
    				break;
    			case R.id.MyBottemMyBtn:
    				mViewPager.setCurrentItem(3);
    				initBottemBtn();
    				mMyBottemMyImg
    						.setImageResource(R.drawable.main_index_my_pressed);
    				mMyBottemMyTxt.setTextColor(Color.parseColor("#FF8C00"));
    				break;
    			case R.id.MyBottemMoreBtn:
    				mViewPager.setCurrentItem(4);
    				initBottemBtn();
    				mMyBottemMoreImg
    						.setImageResource(R.drawable.main_index_more_pressed);
    				mMyBottemMoreTxt.setTextColor(Color.parseColor("#FF8C00"));
    				break;
    			}
    
    		}
    
    	}
    
    	/**
    	 * 初始化控件的颜色
    	 * */
    	private void initBottemBtn() {
    		mMyBottemSearchImg.setImageResource(R.drawable.search_bottem_search);
    		mMyBottemTuanImg.setImageResource(R.drawable.search_bottem_tuan);
    		mMyBottemCheckinImg.setImageResource(R.drawable.search_bottem_checkin);
    		mMyBottemMyImg.setImageResource(R.drawable.search_bottem_my);
    		mMyBottemMoreImg.setImageResource(R.drawable.search_bottem_more);
    		mMyBottemSearchTxt.setTextColor(getResources().getColor(
    				R.color.search_bottem_textcolor));
    		mMyBottemTuanTxt.setTextColor(getResources().getColor(
    				R.color.search_bottem_textcolor));
    		mMyBottemCheckinTxt.setTextColor(getResources().getColor(
    				R.color.search_bottem_textcolor));
    		mMyBottemMyTxt.setTextColor(getResources().getColor(
    				R.color.search_bottem_textcolor));
    		mMyBottemMoreTxt.setTextColor(getResources().getColor(
    				R.color.search_bottem_textcolor));
    	}
    
    	/**
    	 * 返回按钮的监听,用来询问用户是否退出程序
    	 * */
    	@Override
    	public boolean onKeyDown(int keyCode, KeyEvent event) {
    		if (keyCode == KeyEvent.KEYCODE_BACK) {
    			if (keyCode == KeyEvent.KEYCODE_BACK) {
    				Builder builder = new Builder(FrameActivity.this);
    				builder.setTitle("提示");
    				builder.setMessage("你确定要退出吗?");
    				builder.setIcon(R.drawable.ic_launcher);
    
    				DialogInterface.OnClickListener dialog = new DialogInterface.OnClickListener() {
    
    					@Override
    					public void onClick(DialogInterface arg0, int arg1) {
    						if (arg1 == DialogInterface.BUTTON_POSITIVE) {
    							arg0.cancel();
    						} else if (arg1 == DialogInterface.BUTTON_NEGATIVE) {
    							FrameActivity.this.finish();
    						}
    					}
    				};
    				builder.setPositiveButton("取消", dialog);
    				builder.setNegativeButton("确定", dialog);
    				AlertDialog alertDialog = builder.create();
    				alertDialog.show();
    
    			}
    		}
    		return false;
    	}
    }
    


    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff" >
    
        <LinearLayout
            android:id="@+id/Frame_BottemView"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_alignParentBottom="true"
            android:background="@drawable/tab_bar_bg"
            android:orientation="horizontal" >
    
            <LinearLayout
                android:id="@+id/MyBottemSearchBtn"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical|center_horizontal"
                android:orientation="vertical" >
    
                <ImageView
                    android:id="@+id/MyBottemSearchImg"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/main_index_search_pressed" />
    
                <TextView
                    android:id="@+id/MyBottemSearchTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="查找"
                    android:textColor="#FF8C00"
                    android:textSize="13dp" />
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/MyBottemTuanBtn"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical|center_horizontal"
                android:orientation="vertical" >
    
                <ImageView
                    android:id="@+id/MyBottemTuanImg"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/search_bottem_tuan" />
    
                <TextView
                    android:id="@+id/MyBottemTuanTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="团购"
                    android:textColor="@color/search_bottem_textcolor"
                    android:textSize="13dp" />
    
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/MyBottemCheckinBtn"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical|center_horizontal"
                android:orientation="vertical" >
    
                <ImageView
                    android:id="@+id/MyBottemCheckinImg"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/search_bottem_checkin" />
    
                <TextView
                    android:id="@+id/MyBottemCheckinTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="签到"
                    android:textColor="@color/search_bottem_textcolor"
                    android:textSize="13dp" />
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/MyBottemMyBtn"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical|center_horizontal"
                android:orientation="vertical" >
    
                <ImageView
                    android:id="@+id/MyBottemMyImg"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/search_bottem_my" />
    
                <TextView
                    android:id="@+id/MyBottemMyTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="我的"
                    android:textColor="@color/search_bottem_textcolor"
                    android:textSize="13dp" />
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/MyBottemMoreBtn"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical|center_horizontal"
                android:orientation="vertical" >
    
                <ImageView
                    android:id="@+id/MyBottemMoreImg"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/search_bottem_more" />
    
                <TextView
                    android:id="@+id/MyBottemMoreTxt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="更多"
                    android:textColor="@color/search_bottem_textcolor"
                    android:textSize="13dp" />
            </LinearLayout>
        </LinearLayout>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/FramePager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/Frame_BottemView" >
        </android.support.v4.view.ViewPager>
    
    </RelativeLayout>


      其他Activity雷同:

    public class TuanActivity extends Activity {
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		TextView textView = new TextView(this);
    		textView.setText("TuanActivity");
    		setContentView(textView);
    	}
    }
    

         

    源码下载地址:http://download.csdn.net/detail/u010016914/8197723

    展开全文
  • 研究bottomnaviagtionbar控件,制作底部导航,app搭框架时用可以,很好用的
  • 这个底部导航的特点: 1.告别xml中的item布局,一切icon、title统统绘制得出; 2.扁平化,由于icon、title都是绘制得出的,所以只需要一个view即可,无需父布局 3.为你处理好碎片切换事务,告别冗余代码,让你从此...

    转载自这个项目的github地址:https://github.com/xubinhong/BottomBar

    这个底部导航栏的特点:

    1.告别xml中的item布局,一切icon、title统统绘制得出;

    2.扁平化,由于icon、title都是绘制得出的,所以只需要一个view即可,无需父布局

    3.为你处理好碎片切换事务,告别冗余代码,让你从此光速开发

    4.不怕需求变动,拔插式体验,增删item,只需修改1行代码

    5.源代码十分简单,有助于使用者开发高度适配自身需求的底部

    使用方式

    1.只需要到给出的github地址中拷贝BottomBar类到你的包下即可,或者自己创建一个类名字叫BottomBar,复制如下代码并导包:

    public class BottomBar extends View{
    
        private Context context;
    
        public BottomBar(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.context = context;
        }
    
        //////////////////////////////////////////////////
        //提供的api 并且根据api做一定的物理基础准备
        //////////////////////////////////////////////////
    
        private int containerId;
    
        private List<Class> fragmentClassList = new ArrayList<>();
        private List<String> titleList = new ArrayList<>();
        private List<Integer> iconResBeforeList = new ArrayList<>();
        private List<Integer> iconResAfterList = new ArrayList<>();
    
        private List<Fragment> fragmentList = new ArrayList<>();
    
        private int itemCount;
    
        private Paint paint = new Paint();
    
        private List<Bitmap> iconBitmapBeforeList = new ArrayList<>();
        private List<Bitmap> iconBitmapAfterList = new ArrayList<>();
        private List<Rect> iconRectList = new ArrayList<>();
    
        private int currentCheckedIndex;
        private int firstCheckedIndex;
    
        private int titleColorBefore = Color.parseColor("#999999");
        private int titleColorAfter = Color.parseColor("#ff5d5e");
    
        private int titleSizeInDp = 10;
        private int iconWidth = 20;
        private int iconHeight = 20;
        private int titleIconMargin = 5;
    
        public BottomBar setContainer(int containerId) {
            this.containerId = containerId;
            return this;
        }
    
        public BottomBar setTitleBeforeAndAfterColor(String beforeResCode, String AfterResCode) {//支持"#333333"这种形式
            titleColorBefore = Color.parseColor(beforeResCode);
            titleColorAfter = Color.parseColor(AfterResCode);
            return this;
        }
    
        public BottomBar setTitleSize(int titleSizeInDp) {
            this.titleSizeInDp = titleSizeInDp;
            return this;
        }
    
        public BottomBar setIconWidth(int iconWidth) {
            this.iconWidth = iconWidth;
            return this;
        }
    
        public BottomBar setTitleIconMargin(int titleIconMargin) {
            this.titleIconMargin = titleIconMargin;
            return this;
        }
    
        public BottomBar setIconHeight(int iconHeight) {
            this.iconHeight = iconHeight;
            return this;
        }
    
        public BottomBar addItem(Class fragmentClass, String title, int iconResBefore, int iconResAfter) {
            fragmentClassList.add(fragmentClass);
            titleList.add(title);
            iconResBeforeList.add(iconResBefore);
            iconResAfterList.add(iconResAfter);
            return this;
        }
    
        public BottomBar setFirstChecked(int firstCheckedIndex) {//从0开始
            this.firstCheckedIndex = firstCheckedIndex;
            return this;
        }
    
        public void build() {
            itemCount = fragmentClassList.size();
            //预创建bitmap的Rect并缓存
            //预创建icon的Rect并缓存
            for (int i = 0; i < itemCount; i++) {
                Bitmap beforeBitmap = getBitmap(iconResBeforeList.get(i));
                iconBitmapBeforeList.add(beforeBitmap);
    
                Bitmap afterBitmap = getBitmap(iconResAfterList.get(i));
                iconBitmapAfterList.add(afterBitmap);
    
                Rect rect = new Rect();
                iconRectList.add(rect);
    
                Class clx = fragmentClassList.get(i);
                try {
                    Fragment fragment = (Fragment) clx.newInstance();
                    fragmentList.add(fragment);
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
    
            currentCheckedIndex = firstCheckedIndex;
            switchFragment(currentCheckedIndex);
    
            invalidate();
        }
    
        private Bitmap getBitmap(int resId) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) context.getResources().getDrawable(resId);
            return bitmapDrawable.getBitmap();
        }
    
        //////////////////////////////////////////////////
        //初始化数据基础
        //////////////////////////////////////////////////
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            initParam();
        }
    
        private int titleBaseLine;
        private List<Integer> titleXList = new ArrayList<>();
    
        private int parentItemWidth;
    
        private void initParam() {
            if (itemCount != 0) {
                //单个item宽高
                parentItemWidth = getWidth() / itemCount;
                int parentItemHeight = getHeight();
    
                //图标边长
                int iconWidth = dp2px(this.iconWidth);//先指定20dp
                int iconHeight = dp2px(this.iconHeight);
    
                //图标文字margin
                int textIconMargin = dp2px(((float)titleIconMargin)/2);//先指定5dp,这里除以一半才是正常的margin,不知道为啥,可能是图片的原因
    
                //标题高度
                int titleSize = dp2px(titleSizeInDp);//这里先指定10dp
                paint.setTextSize(titleSize);
                Rect rect = new Rect();
                paint.getTextBounds(titleList.get(0), 0, titleList.get(0).length(), rect);
                int titleHeight = rect.height();
    
                //从而计算得出图标的起始top坐标、文本的baseLine
                int iconTop = (parentItemHeight - iconHeight - textIconMargin - titleHeight)/2;
                titleBaseLine = parentItemHeight - iconTop;
    
                //对icon的rect的参数进行赋值
                int firstRectX = (parentItemWidth - iconWidth) / 2;//第一个icon的左
                for (int i = 0; i < itemCount; i++) {
                    int rectX = i * parentItemWidth + firstRectX;
    
                    Rect temp = iconRectList.get(i);
    
                    temp.left = rectX;
                    temp.top = iconTop ;
                    temp.right = rectX + iconWidth;
                    temp.bottom = iconTop + iconHeight;
                }
    
                //标题(单位是个问题)
                for (int i = 0; i < itemCount; i ++) {
                    String title = titleList.get(i);
                    paint.getTextBounds(title, 0, title.length(), rect);
                    titleXList.add((parentItemWidth - rect.width()) / 2 + parentItemWidth * i);
                }
            }
        }
    
        private int dp2px(float dpValue) {
            float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    
        //////////////////////////////////////////////////
        //根据得到的参数绘制
        //////////////////////////////////////////////////
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);//这里让view自身替我们画背景 如果指定的话
    
            if (itemCount != 0) {
                //画背景
                paint.setAntiAlias(false);
                for (int i = 0; i < itemCount; i++) {
                    Bitmap bitmap = null;
                    if (i == currentCheckedIndex) {
                        bitmap = iconBitmapAfterList.get(i);
                    } else {
                        bitmap = iconBitmapBeforeList.get(i);
                    }
                    Rect rect = iconRectList.get(i);
                    canvas.drawBitmap(bitmap, null, rect, paint);//null代表bitmap全部画出
                }
    
                //画文字
                paint.setAntiAlias(true);
                for (int i = 0; i < itemCount; i ++) {
                    String title = titleList.get(i);
                    if (i == currentCheckedIndex) {
                        paint.setColor(titleColorAfter);
                    } else {
                        paint.setColor(titleColorBefore);
                    }
                    int x = titleXList.get(i);
                    canvas.drawText(title, x, titleBaseLine, paint);
                }
            }
        }
    
        //////////////////////////////////////////////////
        //点击事件:我观察了微博和掌盟,发现down和up都在该区域内才响应
        //////////////////////////////////////////////////
    
        int target = -1;
    
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN :
                    target = withinWhichArea((int)event.getX());
                    break;
                case MotionEvent.ACTION_UP :
                    if (event.getY() < 0) {
                        break;
                    }
                    if (target == withinWhichArea((int)event.getX())) {
                        //这里触发点击事件
                        switchFragment(target);
                        currentCheckedIndex = target;
                        invalidate();
                    }
                    target = -1;
                    break;
            }
            return true;
            //这里return super为什么up执行不到?是因为return super的值,全部取决于你是否
            //clickable,当你down事件来临,不可点击,所以return false,也就是说,而且你没
            //有设置onTouchListener,并且控件是ENABLE的,所以dispatchTouchEvent的返回值
            //也是false,所以在view group的dispatchTransformedTouchEvent也是返回false,
            //这样一来,view group中的first touch target就是空的,所以intercept标记位
            //果断为false,然后就再也进不到循环取孩子的步骤了,直接调用dispatch-
            // TransformedTouchEvent并传孩子为null,所以直接调用view group自身的dispatch-
            // TouchEvent了
        }
    
        private int withinWhichArea(int x) { return x/parentItemWidth; }//从0开始
    
        //////////////////////////////////////////////////
        //碎片处理代码
        //////////////////////////////////////////////////
        private Fragment currentFragment;
    
        //注意 这里是只支持AppCompatActivity 需要支持其他老版的 自行修改
        protected void switchFragment(int whichFragment) {
            Fragment fragment = fragmentList.get(whichFragment);
            int frameLayoutId = containerId;
    
            if (fragment != null) {
                FragmentTransaction transaction = ((AppCompatActivity)context).getSupportFragmentManager().beginTransaction();
                if (fragment.isAdded()) {
                    if (currentFragment != null) {
                        transaction.hide(currentFragment).show(fragment);
                    } else {
                        transaction.show(fragment);
                    }
                } else {
                    if (currentFragment != null) {
                        transaction.hide(currentFragment).add(frameLayoutId, fragment);
                    } else {
                        transaction.add(frameLayoutId, fragment);
                    }
                }
                currentFragment = fragment;
                transaction.commit();
            }
        }
    }
    
    

    2.xml中

    <com.example.bottombar.BottomBar
        android:background="#FFFFFF"
        android:id="@+id/bottom_bar"
        android:layout_width="match_parent"
        android:layout_height="46dp"
        android:layout_gravity="bottom" />
    

    3.java代码中

    BottomBar bottomBar = findViewById(R.id.bottom_bar);
    bottomBar.setContainer(R.id.fl_container)
            .setTitleBeforeAndAfterColor("#999999", "#ff5d5e")
            .addItem(Fragment1.class,
                    "首页",
                    R.drawable.item1_before,
                    R.drawable.item1_after)
            .addItem(Fragment2.class,
                    "订单",
                    R.drawable.item2_before,
                    R.drawable.item2_after)
            .addItem(Fragment3.class,
                    "我的",
                    R.drawable.item3_before,
                    R.drawable.item3_after)
            .build();
    

    设置了容器frame layout

    设置了字体选中前后的颜色

    增加了item,并且给item绑定碎片,设定选中前后的drawable以及文本

    就这么简单的代码,就搞定了一切!效果如下:

    image.png

    而如果你正常写一个底部导航栏是怎样的?

    1.item布局,你还得精心设置半天

    2.底部title布局,引入若干

    3.title布局放到主布局中

    4.java代码中要通过findViewById找到所有item

    5.给所有item设置点击事件

    6.点击事件内作碎片的切换

    7.当你如果要增加一个item的时候,前面的又要大幅度修改,而且代码冗余程度极高

    如果你对里面icon、title的位置不满意,有更多的api供你选择

    setTitleSize,以dp为单位

    setIconWidth,图标宽度

    setIconHeight,图标高度

    setTitleIconMargin,标题图标间距

    setFirstChecked,设置第一个默认选中item

    由于源代码简单,易于阅读,开发者更可以自行修改源码

    底部导航栏设计思路

    根据api中获取的参数,计算出icon、title的精确位置,并在onDraw中绘制

    在onTouchEvent里,根据触摸点,获知点击区域,响应Icon、title的更改事件以及碎片的切换事件

    另一个BottomBar的实战应用可以看:

    https://blog.csdn.net/qq_36523667/article/details/79983010

    再次证明了,BottomBar,实在太方便啦!

    @希望能帮到大家!

    在这里插入图片描述

    展开全文
  • TabLayout是android.support.design里的一个控件,使用它可以很方便的做出顶部导航和底部导航。类似于这样的,能设置选中时字体的颜色和选中时的图片。 首先我们引入compile 'com.android.support:design:23.1.1'...

    TabLayout是android.support.design里的一个控件,使用它可以很方便的做出顶部导航和底部导航。类似于这样的,能设置选中时字体的颜色和选中时的图片。



    首先我们引入compile 'com.android.support:design:23.1.1'

    它的用法是:

    第一种比较简单,就是文本和一个指示器。

    布局文件是

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical">
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#32CD32"
            app:tabIndicatorColor="#f00"
            app:tabSelectedTextColor="#444"
            app:tabMode="fixed"
            app:tabTextColor="#fff" />
    
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    
    </LinearLayout> 
        顶部是一个TabLayout,可以设置background。app:tabIndicatorColor是设置指示器的背景颜色,app:tabIndicatorHeight设置指示器的高度,app:tabSelectedTextColor是选中时文本的颜色,app:tabTextColor是普通状态的文本颜色,app:tabMode是是否可滑动,有两个fixed和scrollable,fixed是固定的,scrollable是类似于今日头条那种可以滑动的。

        java代码

    import android.app.Fragment;
    import android.os.Bundle;
    import android.support.design.widget.TabLayout;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    
    import com.tianyalei.wolf.mddesignlib.view.titlelayout.TitleFragmentPagerAdapter;
    import com.tianyalei.wolf.sample.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import butterknife.Bind;
    import butterknife.ButterKnife;
    
    public class TabActivity extends AppCompatActivity {
    
        @Bind(R.id.tab)
        TabLayout tabLayout;
        @Bind(R.id.viewpager)
        ViewPager viewpager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_tab);
            ButterKnife.bind(this);
    
    //        tabLayout.setTabTextColors(Color.WHITE, Color.GRAY);//设置文本在选中和为选中时候的颜色
    //        tabLayout.setSelectedTabIndicatorColor(Color.WHITE);//设置选中时的指示器的颜色
    //        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);//可滑动,默认是FIXED
    
    
            List<Fragment> fragments = new ArrayList<>();
            fragments.add(new BlankFragment());
            fragments.add(new BlankFragment());
            fragments.add(new BlankFragment());
    
            TitleFragmentPagerAdapter adapter = new TitleFragmentPagerAdapter(getFragmentManager(), fragments, new String[]{"第一栏", "第二栏", "第三栏"});
            viewpager.setAdapter(adapter);
    
            tabLayout.setupWithViewPager(viewpager);
        }
    
    }
    
    TitleFragmentPagerAdapter是viewpager的适配器,
    /*
     * Copyright (C) 2012 www.amsoft.cn
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.tianyalei.wolf.mddesignlib.view.titlelayout;
    
    import android.app.Fragment;
    import android.app.FragmentManager;
    import android.support.v13.app.FragmentPagerAdapter;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * © 2012 amsoft.cn 名称:TitleFragmentPagerAdapter.java 描述:一个通用的Fragment适配器
     *
     * @author wolf
     * @version v1.0
     * @date:2016-3-7 上午10:57:53
     */
    public class TitleFragmentPagerAdapter extends FragmentPagerAdapter {
    
        /**
         * The m fragment list.
         */
        private List<Fragment> mFragmentList = null;
    
        private String[] titles;
    
        /**
         * Instantiates a new ab fragment pager adapter.
         *
         * @param mFragmentManager the m fragment manager
         * @param fragmentList     the fragment list
         */
        public TitleFragmentPagerAdapter(FragmentManager mFragmentManager,
                                         ArrayList<Fragment> fragmentList) {
            super(mFragmentManager);
            mFragmentList = fragmentList;
        }
    
        /**
         * titles是给TabLayout设置title用的
         *
         * @param mFragmentManager
         * @param fragmentList
         * @param titles
         */
        public TitleFragmentPagerAdapter(FragmentManager mFragmentManager,
                                         List<Fragment> fragmentList, String[] titles) {
            super(mFragmentManager);
            mFragmentList = fragmentList;
            this.titles = titles;
        }
    
        /**
         * 描述:获取数量.
         *
         * @return the count
         * @see android.support.v4.view.PagerAdapter#getCount()
         */
        @Override
        public int getCount() {
            return mFragmentList.size();
        }
    
        /**
         * 描述:获取索引位置的Fragment.
         *
         * @param position the position
         * @return the item
         * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
         */
        @Override
        public Fragment getItem(int position) {
    
            Fragment fragment = null;
            if (position < mFragmentList.size()) {
                fragment = mFragmentList.get(position);
            } else {
                fragment = mFragmentList.get(0);
            }
            return fragment;
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            if (titles != null && titles.length > 0)
                return titles[position];
            return null;
        }
    }
    
    需要注意的是getPageTitle方法,返回viewpager对应的title。

    以上就是TabLayout和viewpager结合的简单例子。

    下面说第二种带图片的底部导航,

    其实也很简单,就是把TabLayout放到底部,上面是viewpager,然后给text设置个图片就行了。布局如下

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical">
    
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabBackground="@drawable/selector_bg"
            style="@style/MyCustomTabLayout"/>
    
    </LinearLayout> 
    style里面设置了一些属性
    <style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
            <item name="tabIndicatorColor">?attr/colorAccent</item>
            <item name="tabIndicatorHeight">0dp</item>
            <item name="tabPaddingStart">12dp</item>
            <item name="tabTextColor">#aaa</item>
            <item name="tabPaddingEnd">12dp</item>
            <item name="tabSelectedTextColor">#f00</item>
        </style>
    tabIndicatorHeight是设置导航那个指示器高度为0,因为不需要那个指示器了。然后app:tabBackground这个属性待会再说。

    代码如下

    package com.tianyalei.wolf.sample.activity;
    
    import android.annotation.TargetApi;
    import android.app.Fragment;
    import android.graphics.drawable.Drawable;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.design.widget.TabLayout;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    
    import com.tianyalei.wolf.mddesignlib.view.titlelayout.TitleFragmentPagerAdapter;
    import com.tianyalei.wolf.sample.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import butterknife.Bind;
    import butterknife.ButterKnife;
    
    public class TabBottomActivity extends AppCompatActivity {
    
        @Bind(R.id.tab)
        TabLayout tabLayout;
        @Bind(R.id.viewpager)
        ViewPager viewpager;
    
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_bottom_tab);
            ButterKnife.bind(this);
    
            List<Fragment> fragments = new ArrayList<>();
            fragments.add(new BlankFragment());
            fragments.add(new BlankFragment());
            fragments.add(new BlankFragment());
            fragments.add(new BlankFragment());
            TitleFragmentPagerAdapter adapter = new TitleFragmentPagerAdapter(getFragmentManager(), fragments, new String[]{"首页", "流量", "社区", "关于"});
            viewpager.setAdapter(adapter);
    
            tabLayout.setupWithViewPager(viewpager);
    
            for (int i = 0; i < tabLayout.getTabCount(); i++) {
                TabLayout.Tab tab = tabLayout.getTabAt(i);
                 Drawable d = null;
                 switch (i) {
                        case 0:
                            d = getResources().getDrawable(R.drawable.selector_home);
                            break;
                        case 1:
                            d = getResources().getDrawable(R.drawable.selector_mall);
                            break;
                        case 2:
                            d = getResources().getDrawable(R.drawable.selector_socially);
                            break;
                        case 3:
                            d = getResources().getDrawable(R.drawable.selector_more);
                            break;
                    }
                tab.setIcon(d);
            }
    //        viewpager.setCurrentItem(2);
        }
    
    }
    
    前面的部分没什么好说的。下面的那块是设置图片的,就是在selected的时候把图片换成选中态的图片。遍历tab,给tab设置icon,icon就是selector。

    R.drawable.selector_home

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android = "http://schemas.android.com/apk/res/android">
        <item android:drawable = "@drawable/nav_home_pre" android:state_selected = "true" />
        <item android:drawable = "@drawable/nav_home" android:state_selected = "false" />
    </selector>
    OK,以上做完就可以了,带图片的底部导航栏就做好了。

    下面说一下app:tabBackground,这个是设置单项的背景颜色的,见下图

    
    就是如果你需要给单项选中时设置个背景,那就用app:tabBackground,也写一个颜色的selector就行了。不需要改变背景的话就不用设置这个属性了。
    


    以上的代码可以从oschina的git托管http://git.oschina.net/tianyalei/MDDesignLib获取,TabLayout相关的在Sample的TabActivity那里。

    展开全文
  • Android4.2.2中,导航(也就是屏幕底部的三个按钮,home,back,recentapp)是系统应用SystemUi.apk的一部分,简言之,我们的需求就是让我们的app来控制SystemUi.apk,达到动态显示隐藏屏幕底部导航的效果。...
  • TabBar这个名字相信很多学过一点IOS程序员都知道它是用来干嘛的,但本人也并非擅长开发IOS程序员,只是略懂略懂....这是一个很强大的TabBar,可满足很多需求。用起来也非常简单,在oncreate只调用一行代码就把UI布局和...

    TabBar这个名字相信很多学过一点IOS程序员都知道它是用来干嘛的,但本人也并非擅长开发IOS程序员,只是略懂略懂....这是一个很强大的TabBar,可满足很多需求。用起来也非常简单,在oncreate只调用一行代码就把UI布局和切换页面功能基本都实现了。具体实现的功能,请看效果图:

    主

    使用方法:

    1.引入Gradle依赖
     repositories { 
           jcenter()   
     }   
    
     dependencies{     
       compile 'com.jpeng:JPTabBar:1.0.4'   
     }
    2.在你的主页面XML,在适当位置添加下面代码

    <com.jpeng.jptabbar.JPTabBar
        android:layout_alignParentBottom="true"
        android:id="@+id/tabbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        app:TabHeight="56dp"
        app:BadgeDraggable="true"
        app:TabAnimate="Jump"
        app:BadgePadding="4dp"
        app:BadgeMargin="5dp"
        app:BadgeTextSize="10dp"
        />
    3.在你的Activity里面声明注解变量。(seleIcons和BadgeModes可以不声明,还有你要确保你全部数组的长度是一样的)

    //设置标题
    @Titles
    private static final String[] mTitles={"微信","通讯录","发现",""};
    
    //设置选中图标
    @SeleIcons
    private static final int[] mSelectIcons={R.mipmap.al_,R.mipmap.al8,R.mipmap.alb,R.mipmap.ald};
    
    //设置未选中图标
    @NorIcons
    private static final int[] mNormalIcon={R.mipmap.ala,R.mipmap.al9,R.mipmap.alc,R.mipmap.ale};

    经过上面的设置后,基本上就可以把一个底部的UI搭建了!
    但还有一步,想达到Wechat那种渐变和自动切换ViewPager就使用这个方法:

     mTabBar.setContainer(mVp);  //mVp是ViewPager对象
    
    

    方法和节点说明:

    JPTabBar主要方法:

     /**     * 设置自定义Tab切换动画     */    public void setCustomAnimate(Animatable customAnimate);     
    /** 显示BadgeView ,传入字符串     * 当然还有一个重载方法,第二个参数为int,设置消息数量     * 传入""字符串显示圆点     */    public void ShowBadge(int position,String text);    /**     * 隐藏BadgeView     */    public void HideBadge(int position);    /**     * 切换Tab页面,是否带动画     */    public void setSelectTab(int index, boolean animated);    /**     * 设置点击TabBar事件的观察者     */    public void setTabListener(OnTabSelectListener listener);    /**     * 设置badgeView消失的回调事件     */    public void setDismissListener(BadgeDismissListener listener);

    结点说明:

    结点名字 结点说明 参数类型 默认值
    TabHeight TabBar的高度,将会覆盖layout_height的设置 dimension 56dp
    TabNormalColor 字体和图标的未选中颜色 color 0xffAEAEAE(灰色)
    TabSelectColor 字体和图标的选中的颜色 color 0xff59D9B9(青色)
    TabTextSize Tab底部文件大小 dimension 14sp
    TabIconSize Tab图标的大小 dimension 24dp
    TabIconFilter 设置图标是否随着字体颜色而改变 boolean true
    TabMargin 设置图标距离上面和文字距离下面的距离 dimension 8dp
    TabSelectBg 设置TabBarItem选中的背景颜色 color 透明
    TabDuration Tab切换的动画时间 Integer 500
    TabAnimate Tab切换的动画类型 enum Flip
    TabMiddleIcon Tab中间的图标 drawable
    BadgeColor 徽章的背景颜色 color #f00(红色)
    BadgeDraggable 徽章是否可以拖动 boolean false
    BadgePadding 徽章的背景扩展距离 dimension 4dp
    BadgeTextSize 徽章显示的字体大小 dimension 11dp
    BadgeMargin 徽章距离右边边缘的间隔 dimension 9dp

    注意事项

    1.假如你已经给TabBar setContainer,不要setOnPageChangeListener给ViewPager

    /**    *如果你前面已经给TabBar设置了容器,然后调用这个方法的话,类似WeChat那种拖动渐变效果以及自动切换页面将会失效    *假如你要监听页面改变事件,可以使用TabListener   */  mPager.setOnPageChangeListener(this);

    2.假如你要实现中间凸出的按钮,必须要在主界面最外围的父结点设置 android:clipChildren="false",否则会遮盖

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:jp="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        android:gravity="bottom"
        android:orientation="vertical"
        >



    下面是实现微信底部导航栏的完整代码:

    activity的xml代码:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context="com.cf.android_navigtionbottombar.MainActivity">
       <android.support.v4.view.ViewPager
           android:id="@+id/vp"
           android:layout_above="@+id/tabbar"
           android:layout_width="match_parent"
           android:layout_height="match_parent"/>
       <com.jpeng.jptabbar.JPTabBar
           android:layout_alignParentBottom="true"
           android:id="@+id/tabbar"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="#fff"
           app:TabHeight="56dp"
           app:BadgeDraggable="true"
           app:TabAnimate="Jump"
           app:BadgePadding="4dp"
           app:BadgeMargin="5dp"
           app:BadgeTextSize="10dp"
           />
    </RelativeLayout>

    activity的java代码:

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    
    import com.jpeng.jptabbar.JPTabBar;
    import com.jpeng.jptabbar.anno.NorIcons;
    import com.jpeng.jptabbar.anno.SeleIcons;
    import com.jpeng.jptabbar.anno.Titles;
    
    import layout.HomeFragment;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final int ITEMPAGER = 4;
        private ViewPager mVp;
        private JPTabBar mTabBar;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
             initView();
    
            ViewPagerAdapter adapter=new ViewPagerAdapter(getSupportFragmentManager());
            mVp.setAdapter(adapter);
            mTabBar.setContainer(mVp);
        }
    
        private void initView() {
            mVp = (ViewPager) findViewById(R.id.vp);
            mTabBar = (JPTabBar) findViewById(R.id.tabbar);
        }
    
        //设置标题
        @Titles
        private static final String[] mTitles={"微信","通讯录","发现",""};
    
        //设置选中图标
        @SeleIcons
        private static final int[] mSelectIcons={R.mipmap.al_,R.mipmap.al8,R.mipmap.alb,R.mipmap.ald};
    
        //设置未选中图标
        @NorIcons
        private static final int[] mNormalIcon={R.mipmap.ala,R.mipmap.al9,R.mipmap.alc,R.mipmap.ale};
    
        //Fragment适配器
        private class ViewPagerAdapter extends FragmentStatePagerAdapter{
    
            public ViewPagerAdapter(FragmentManager fm) {
                super(fm);
            }
    
            @Override
            public Fragment getItem(int position) {
                Bundle bundle=new Bundle();
                bundle.putInt("position",position+1);
                HomeFragment fragment = new HomeFragment();
                fragment.setArguments(bundle);
                return fragment;
            }
    
            @Override
            public int getCount() {
                return ITEMPAGER;
            }
        }
    }

    Fragment Java代码:

    public class HomeFragment extends Fragment {
    
    
        public HomeFragment() {
            // Required empty public constructor
        }
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.fragment_home, container, false);
            initView(view);
            return view;
        }
    
        private void initView(View view) {
            TextView tvShow = (TextView) view.findViewById(R.id.tvShow);
            Bundle bundle = getArguments();
            int position = bundle.getInt("position");
            tvShow.setText(""+position+"Fragment");
        }
    
    }

    Fragment Xml代码:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="layout.HomeFragment">
    
        <!-- TODO: Update blank fragment layout -->
        <TextView
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="25sp"
            android:id="@+id/tvShow"
            android:text="@string/hello_blank_fragment" />
    
    </FrameLayout>

    效果图:



    展开全文
  • 关于底部导航的开源库由很多,除了前面介绍的Design/BottomNavigationView和BottomBar 底部导航 ,这里在介绍几个,都比较简单。分类NavBar AHBottomNavigation BottomNavigationBar BottomNavigationViewEx ...
  • 关于底部导航的开源库由很多,除了前面介绍的Design/BottomNavigationView和BottomBar 底部导航 ,这里在介绍几个,都比较简单。 分类 NavBar AHBottomNavigation BottomNavigationBar ...
  • 我们活着不能与草木同腐,不能醉生梦死,枉度人生,要有所作为。——方志敏概述我们挑战自我,为用户创造了崭新的视觉设计语言。与此同时,新的设计语言除了遵循经典设计定则,还汲取了...我们先来看看底部导航最终
  • Android创建底部菜单

    2016-11-22 03:29:53
    布局使用RadioGroup和RadioButton配合Fragment <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
  • 本文叙述的是之前版本的qq或微信中,底部的图标加文字的导航的实现。 本例子依赖viewpagerindicator的两个类:IconPagerAdapter及PageIndicator。这两个类的方法如下: package com.viewpagerindicator; public ...
  • 这个底部导航的特点: 1.告别xml中的item布局,一切icon、title统统绘制得出; 2.扁平化,由于icon、title都是绘制得出的,所以只需要一个view即可,无需父布局 3.为你处理好碎片切换事务,告别冗余代码,让你...
  • 本文目录.png 当开始一个新项目的时候,有一个很重要的步骤就是确定我们...现在市面出了少部分的Material Design 风格的除外,大部分都是这样的一个框架,称之为底部导航,分为3-5个Tab不等。前段时间开始了一个
  • 布局 android:id="@+id/bottom_tab_bar" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:hjm="http://schemas
  • 共享一个android项目界面框架,提高开发效率。 主要功能: 1.使用Button自定义底部Tab和Title 2.点击底部Tab后使用Fragment切换页面 3.主页使用ViewPager滚动显示新闻图片 4.自定义类处理Fragment重叠回退问题 注...
  • https://www.cnblogs.com/yelanggu/p/9516429.html 这里我选择用第三个的底部导航
  • android 优秀框架整理

    2018-01-11 11:28:29
    程序员界有个神奇的网站,那就是github,这个网站集合了一大批优秀的开源框架,极大地节省了开发者开发的时间,在这里我进行了一下整理,这样可以使我们在使用到时快速的查找到,希望对大家有所帮助! 1. Retrofit...
  • 现在大多数App都会用到底部导航,比如常见的聊天工具QQ、微信,购物App等等,有了底部导航,用户可以随时切换界面,查看不同的内容。它的实现方式也很多,以前大多使用TabHost来实现,但是现在我们有很多更好的...
  • 下面介绍一下使用Android控件TabHost实现底部导航的方法。TabHost可以在控件库里直接拖到页面上,非常方便,但拖出来的是顶部导航,如下图所示: 到这里就可以开始实现底部导航了,我们首先转到它的XML布局...
1 2 3 4 5 ... 20
收藏数 14,090
精华内容 5,636
关键字:

底部栏android框架