300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Android开发——底部导航栏设计

Android开发——底部导航栏设计

时间:2019-04-12 06:44:10

相关推荐

Android开发——底部导航栏设计

底部导航栏设计

1.依赖配置2.tabbar的UI实现3.tabbar的逻辑绑定4.tabbar的滑动与点击联动5.tabbar与文本输入的冲突解决方案

    其实,常见的Android和微信小程序一样,通常最下面一排需要有一排导航栏,可以通过点击导航栏图标和滑动实现页面跳转,具体实现使用的是Android的ViewPager2

1.依赖配置

    首先需要在build.gradle引入对应的依赖:

implementation 'androidx.viewpager2:viewpager2:1.0.0'

2.tabbar的UI实现

    在MainActivity中引入viewPager2(viewPager的升级版本,现在用的较多)配置:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:id="@+id/activity_main"tools:context=".MainActivity"><androidx.viewpager2.widget.ViewPager2android:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/><!--引入tabbarUI设计,独立出来,方便详细调整--><include layout="@layout/bottom_layout" /></LinearLayout>

    为了方便大家调试,其中的layout/bottom_layout布局代码如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="55dp"android:id="@+id/table_bar"android:gravity="center"android:background="@color/gray"><LinearLayoutandroid:gravity="center"android:id="@+id/tab_launch"android:layout_width="0dp"android:layout_height="match_parent"android:layout_gravity="center"android:layout_weight="1"android:orientation="vertical"tools:ignore="Suspicious0dp"><ImageViewandroid:id="@+id/iv_launch"android:layout_width="32dp"android:layout_height="32dp"android:background="@drawable/tab_launch" /><TextViewandroid:id="@+id/text_launch"android:layout_width="30dp"android:layout_height="30dp"android:gravity="center"android:text="发布" /></LinearLayout><LinearLayoutandroid:gravity="center"android:id="@+id/tab_mine"android:layout_width="0dp"android:layout_height="match_parent"android:layout_gravity="center"android:layout_weight="1"android:orientation="vertical"tools:ignore="Suspicious0dp"><ImageViewandroid:id="@+id/iv_mine"android:layout_width="30dp"android:layout_height="30dp"android:background="@drawable/tab_mine" /><TextViewandroid:id="@+id/text_mine"android:layout_width="32dp"android:layout_height="32dp"android:gravity="center"android:text="我的" /></LinearLayout></LinearLayout>

    这里我使用的tabbar设计如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:id="@+id/table_bar"android:layout_width="match_parent"android:layout_height="55dp"android:background="@color/gray"android:gravity="center"android:orientation="horizontal"><LinearLayoutandroid:id="@+id/tab_home"android:layout_width="0dp"android:layout_height="match_parent"android:layout_gravity="center"android:layout_weight="1"android:gravity="center"android:orientation="vertical"tools:ignore="Suspicious0dp"><ImageViewandroid:id="@+id/iv_home"android:layout_width="32dp"android:layout_height="32dp"android:background="@drawable/tab_home" /><TextViewandroid:id="@+id/text_home"android:layout_width="32dp"android:layout_height="32dp"android:gravity="center"android:text="首页" /></LinearLayout><LinearLayoutandroid:id="@+id/tab_focus"android:layout_width="0dp"android:layout_height="match_parent"android:layout_gravity="center"android:layout_weight="1"android:gravity="center"android:orientation="vertical"tools:ignore="Suspicious0dp"><ImageViewandroid:id="@+id/iv_focus"android:layout_width="32dp"android:layout_height="32dp"android:background="@drawable/tab_focus" /><TextViewandroid:id="@+id/text_focus"android:layout_width="32dp"android:layout_height="match_parent"android:gravity="center"android:text="关注" /></LinearLayout><LinearLayoutandroid:id="@+id/tab_subscribe"android:layout_width="0dp"android:layout_height="match_parent"android:layout_gravity="center"android:layout_weight="1"android:gravity="center"android:orientation="vertical"tools:ignore="Suspicious0dp"><ImageViewandroid:id="@+id/iv_subscribe"android:layout_width="32dp"android:layout_height="32dp"android:background="@drawable/tab_subscribe" /><TextViewandroid:id="@+id/text_subscribe"android:layout_width="32dp"android:layout_height="32dp"android:gravity="center"android:text="订阅" /></LinearLayout></LinearLayout>

    设计解释:其实就是使用了如下三个相同的代码块:

