自定义导航栏 Android - 四分之一屏幕高度和透明背景

Custom Navigation Bar Android - Quarter Screen Height and Transparent Background

我想知道如何处理ui这种类型的 ui。我的应用程序中有一个底部导航栏,当单击添加按钮时,我想显示如下所示的弧形菜单,同时在屏幕高度的其余部分保持先前膨胀的视图。

图片示例:

我已经使用片段来实现底部导航的默认方式,但我该如何调整它以使其看起来像这样。 BottomNavigationView 小部件不支持视图的部分呈现。是否有支持此功能的库或自定义方法来执行此操作?谢谢

编辑: 这是我当前使用片段事务、片段和默认底部导航小部件的实现:

public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {

private static final String TAG = MainActivity.class.getSimpleName();

private Toolbar toolbar;
private BottomNavigationView bottomNav;

private Fragment fragment;
private FragmentTransaction transaction;

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

    init();

}

private void switchFragment(Fragment fragment) {
    transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.fragHolder, fragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

private void init() {
    bottomNav = findViewById(R.id.bottomNav);
    toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    fragment = new HomeFragment();
    switchFragment(fragment);

    bottomNav.setOnNavigationItemSelectedListener(this);

}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.ACTION_DOWN) {
        super.onKeyDown(keyCode, event);
        return true;
    }
    return false;

}

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
    switch (menuItem.getItemId()){
        case R.id.nav_home:
            fragment = new HomeFragment();
            switchFragment(fragment);
            return true;
        case R.id.nav_notifications:
            fragment = new AlertsFragment();
            switchFragment(fragment);
            return true;
        case R.id.nav_add:
            //fragment = new AddFragment();
            //switchFragment(fragment);
            //return true;
            This is where I want to load the curved menu/dialog and ideally the previous screen from Activity Stack or Fragment BackStack will be visible on top and this screen only takes up 20-25% of screen height
        case R.id.nav_messages:
            fragment = new MessagesFragment();
            switchFragment(fragment);
            return true;
        case R.id.nav_profile:
            fragment = new ProfileFragment();
            switchFragment(fragment);
            return true;
    }
    return false;
}
}

这不是一个完整的示例,但希望它能让您了解您可以做什么。

这使用自定义 BottomSheetDialog,使用对话框的好处是可以使用后退按钮或在视图外单击轻松关闭它。

TestDialog.java

public class TestDialog extends BottomSheetDialog
{
    private Context _context;

    public TestDialog(Context context)
    {
        super(context);
        this._context = context;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        Window window = getWindow();
        if (window != null)
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        setContentView(R.layout.test_layout);
    }
}

R.layout.test_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/transparent">

    <View
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:background="@drawable/curve"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="14dp"
        android:background="@color/white"
        android:baselineAligned="false">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical">

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                app:srcCompat="@drawable/ic_person_black_24dp"
                android:layout_gravity="center_horizontal"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:text="New Session"
                android:textColor="@color/black"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical">

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                app:srcCompat="@drawable/ic_person_black_24dp"
                android:layout_gravity="center_horizontal"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:text="Enroll Player"
                android:textColor="@color/black"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical">

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                app:srcCompat="@drawable/ic_person_black_24dp"
                android:layout_gravity="center_horizontal"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:text="New Batch"
                android:textColor="@color/black"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

@drawable/curve

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle"/>
    </item>
    <item
        android:bottom="-80dp"
        android:left="-100dp"
        android:right="-100dp"
        android:top="0dp">
        <shape android:shape="oval">
            <solid android:color="@color/white" />
        </shape>
    </item>
</layer-list>

显示对话框

TestDialog dialog = new TestDialog(MainActivity.this);
tdialog.show();

//This is done in order to make dialog width match the screen width
Window window = dialog.getWindow();
window.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

现在做什么

如果您决定走这条路,现在还有两件事需要实施。首先是确保对话框 window 本身没有背景,现在它不是完全透明的,第二件事是确保它不会覆盖你的 BottomNavigationView

如何在您的案例中显示对话框的示例

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
    switch (menuItem.getItemId()){
        case R.id.nav_home:
            fragment = new HomeFragment();
            switchFragment(fragment);
            return true;
        case R.id.nav_notifications:
            fragment = new AlertsFragment();
            switchFragment(fragment);
            return true;
        case R.id.nav_add:
            //Show the dialog
            TestDialog dialog = new TestDialog(MainActivity.this);
            tdialog.show();

            //This is done in order to make dialog width match the screen width
            Window window = dialog.getWindow();
            window.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        case R.id.nav_messages:
            fragment = new MessagesFragment();
            switchFragment(fragment);
            return true;
        case R.id.nav_profile:
            fragment = new ProfileFragment();
            switchFragment(fragment);
            return true;
    }
    return false;
}