【问题标题】:Navigate to fragment with MaterialDrawer使用 MaterialDrawer 导航到片段
【发布时间】:2017-12-15 01:30:00
【问题描述】:

我创建了一个新的 Android Studio 项目,并基于 (Mike Penz) 的 Github 项目实现了一个导航抽屉

到目前为止一切都很好,但我唯一的问题是片段之间的导航不起作用。

我希望抽屉中的每个项目都打开一个单独的片段。

这是我的 MainActivity.java

package com.senseidev.isensei.activities;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem;
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import com.senseidev.isensei.R;
import com.senseidev.isensei.fragments.HomeFragment;
import com.senseidev.isensei.fragments.PhotosFragment;
import com.senseidev.isensei.fragments.ProductsFragment;
import com.senseidev.isensei.fragments.ProfileFragment;
import com.senseidev.isensei.fragments.ServicesFragment;

public class MainActivity extends AppCompatActivity {

    private static final int PROFILE_SETTING = 1;
    private Toolbar mainToolbar;
    private AccountHeader headerResult = null;
    private Drawer result = null;

    private IProfile profile_1;
    private IProfile profile_2;

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

        mainToolbar = (Toolbar) findViewById(R.id.main_toolbar);
        setSupportActionBar(mainToolbar);
        getSupportActionBar().setTitle(R.string.app_name);

        profile_1 = new ProfileDrawerItem().withName("Dev").withEmail("developer@gmail.com").withIcon(getResources().getDrawable(R.drawable.ip_user_bi_photo));
        profile_2 = new ProfileDrawerItem().withName("Isen").withEmail("isen@gmail.com").withIcon(getResources().getDrawable(R.drawable.ip_user_bi_photo));

        // Create the AccountHeader
        buildHeader(false, savedInstanceState);

        //create the drawer and remember the `Drawer` result object
        result = new DrawerBuilder()
                .withActivity(this)
                .withAccountHeader(headerResult)
                .withToolbar(mainToolbar)
                .addDrawerItems(
                        new SecondaryDrawerItem().withName(R.string.drawer_profile)
                                .withSelectedIconColor(ContextCompat.getColor(this, R.color.app_belize)).withIconTintingEnabled(true)
                                .withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_account_box).actionBar().colorRes(R.color.material_drawer_dark_primary_text))
                                .withTag("Bullhorn"),

                        new SecondaryDrawerItem().withName(R.string.drawer_services)
                                .withSelectedIconColor(ContextCompat.getColor(this, R.color.app_belize)).withIconTintingEnabled(true)
                                .withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_device_hub).actionBar().colorRes(R.color.material_drawer_dark_primary_text))
                                .withTag("Bullhorn"),

                        new SecondaryDrawerItem().withName(R.string.drawer_products)
                                .withSelectedIconColor(ContextCompat.getColor(this, R.color.app_belize)).withIconTintingEnabled(true)
                                .withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_shopping_cart).actionBar().colorRes(R.color.material_drawer_dark_primary_text))
                                .withTag("Bullhorn"),

                        new SecondaryDrawerItem().withName(R.string.drawer_images)
                                .withSelectedIconColor(ContextCompat.getColor(this, R.color.app_belize)).withIconTintingEnabled(true)
                                .withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_camera_roll).actionBar().colorRes(R.color.material_drawer_dark_primary_text))
                                .withTag("Bullhorn")



                )
                .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
                    @Override
                    public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
                        // do something with the clicked item :D

                        selectDrawerItem((int) drawerItem.getIdentifier(), drawerItem);

                        return true;
                    }
                })
                .addStickyDrawerItems(
                        new SecondaryDrawerItem().withName(R.string.drawer_all_right_reserved).withIcon(FontAwesome.Icon.faw_copyright).withEnabled(false)
                ).build();

    }


    /**
     * small helper method to reuse the logic to build the AccountHeader
     * this will be used to replace the header of the drawer with a compact/normal header
     *
     * @param compact
     * @param savedInstanceState
     */
    private void buildHeader(boolean compact, Bundle savedInstanceState) {
        headerResult = new AccountHeaderBuilder()
                .withActivity(this)
                .withHeaderBackground(R.drawable.ip_menu_header_bg)
                .withCompactStyle(compact)
                .addProfiles(
                        profile_1,
                        profile_2,

                        new ProfileSettingDrawerItem()
                                .withName("Add Account")
                                .withDescription("Add new GitHub Account")
                                .withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_add)
                                        .actionBar().paddingDp(5).colorRes(R.color.material_drawer_dark_primary_text)).withIdentifier(PROFILE_SETTING),
                        new ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings)
                )
                .withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
                    @Override
                    public boolean onProfileChanged(View view, IProfile profile, boolean current) {
                        //sample usage of the onProfileChanged listener
                        //if the clicked item has the identifier 1 add a new profile ;)
                        if (profile instanceof IDrawerItem && ((IDrawerItem) profile).getIdentifier() == PROFILE_SETTING) {
                            IProfile newProfile = new ProfileDrawerItem()
                                    .withNameShown(true)
                                    .withName("Kensei")
                                    .withEmail("kensei@gmail.com")
                                    .withIcon(getResources().getDrawable(R.drawable.ip_user_bi_photo));
                            if (headerResult.getProfiles() != null) {
                                //we know that there are 2 setting elements. set the new profile above them ;)
                                headerResult.addProfile(newProfile, headerResult.getProfiles().size() - 2);
                            } else {
                                headerResult.addProfiles(newProfile);
                            }
                        }

                        //false if you have not consumed the event and it should close the drawer
                        return false;
                    }
                })
                .build();
    }

    public void selectDrawerItem(int ItemId, IDrawerItem drawerItem) {
        // Create a new fragment and specify the fragment to show based on nav item clicked
        Fragment fragment = null;
        Class fragmentClass;
        switch (ItemId) {

            case 1:
                fragmentClass = ProfileFragment.class;
                break;

            case 2:
                fragmentClass = ServicesFragment.class;
                break;

            case 3:
                fragmentClass = ProductsFragment.class;
                break;

            case 4:
                fragmentClass = PhotosFragment.class;
                break;

            default:
                fragmentClass = HomeFragment.class;
        }
        try {
            fragment = (Fragment) fragmentClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // Insert the fragment by replacing any existing fragment
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
        result.closeDrawer();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {

            default:
                return super.onOptionsItemSelected(item);
        }

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        //add the values which need to be saved from the drawer to the bundle
        outState = result.saveInstanceState(outState);
        //add the values which need to be saved from the accountHeader to the bundle
        outState = headerResult.saveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onBackPressed() {
        //handle the back press :D close the drawer first and if the drawer is closed close the activity
        if (result != null && result.isDrawerOpen()) {
            result.closeDrawer();
        } else {
            super.onBackPressed();
        }
    }

}

这是我的 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.senseidev.isensei.activities.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/main_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?android:attr/actionBarSize"
        android:background="@color/colorPrimary">

    </android.support.v7.widget.Toolbar>

    <FrameLayout
        android:id="@+id/flContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

</RelativeLayout>

这是我的 HomeFragment.java

package com.project.app.fragments;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.project.app.R;

/**
 * A simple {@link Fragment} subclass.
 */
public class HomeFragment extends Fragment {


    public HomeFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

       View view = inflater.inflate(R.layout.fragment_home, container, false);
       return view;
    }

}

