1. ホーム
  2. Android

Androidのボトムナビゲーションバー、3つのスタイルとインプリメンテーション

2022-02-17 15:55:35

1つは、エフェクトが表示されます。


    動画が動かない場合は、以下の静止画もご覧ください。


    以下は、1つ1つの実装を分析し、ここでは効果の簡単なデモだけで、あなたは現在のコードに基づいて、二次開発を行うことができます。


II. BottomNavigationView

    これはGoogleが提供するボトムナビゲーション用の特別なViewで、新しいActivityを作成するときに "ボトムナビゲーションアクティビティ" を選択するだけで、IDEは自動的にBottomNavigationViewを使用してコードを生成してくれます。

1. xmlの中で

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="0dp"
        android:layout_marginStart="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/navigation" />

    ここで注目すべきはapp:menu属性で、ナビゲーション・バーがページ・メニューをどのように表示するかを指定することです。

2. メニューのレイアウトファイル

<?xml version="1.0" encoding="utf-8"? >
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home" />

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_dashboard" />

    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications" />

</menu>

3. アクティビティで呼び出される

    private TextView mTextMessage;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    mTextMessage.setText(R.string.title_home);
                    return true;
                case R.id.navigation_dashboard:
                    mTextMessage.setText(R.string.title_dashboard);
                    return true;
                case R.id.navigation_notifications:
                    mTextMessage.setText(R.string.title_notifications);
                    return true;
            }
            return false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_style1);

        mTextMessage = findViewById(R.id.message);
        BottomNavigationView navigation = findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

    ここのデモコードはIDEが自動生成したもので、まだ実際にBottomNavigationViewをプロジェクトで使っていないので、ここではあまり分析しませんが、使い方は難しくなく、上記のコードで十分基本的な使用条件は満たしています。


III. ラジオグループ+ビューページャー

    これは、より一般的なもの、ナビゲーションボタンの次の4つのタブは、別のページを切り替えることができます、ここでページは、スライドページの効果を達成するためにViewPager +フラグメントの組み合わせを使用して、あなたもViewPagerを使用しないことができます、これは製品の定義に応じて使用することができます。

1. レイアウトファイル

<?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=".style2.Style2Activity">

    <android.support.v4.view.ViewPager
        android:id="@+id/fragment_vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/tabs_rg" />

    <RadioGroup
        android:id="@+id/tabs_rg"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="#dcdcdc"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/today_tab"
            style="@style/Custom.TabRadioButton"
            android:checked="true"
            android:drawableTop="@drawable/tab_sign_selector"
            android:text="Today" />

        <RadioButton
            android:id="@+id/record_tab"
            style="@style/Custom.TabRadioButton"
            android:drawableTop="@drawable/tab_record_selector"
            android:text="record" />

        <RadioButton
            android:id="@+id/contact_tab"
            style="@style/Custom.TabRadioButton"
            android:drawableTop="@drawable/tab_contact_selector"
            android:text="Contacts" />

        <RadioButton
            android:id="@+id/settings_tab"
            style="@style/Custom.TabRadioButton"
            android:drawableTop="@drawable/tab_setting_selector"
            android:text="setting" />
    </RadioGroup>
</Relat

2. アクティビティクラス

public class Style2Activity extends AppCompatActivity {

    private ViewPager mViewPager;
    private RadioGroup mTabRadioGroup;

