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

时间:2018-11-02 07:35:07

标签: android bottomnavigationview

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

图片示例: enter image description here

我已经使用片段来实现默认的底部导航方式,但是如何使它看起来像这样。 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;
}
}

1 个答案:

答案 0 :(得分:1)

这不是一个完整的示例,但希望它可以使您对可以做的事情有所了解。

这使用了自定义的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);

现在该怎么做

如果您决定走这条路,现在还有两件事要做。首先是要确保对话框窗口本身没有背景,现在它还不完全透明,其次是要确保它不覆盖您的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;
}