底部导航栏中间凸起的菜单键实现

这篇博客介绍了如何在Android应用中实现底部导航栏中间菜单键凸起的效果。通过使用不同的drawable选择器和Fragment管理,详细展示了代码实现过程,包括BaseActivity和多个Fragment的创建。文章还提到了考虑性能问题,初始化时仅加载前两个Fragment的数据。最后,作者提醒读者不同设备可能需要调整布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看图:
这里写图片描述

下面看代码代码组成部分Activity+Fragment的实现方式,考虑到可能加载数据过多导致第一次比较卡的情况,代码实现以默认初始化加载前两个Fragment的数据,以后逐次添加。

首先创建简单框架,这样能培养OOP(面向对象编程)的思维过程,为了长远打算这都是值得的。
创建基类BaseActivity 继承FragmentActivity

public class BaseActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        TODO 可以在这里初始化一些东西
//  TODO 我的项目里初始化诸如ButterKnife和toolbar之类的东西
    }
//一些子类都有可能用到的方法,等等……
    public void showMessage(String text){
        Toast.makeText(this,text,Toast.LENGTH_SHORT).show();
    }

    protected void showDialog(){

    }
    protected void dismissDialog(){

    }
}

MainActivity 继承BaseActivity

public class MainActivity extends BaseActivity implements View.OnClickListener {

    private List<Fragment> fragments;
    private MovieFragment movieFragment;
    private TvFragment tvFragment;
    private VarietyFragment varietyFragment;
    private CartoonFragment cartoonFragment;
    private List<TextView> views;
    private TextView movie;
    private TextView tv;
    private TextView variety;
    private TextView cartoon;
//    底部中间凸起view
    private ImageView menuIv;
//    当前选中的views的下标
    private int currentIndex = 0;
//    旧的views下标
    private int oldIndex = 0;
    private boolean isMenuSelect = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        if (savedInstanceState == null) {
            initFragments();
            initViews();
        }
    }

    /**
     * 初始化所用到的view;
     */
    private void initViews() {
        movie = (TextView) findViewById(R.id.movie);
        tv = (TextView) findViewById(R.id.tv);
        variety = (TextView) findViewById(R.id.variety);
        cartoon = (TextView) findViewById(R.id.cartoon);

        movie.setOnClickListener(this);
        tv.setOnClickListener(this);
        variety.setOnClickListener(this);
        cartoon.setOnClickListener(this);
//      默认第一个为选中状态
        movie.setSelected(true);

        views = new ArrayList<>();
        views.add(movie);
        views.add(tv);
        views.add(variety);
        views.add(cartoon);
        menuIv = (ImageView) findViewById(R.id.menu_iv);
        //底部中间凸起view点击
        menuIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                view.setSelected(isMenuSelect=(isMenuSelect==true?false:true));
                //父类的show方法
                showMessage("on click menuIv!");
            }
        });
    }

    /**
     * 初始化用到的Fragment
     */
    private void initFragments() {
        movieFragment = new MovieFragment();
        tvFragment = new TvFragment();
        varietyFragment = new VarietyFragment();
        cartoonFragment = new CartoonFragment();

        fragments = new ArrayList<>();
        fragments.add(movieFragment);
        fragments.add(tvFragment);
        fragments.add(varietyFragment);
        fragments.add(cartoonFragment);
//        默认加载前两个Fragment,其中第一个展示,第二个隐藏
        getSupportFragmentManager().beginTransaction()
                .add(R.id.content,movieFragment)
                .add(R.id.content,tvFragment)
                .hide(tvFragment)
                .show(movieFragment)
                .commit();

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.movie:
                currentIndex = 0;
                break;
            case R.id.tv:
                currentIndex = 1;
                break;
            case R.id.variety:
                currentIndex = 2;
                break;
            case R.id.cartoon:
                currentIndex = 3;
                break;
        }