这是我的 fragment_home.xml

<FrameLayout 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.senseidev.isensei.fragments.HomeFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:text="HOME" />

</FrameLayout>

【问题讨论】:

    标签: java android xml mobile navigation


    【解决方案1】:

    您的 XLM 活动布局首先应该有一个框架布局槽,用于添加和替换片段。

    添加这个新方法,该方法将负责根据从抽屉中选择的项目 ID 创建片段并将其添加到活动中:

    public void selectDrawerItem(int ItemId,IDrawerItem drawerItem) {
        // Create a new fragment and specify the fragment to show based on nav item clicked
        Fragment fragment = null;
        Class fragmentClass;
        switch(ItemId) {
            case 1:
                fragmentClass = PageFragment2.class;
                break;
            case 2:
                fragmentClass = PageFragment2.class;
                break;
             default:
                fragmentClass = PageFragment2.class;
        }
        try {
            fragment = (Fragment) fragmentClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // Insert the fragment by replacing any existing fragment
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
        result.closeDrawer();
    } 
    

    像这样从 withOnDrawerItemClickListener 调用这个方法:

             .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
                    @Override
                    public boolean onItemClick(View view, int position, IDrawerItem drawerItem)
                    {
                        // do something with the clicked item :D
    
                        selectDrawerItem((int)drawerItem.getIdentifier(), drawerItem);
                        return true;
                    }
                })
    

    这可能不会模拟需求,但会为您提供逻辑,祝您好运。

    添加 .withIdentifier()

    .addDrawerItems(
                        new SecondaryDrawerItem().withName(R.string.drawer_profile)
                                .withIdentifier(1)
                                .withSelectedIconColor(ContextCompat.getColor(this, R.color.app_belize)).withIconTintingEnabled(true)
                                .withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_account_box).actionBar().colorRes(R.color.material_drawer_dark_primary_text))
                                .withTag("Bullhorn"),
    

    【讨论】:

    • 感谢您的帮助 - 但是我仍然需要一些帮助我已经在 (activity_main.xml) 中添加了 Framelayout 但仍然存在问题,因为它没有切换片段我已经更新了上面的代码
    • 你怎么知道片段没有显示?这可能并不明显,除非每个片段都包含不同的内容,例如不同的背景颜色或您添加的 textview 显示不同的文本,它始终显示 HOME。尝试为 textview 设置不同的背景颜色并显示不同的文本,看看会发生什么。
    • 每个片段都有自己的 layout.xml(每个片段都有自己的 TextView 和不同的 TEXT) - 但就像你说的,它总是显示只是“家”一定有问题,但我不能弄清楚是什么
    • 在我看来 switch 语句没有传递项目标识符并且总是到达默认部分。为您配置的每个项目添加一个标识符,就像我添加到我的答案中的示例一样,相信这将解决问题并且片段将替换。不用说标识符在项目之间应该是唯一的,并且在 switch 语句中应该是相同的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    相关资源
    最近更新 更多