<LinearLayoutandroid:id="@+id/tab_home"android:layout_width="0dp"android:layout_height="match_parent"android:layout_gravity="center"android:layout_weight="1"android:gravity="center"android:orientation="vertical"tools:ignore="Suspicious0dp"><ImageViewandroid:id="@+id/iv_home"android:layout_width="32dp"android:layout_height="32dp"android:background="@drawable/tab_home" /><TextViewandroid:id="@+id/text_home"android:layout_width="32dp"android:layout_height="32dp"android:gravity="center"android:text="首页" /></LinearLayout>

    图标加上导航页的名字,使用android:layout_weight="1",类似于前端的flex=1,其实就是为了把底部导航栏分成多个等分,android:layout_gravity="center",类似于前端的justify-content:center使得各个导航栏中的内容居中。

    补充关于按钮的点亮和未点亮状态设计,在Android的可选按钮中设计selector资源:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="/apk/res/android"><item android:drawable="@drawable/home_default" android:state_selected="false"/><item android:drawable="@drawable/home_active" android:state_selected="true"/></selector>

3.tabbar的逻辑绑定

    有了UI还需要实现逻辑上的绑定,可以在MainActivity里面设计一个初始化函数:

//viewPager相关的代码比较固定,可以直接搬运,然后自己初始化对应的Fragment页面实现定制化public void initPager() {viewPager = findViewById(R.id.viewPager);ArrayList<Fragment> fragments = new ArrayList<>();//添加Fragment页面fragments.add(new FragmentHome());fragments.add(new FragmentFocus());fragments.add(new FragmentSubscribe());FragmentPagerAdapter PagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager(), getLifecycle(), fragments);viewPager.setAdapter(PagerAdapter);viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);changeTab(position);//监听用户滑动,这里面的changeTab是自定义函数为了将滑动和点击tabbar的视觉效果统一}@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {super.onPageScrolled(position, positionOffset, positionOffsetPixels);}@Overridepublic void onPageScrollStateChanged(int state) {super.onPageScrollStateChanged(state);}});}

    下面详细说一下Fragment的实现,直接继承Android自带的FragmentList,详细原理可以参考菜鸟教程关于fragment的介绍:

public class FragmentFocus extends ListFragment {//根据提示重写里面的方法,其实类似于一个Activity,只是通过FragmentPagerAdapter捆绑在一起}

4.tabbar的滑动与点击联动