//        规避策略将凸起的view还原
        menuIv.setSelected(false);
        isMenuSelect = false;

        showCurrentFragment(currentIndex);
    }

    /**
     * 展示当前选中的Fragment
     * @param currentIndex
     */
    private void showCurrentFragment(int currentIndex) {
        if (currentIndex != oldIndex){
            views.get(oldIndex).setSelected(false);
            views.get(currentIndex).setSelected(true);
            FragmentTransaction ft = getSupportFragmentManager()
                                    .beginTransaction();
            ft.hide(fragments.get(oldIndex));
            if (!fragments.get(currentIndex).isAdded()){
                ft.add(R.id.content,fragments.get(currentIndex));
            }
            ft.show(fragments.get(currentIndex)).commit();
            oldIndex = currentIndex;
        }
    }
}

main_activity的布局:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.bar.mybar.MainActivity">
    <RelativeLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="48dp"/>
    <ImageView
            android:id="@+id/menu_iv"
            android:layout_width="100dp"
            android:layout_height="66dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:background="@drawable/bg_menu"
            android:src="@drawable/selector_menu"
            android:scaleType="centerInside"/>

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:weightSum="2"
       android:orientation="horizontal"
       android:layout_alignParentBottom="true"
       android:background="@drawable/bg_bottom"
       android:paddingTop="2dp"
       android:paddingBottom="2dp"
       android:layout_toLeftOf="@id/menu_iv">
       <TextView
           android:id="@+id/movie"
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_weight="1"
           android:drawablePadding="2dp"
           android:drawableTop="@drawable/selector_movie"
           android:text="电影"
           android:textColor="@android:color/white"
           android:selectAllOnFocus="true"
           android:gravity="center"
           android:textSize="12dp"/>
       <TextView
           android:id="@+id/tv"
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_weight="1"
           android:drawablePadding="2dp"
           android:drawableTop="@drawable/selector_tv"
           android:text="电视剧"
           android:textColor="@android:color/white"
           android:gravity="center"
           android:textSize="12dp"/>

   </LinearLayout>

    <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:weightSum="2"
       android:orientation="horizontal"
       android:layout_alignParentBottom="true"
       android:background="@drawable/bg_bottom"
       android:layout_toRightOf="@id/menu_iv"
       android:paddingTop="2dp"
       android:paddingBottom="2dp">

       <TextView
           android:id="@+id/variety"
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_weight="1"
           android:drawablePadding="2dp"
           android:drawableTop="@drawable/selector_variety"
           android:text="综艺"
           android:textColor="@android:color/white"
           android:gravity="center"
           android:textSize="12dp"/>
       <TextView
           android:id="@+id/cartoon"
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_weight="1"
           android:drawablePadding="2dp"
           android:drawableTop="@drawable/selector_cartoon"
           android:text="动漫"
           android:textColor="@android:color/white"
           android:gravity="center"
           android:textSize="12dp"/>
   </LinearLayout>
</RelativeLayout>

其中电影view用到的drawable为selector_movie.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true" android:drawable="@android:drawable/ic_menu_crop"></item>
    <item android:drawable="@android:drawable/ic_menu_edit"></item>
</selector>

其中电视剧view用到的drawable为selector_tv.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true" android:drawable="@android:drawable/ic_media_pause"></item>
    <item android:drawable="@android:drawable/ic_media_play"></item>
</selector>

其中综艺view用到的drawable为selector_variety.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true" android:drawable="@android:drawable/ic_media_previous"></item>
    <item android:drawable="@android:drawable/ic_media_next"></item>
</selector>

其中动漫view用到的drawable为selector_cartoon.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true" android:drawable="@android:drawable/ic_menu_close_clear_cancel"></item>
    <item android:drawable="@android:drawable/ic_menu_compass"></item>
</selector>

创建MovieFragment继承v4包下的Fragment,如果有需要你也可以创建基类Fragment处理一些事情

public class MovieFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//  每个Fragment里都只有一个简单的view用于演示界面
        TextView textView = new TextView(container.getContext());
        textView.setText("movie");
        return textView;
    }
}

创建TvFragment、VarietyFragment、CartoonFragment与MovieFragment一样的代码
总结:通过这一篇可以简单了解Fragment的使用,以及界面中底部bar的中间凸起实现方式

其中demo使用的是mi3c测试,其他机子布局可能有所不同

android底部bar中间凸起的实现 DEMO:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值