    private List<Fragment> mFragments;
    private FragmentPagerAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_style2);
        initView();
    }

    private void initView() {
        // find view
        mViewPager = findViewById(R.id.fragment_vp);
        mTabRadioGroup = findViewById(R.id.tabs_rg);
        // init fragment
        mFragments = new ArrayList<>(4);
        mFragments.add(BlankFragment.newInstance("Today"));
        mFragments.add(BlankFragment.newInstance("Record"));
        mFragments.add(BlankFragment.newInstance("Address Book"));
        mFragments.add(BlankFragment.newInstance("Settings"));
        // init view pager
        mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), mFragments);
        mViewPager.setAdapter(mAdapter);
        // register listener
        mViewPager.addOnPageChangeListener(mPageChangeListener);
        mTabRadioGroup.setOnCheckedChangeListener(mOnCheckedChangeListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mViewPager.removeOnPageChangeListener(mPageChangeListener);
    }

    private ViewPager.OnPageChangeListener mPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            RadioButton radioButton = (RadioButton) mTabRadioGroup.getChildAt(position);
            radioButton.setChecked(true);
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    };

    private RadioGroup.OnCheckedChangeListener mOnCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            for (int i = 0; i < group.getChildCount(); i++) {
                if (group.getChildAt(i).getId() == checkedId) {
                    mViewPager.setCurrentItem(i);
                    return;
                }
            }
        }
    };

    private class MyFragmentPagerAdapter extends FragmentPagerAdapter {

        private List<Fragment> mList;

        public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> list) {
            super(fm);
            this.mList = list;
        }

        @Override
        public Fragment getItem(int position) {
            return this.mList == null ? null : this.mList.get(position);
        }

        @Override
        public int getCount() {
            return this.mList == null ? 0 : this.mList.size();
        }
    }

}

    ここでの唯一の注目点は、下のナビゲーションボタンとページの間の連携を可能にするための2つのリスナーイベントです。


IV. ページジャンプ機能付きボトムナビゲーション

    多くのアプリには、下のナビゲーションバーの真ん中に大きなボタンがあり、クリックすると通常新しいページが開きますが、ここで実装したいのは、このようなボトムナビゲーションです。
RadioGroupを使用していますが、空のViewを使用して中央のタブを占有し、その場所に大きなボタンを配置してカバーしています。

1. レイアウトファイル

<?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=".style3.Style3Activity">

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/tabs_rg" />

    <RadioGroup
        android:id="@+id/tabs_rg"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="#dcdcdc"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/today_tab"
            style="@style/Custom.TabRadioButton"
            android:checked="true"
            android:drawableTop="@drawable/tab_sign_selector"
            android:text="Today" />

        <RadioButton
            android:id="@+id/record_tab"
            style="@style/Custom.TabRadioButton"
            android:drawableTop="@drawable/tab_record_selector"
            android:text="record" />

        <View style="@style/Custom.TabRadioButton" />

        <RadioButton
            android:id="@+id/contact_tab"
            style="@style/Custom.TabRadioButton"
            android:drawableTop="@drawable/tab_contact_selector"
            android:text="Contacts" />

        <RadioButton
            android:id="@+id/settings_tab"
            style="@style/Custom.TabRadioButton"
            android:drawableTop="@drawable/tab_setting_selector"
            android:text="setting" />
    </RadioGroup>

    <ImageView
        android:id="@+id/sign_iv"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@android:color/transparent"
        android:src="@mipmap/sign" />
</RelativeLayout>


2. アクティビティクラス

public class Style3Activity extends AppCompatActivity {

    private RadioGroup mTabRadioGroup;
    private SparseArray<Fragment> mFragmentSparseArray;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_style3);
        initView();
    }

    private void initView() {
        mTabRadioGroup = findViewById(R.id.tabs_rg);
        mFragmentSparseArray = new SparseArray<>();
        mFragmentSparseArray.append(R.id.today_tab, BlankFragment.newInstance("Today"));
        mFragmentSparseArray.append(R.id.record_tab, BlankFragment.newInstance("record"));
        mFragmentSparseArray.append(R.id.contact_tab, BlankFragment.newInstance("Address Book"));
        mFragmentSparseArray.append(R.id.settings_tab, BlankFragment.newInstance("settings"));
        mTabRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // The specific fragment switching logic can be adapted to the application, e.g. using show()/hide()
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        mFragmentSparseArray.get(checkedId)).commit();
            }
        });
        // Show the first one by default
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,
                mFragmentSparseArray.get(R.id.today_tab)).commit();
        findViewById(R.id.sign_iv).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Style3Activity.this, SignActivity.class));
            }
        });
    }

}

<スパン 注意事項

    ここでもViewPagerを使ってFragmentを表示したい場合は、ここのRadioGroupの真ん中、つまり両方のlistenイベントにplaceholder Viewがあることに注意し、このViewが複数あることを考慮して、連携を実装するようにしてください。


コードのアドレスです。 https://gitee.com/afei_/BottomTabbar