导航抽屉从右到左?

Posted

技术标签:

【中文标题】导航抽屉从右到左?【英文标题】:Navigation Drawer from right to left? 【发布时间】:2018-06-08 15:20:06 【问题描述】:

我正在使用 android studio 3.1,我想更改抽屉,使其从右侧显示。我尝试了android:layout_gravity="end",当我从 rtl 滑动时效果很好,但是当我点击左侧的菜单按钮时,我仍然有一个问题,应用程序停止了

我想我必须把它改到右边,但我不知道怎么做

MainActivity.java:

public class MainActivity extends AppCompatActivity 
private final String TAG = MainActivity.class.getSimpleName();
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

//Defining Variables
private Toolbar toolbar;
private NavigationView navigationView;
private DrawerLayout drawerLayout;
private int previousDrawerItemChecked;
private SearchView searchView;

private BroadcastReceiver mRegistrationBroadcastReceiver;
//private ProgressBar mRegistrationProgressBar;
//private TextView mInformationTextView;
private boolean isReceiverRegistered;


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

    // Initializing Toolbar and setting it as the actionbar
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    //Initializing NavigationView
    navigationView = (NavigationView) findViewById(R.id.navigation_view);

    //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() 

        // This method will trigger on item Click of navigation menu
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) 


            //Checking if the item is in checked state or not, if not make it in checked state
            if(menuItem.isChecked()) menuItem.setChecked(false);
            else menuItem.setChecked(true);

            //Closing drawer on item click
            drawerLayout.closeDrawers();

            //Check to see which item was being clicked and perform appropriate action
            switch (menuItem.getItemId())
                //Replacing the main content with ContentFragment Which is our Inbox View;
                case R.id.recently_added:
                    sub_recently_added();
                    previousDrawerItemChecked = 0;
                    return true;
                case R.id.categories:
                    sub_labels_results();
                    previousDrawerItemChecked = 1;
                    return true;
                case R.id.popular:
                    sub_label_results(Const.BLOGGER_FEATURED_CATEGORY);
                    previousDrawerItemChecked = 2;
                    return true;
                case R.id.about:
                    sub_about_fragment();
                    previousDrawerItemChecked = 3;
                    return true;
                case R.id.rate_app:
                    Uri uri = Uri.parse("market://details?id=" + getApplicationContext().getPackageName());
                    Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
                    // To count with Play market backstack, After pressing back button,
                    // to taken back to our application, we need to add following flags to intent.
                    goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY |
                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
                            Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
                    try 
                        startActivity(goToMarket);
                     catch (ActivityNotFoundException e) 
                        startActivity(new Intent(Intent.ACTION_VIEW,
                                Uri.parse("http://play.google.com/store/apps/details?id=" + getApplicationContext().getPackageName())));
                    
                    return true;
                default:
                    Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
                    return true;

            
        
    );

    // Initializing Drawer Layout and ActionBarToggle
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
    ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.openDrawer, R.string.closeDrawer)

        @Override
        public void onDrawerClosed(View drawerView) 
            // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
            super.onDrawerClosed(drawerView);
        

        @Override
        public void onDrawerOpened(View drawerView) 
            // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank

            super.onDrawerOpened(drawerView);
        
    ;

    //Setting the actionbarToggle to drawer layout
    drawerLayout.setDrawerListener(actionBarDrawerToggle);

    //calling sync state is necessay or else your hamburger icon wont show up
    actionBarDrawerToggle.syncState();


    if (savedInstanceState == null) 
        sub_recently_added();
        previousDrawerItemChecked = 0;
    

    if (AppController.getInstance().getPrefManger().getFirstLaunched())
        //Sending Broadcast to LabelsController
        Intent intent = new Intent();
        intent.setAction(Const.PACKAGE_INTENT);
        sendBroadcast(intent);
        AppController.getInstance().getPrefManger().setFirstLaunched(false);
    



@Override
public boolean onCreateOptionsMenu(final Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);

    // Associate searchable configuration with the SearchView
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setQueryHint(getString(R.string.search_hint));
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() 

        @Override
        public boolean onQueryTextChange(String newText) 
            return false;
        

        @Override
        public boolean onQueryTextSubmit(String query) 
            toolbar.setSubtitle("Search Results for: " + query);
            searchView.onActionViewCollapsed();
            searchView.setQuery("", false);
            searchView.clearFocus();
            //menu.findItem(R.id.action_search).collapseActionView();

            sub_search_results(query);
            return true;
        
    );
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    return true;


@Override
public boolean onOptionsItemSelected(MenuItem item) 
    int id = item.getItemId();
    return super.onOptionsItemSelected(item);


@Override
public void onBackPressed()

    FragmentManager fm = getSupportFragmentManager();
    if (fm.getBackStackEntryCount()>0)

        String title = fm.getBackStackEntryAt(fm.getBackStackEntryCount()-1).getName();
        fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() 
            @Override
            public void onBackStackChanged() 
                FragmentManager manager = getSupportFragmentManager();
                if (manager != null) 
                    int backStackEntryCount = manager.getBackStackEntryCount();
                    if (backStackEntryCount == 0) 
                        finish();
                    
                    if ((backStackEntryCount - 1)>=0) 
                        Fragment fragment = manager.getFragments().get(backStackEntryCount - 1);
                        fragment.onResume();
                    
                

            
        );
        fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1);
        int pos = Integer.parseInt(title);
        navigationView.getMenu().getItem(pos).setChecked(true);
        fm.popBackStack();

    else
        getSupportActionBar().setSubtitle(null);
        super.onBackPressed();
    