    设计思路入下:

标记当前正在访问的页面,当修改了页面就将当前正在访问的页面设置成false,然后修改正在访问的页面标记为跳转目标页面,主要是为了实现tabbar的点亮和关闭:

public void initTabView() {//tab_home 是为了获取整个图标和文字部分iv_home 获取的是图标,目的是将图标设计成点亮态和未访问态。tab_home = findViewById(R.id.tab_home);tab_focus = findViewById(R.id.tab_focus);tab_subscribe = findViewById(R.id.tab_subscribe);//前面提到过,setOnClickListener是由于MainActivity实现了点击接口,便于统一管理点击事件tab_home.setOnClickListener(this);tab_focus.setOnClickListener(this);tab_subscribe.setOnClickListener(this);iv_home = findViewById(R.id.iv_home);iv_focus = findViewById(R.id.iv_focus);iv_subscribe = findViewById(R.id.iv_subscribe);iv_home.setOnClickListener(this);iv_focus.setOnClickListener(this);iv_subscribe.setOnClickListener(this);iv_home.setSelected(true);iv_current = iv_home;}@Override//点击切换public void onClick(View view) {switch (view.getId()) {case R.id.tab_home:viewPager.setCurrentItem(0);break;case R.id.tab_focus:viewPager.setCurrentItem(1);break;case R.id.tab_subscribe:viewPager.setCurrentItem(2);break;}}

    这样是不够的,还需要绑定用户对页面的滑动:

private void changeTab(int position) {iv_current.setSelected(false);switch (position) {case 0:iv_home.setSelected(true);iv_current = iv_home;break;case 1:iv_focus.setSelected(true);iv_current = iv_focus;break;case 2:iv_subscribe.setSelected(true);iv_current = iv_subscribe;break;}}

然后,将changeTab函数放在registerOnPageChangeCallback相关的函数里面即可。

5.tabbar与文本输入的冲突解决方案

    由于这里使用的是match_parent布局,所以遇到文本框输入页面的高度缩小,底部导航栏会被吸附上去,而且跳转还是能够相应的,用户输入内容的时候难免可能误碰tabbar,因此很有必要解决一下,下面给出一种方案——全局监听输入法是否打开

    给出大佬封装的键盘监听类:

public class SoftKeyboardStateHelper implements ViewTreeObserver.OnGlobalLayoutListener {public interface SoftKeyboardStateListener {void onSoftKeyboardOpened(int keyboardHeightInPx);void onSoftKeyboardClosed();}private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();private final View activityRootView;private int lastSoftKeyboardHeightInPx;private boolean isSoftKeyboardOpened=false;public SoftKeyboardStateHelper(View activityRootView) {this(activityRootView, false);}public SoftKeyboardStateHelper(View activityRootView, boolean isSoftKeyboardOpened) {this.activityRootView= activityRootView;this.isSoftKeyboardOpened = isSoftKeyboardOpened;activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);}@Overridepublic void onGlobalLayout() {final Rect r = new Rect();//r will be populated with the coordinates of your view that area still visible.activityRootView.getWindowVisibleDisplayFrame(r);final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);if (!isSoftKeyboardOpened && heightDiff > 600) {isSoftKeyboardOpened = true;notifyOnSoftKeyboardOpened(heightDiff);} else if (isSoftKeyboardOpened && heightDiff < 600) {isSoftKeyboardOpened = false;notifyOnSoftKeyboardClosed();}}public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {this.isSoftKeyboardOpened = isSoftKeyboardOpened;}public boolean isSoftKeyboardOpened() {return isSoftKeyboardOpened;}/** * Default value is zero (0) * @return last saved keyboard height in px */public int getLastSoftKeyboardHeightInPx() {return lastSoftKeyboardHeightInPx;}public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {listeners.add(listener);}public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {listeners.remove(listener);}private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;for (SoftKeyboardStateListener listener : listeners) {if (listener != null) {listener.onSoftKeyboardOpened(keyboardHeightInPx);}}}private void notifyOnSoftKeyboardClosed() {for (SoftKeyboardStateListener listener : listeners) {if (listener != null) {listener.onSoftKeyboardClosed();}}}}

    具体的调用方法如下:

public void initTabbarListener() {final SoftKeyboardStateHelper softKeyboardStateHelper = new SoftKeyboardStateHelper(findViewById(R.id.activity_main));softKeyboardStateHelper.addSoftKeyboardStateListener(new SoftKeyboardStateHelper.SoftKeyboardStateListener() {@Overridepublic void onSoftKeyboardOpened(int keyboardHeightInPx) {//键盘打开//Log.d("nightowl", "键盘打开");//将tabbar设置成不可见findViewById(R.id.table_bar).setVisibility(View.INVISIBLE);}@Overridepublic void onSoftKeyboardClosed() {//键盘关闭// Log.d("nightowl", "键盘关闭");findViewById(R.id.table_bar).setVisibility(View.VISIBLE);}});}

    好啦!关于Android tabbar部分的分享就到这里。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。