private void sub_recently_added()
    toolbar.setSubtitle(R.string.menu_recently_added);
    Fragment fragment = RecentFragment.newInstance(0, getString(R.string.menu_recently_added));
    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.frame, fragment);
    fragmentTransaction.addToBackStack("" + previousDrawerItemChecked).commit();


private void sub_search_results(String searchQuery)
    Fragment fragment = SearchFragment.newInstance(searchQuery);
    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.frame, fragment);
    fragmentTransaction.addToBackStack("" + previousDrawerItemChecked).commit();


public void sub_label_results(String label)
    toolbar.setSubtitle("Category: " + label);
    Fragment fragment = LabelsFragment.newInstance(label);
    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.frame, fragment);
    fragmentTransaction.addToBackStack("" + previousDrawerItemChecked).commit();


private void sub_labels_results()
    toolbar.setSubtitle("Categories");
    Fragment fragment = LabelsListFragment.newInstance();
    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.frame, fragment);
    fragmentTransaction.addToBackStack("" + previousDrawerItemChecked).commit();


private void sub_about_fragment()
    toolbar.setSubtitle(R.string.menu_about);
    Fragment fragment = AboutFragment.newInstance();
    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.frame, fragment);
    fragmentTransaction.addToBackStack("" + previousDrawerItemChecked).commit();




@Override
protected void onResume() 
    super.onResume();
    //registerReceiver();


@Override
protected void onPause() 
    //LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
    //isReceiverRegistered = false;
    super.onPause();


private void registerReceiver()
    /*if(!isReceiverRegistered) 
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(Const.GCM_REGISTRATION_COMPLETE));
        isReceiverRegistered = true;
    */

/**
 * Check the device to make sure it has the Google Play Services APK. If
 * it doesn't, display a dialog that allows users to download the APK from
 * the Google Play Store or enable it in the device's system settings.
 */
private boolean checkPlayServices() 
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
    if (resultCode != ConnectionResult.SUCCESS) 
        if (apiAvailability.isUserResolvableError(resultCode)) 
            apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                    .show();
         else 
            Log.i(TAG, "This device is not supported.");
            finish();
        
        return false;
    
    return true;


activity_main.xml:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer"
android:layout_
android:layout_
android:fitsSystemWindows="true"
tools:context=".MainActivity">

<LinearLayout
    android:layout_
    android:layout_
    android:orientation="vertical">
    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar"/>

    <FrameLayout
        android:id="@+id/frame"
        android:layout_
        android:layout_>

    </FrameLayout>
</LinearLayout>

<!--app:itemBackground="@color/primary"-->
<android.support.design.widget.NavigationView
    android:id="@+id/navigation_view"
    android:layout_
    android:layout_
    android:layout_gravity="end"
    app:headerLayout="@layout/drawer_header"
    app:itemIconTint="@drawable/navview_selected"
    app:itemTextColor="@drawable/navview_selected"
    app:menu="@menu/drawer_menu"
    />
</android.support.v4.widget.DrawerLayout>

【问题讨论】:

能否请您添加错误信息? java.lang.IllegalArgumentException: 没有找到重力左侧的抽屉视图 【参考方案1】:

您可能会得到 空指针异常,因为您在将其实例化之前使用了抽屉布局

navigationView.setNavigationItemSelectedListener

这里

drawerLayout.closeDrawers();

解决办法是先初始化drawerlayout

drawerLayout = (DrawerLayout) findViewById(R.id.drawer);

//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() 

        // This method will trigger on item Click of navigation menu
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) 


            //Checking if the item is in checked state or not, if not make it in checked state
            if(menuItem.isChecked()) menuItem.setChecked(false);
            else menuItem.setChecked(true);

            //Closing drawer on item click
            drawerLayout.closeDrawers();

            //Check to see which item was being clicked and perform appropriate action
            switch (menuItem.getItemId())
                //Replacing the main content with ContentFragment Which is our Inbox View;
                case R.id.recently_added:
                    sub_recently_added();
                    previousDrawerItemChecked = 0;
                    return true;
                case R.id.categories:
                    sub_labels_results();
                    previousDrawerItemChecked = 1;
                    return true;
                case R.id.popular:
                    sub_label_results(Const.BLOGGER_FEATURED_CATEGORY);
                    previousDrawerItemChecked = 2;
                    return true;
                case R.id.about:
                    sub_about_fragment();
                    previousDrawerItemChecked = 3;
                    return true;
                case R.id.rate_app:
                    Uri uri = Uri.parse("market://details?id=" + getApplicationContext().getPackageName());
                    Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
                    // To count with Play market backstack, After pressing back button,
                    // to taken back to our application, we need to add following flags to intent.
                    goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY |
                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
                            Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
                    try 
                        startActivity(goToMarket);
                     catch (ActivityNotFoundException e) 
                        startActivity(new Intent(Intent.ACTION_VIEW,
                                Uri.parse("http://play.google.com/store/apps/details?id=" + getApplicationContext().getPackageName())));
                    
                    return true;
                default:
                    Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
                    return true;

            
        
    );

【讨论】:

以上是关于导航抽屉从右到左?的主要内容,如果未能解决你的问题,请参考以下文章

react native - 改变导航方向(即从右到左)

从右到左滑动抽屉菜单

Xcode Segue View Controller 从右到左没有 UINavigation

如何从右到左设计android.support.design.widget.NavigationView?

在Xamarin android中从右向左滑动抽屉

反转 SWIFT 中导航控制器的默认转换 [重复]