Cách đặt Ngăn điều hướng được mở từ phải sang trái


83

Trước hết, tôi biết câu hỏi này đã xuất hiện ở đây trước đây nhưng sau khi cố gắng rất nhiều tôi vẫn không thành công. Tôi đang làm việc trên ví dụ từ trang web Nhà phát triển Android .

Tôi đang cố gắng đặt menu được mở từ phải sang trái thay vì cách triển khai của nó trong ví dụ (từ trái sang phải). Ngoài ra, tôi muốn di chuyển nút menu đang mở sang bên phải của thanh tác vụ. Tôi cũng tô đỏ một số câu trả lời ở đây, ví dụ trong câu trả lời này .

Tôi cố gắng thay đổi lực hấp dẫn của các chế độ xem và bố cục nhưng tôi gặp lỗi:

không tìm thấy chế độ xem ngăn kéo với trọng lực tuyệt đối LEFT

Bạn có thể vui lòng giúp tôi tìm ra vấn đề trong mã của tôi là gì và tôi nên thay đổi điều gì để đặt menu được mở từ bên phải và di chuyển nút thanh tác vụ sang bên phải?

mã xml ở đây:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_gravity="right"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/content_frame"
        android:layoutDirection="rtl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <ListView android:id="@+id/left_drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="10dp"
        android:background="#111"/>

</android.support.v4.widget.DrawerLayout>


Hãy xem github.com/Ali-Rezaei/SlidingDrawer giúp bạn có thể trượt từ bất kỳ phía nào bằng một vài dòng mã.
Ali

Vui lòng xem câu trả lời stackoverflow.com/a/44076363/5332645
Aman Saxena

Câu trả lời:


154

Trong bố cục chính của bạn, hãy đặt ListViewtrọng lực của bạn sang phải:

android:layout_gravity="right" 

Cũng trong mã của bạn:

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_drawer, R.string.drawer_open,
            R.string.drawer_close) {

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
                mDrawerLayout.closeDrawer(Gravity.RIGHT);
            } 
            else {
                mDrawerLayout.openDrawer(Gravity.RIGHT);
            }
        }
        return false;
    }
};

hy vọng nó hoạt động :)


2
@Rudi: Bạn có biết câu trả lời của phần thứ hai không? Ý tôi là làm thế nào để làm cho thanh hành động từ phải sang trái. (Ngăn kéo và hướng biểu tượng điều hướng lên cũng thay đổi)
Alireza Farahani

@alireza tại sao bạn không sử dụng thanh tác vụ tùy chỉnh?
Rudi

@Rudi: Ý bạn là setCustomViewphương pháp? Nếu có, bạn có phiền dán một số liên kết hướng dẫn cách làm điều đó không?
Alireza Farahani

@alireza Ý tôi là, thay vì sử dụng thanh tác vụ ở đầu chế độ xem của bạn, hãy tạo Thanh tác vụ tùy chỉnh trong xml chính của bạn và thiết lập nó như bạn muốn.
Rudi

@Rudi: Nhưng sau đó, làm thế nào tôi có thể đạt được hành vi tương tự như điều hướng lên và hoạt ảnh đóng mở ngăn kéo? Tôi có phải thực hiện chúng từ đầu không?
Alireza Farahani

61

Thêm mã này vào tệp kê khai:

<application android:supportsRtl="true">

và sau đó viết mã này trên Oncreate:

getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

Nó làm việc cho tôi. ;)


1
đây là câu trả lời đúng, chỉ cần bộ nghiêm trọng của listview của bạn để bắt đầu, sau đó sử dụng mã này, tất cả mọi thứ nên được tốt
Mahdi Giveie

9
Đó là làm việc, tuy nhiên, setLayoutDirection (View.LAYOUT_DIRECTION_RTL) là dành cho API trên 17, vì vậy bạn không thể sử dụng này cho api thấp
Milad

6
Điều này sẽ không lật toàn bộ bố cục của hoạt động, thậm chí cả toStartOf / toEndOf, v.v.?
TWiStErRob

13
Đây là câu trả lời sai. Nó lật toàn bộ bố cục của hoạt động từ phải sang trái.
Tarun

1
Nghĩ rằng đó là một giải pháp nhanh chóng nhưng không phải là một giải pháp chính xác.
sidhanshu

37

GIẢI PHÁP


your_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="end">

    <include layout="@layout/app_bar_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:itemTextColor="@color/black"
        app:menu="@menu/activity_root_drawer" />

</android.support.v4.widget.DrawerLayout>

YourActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
//...
toolbar = (Toolbar) findViewById(R.id.toolbar);

drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT)) {
                drawer.closeDrawer(Gravity.RIGHT);
            } else {
                drawer.openDrawer(Gravity.RIGHT);
            }
        }
    });
//...
}

2
Hoạt động tuyệt vời. Nhưng biểu tượng thanh công cụ vẫn xuất hiện bên trái. Làm thế nào để đưa biểu tượng nút bật tắt sang bên phải?
Darush

tôi đã cung cấp android: layout_gravity = "end" cho cả Drawerlayout và NavigationView, nó hoạt động tốt.
varotariya vajsi

toolbar.setNavigationOnClickListenerđòi hỏi tối thiểu Api Cấp 21 :(
SepJaPro2.4

@ SepJaPro2.4 vâng, nhưng From August 2018, new apps must target at least Android 8.0 (API level 26). From November 2018, app updates must target Android 8.0 (API level 26).(Google)
Volodymyr Kulyk

2
Thêm android: layoutDirection = "rtl" trong AppBarLayout XML của bạn để thiết lập các nút bật tắt ở bên phải
Terranology

4

Câu trả lời này rất hữu ích để đặt điều hướng được mở từ phải sang trái, nhưng không có giải pháp nào để đặt biểu tượng của nó ở bên phải. Mã này có thể sửa chữa nó. Nếu bạn đặt nó drawerlàm tham số đầu tiên và ViewCompat.LAYOUT_DIRECTION_RTLlàm tham số thứ hai, thì bố cục entier sẽ được đặt thành RTL. Đó là một giải pháp nhanh chóng và đơn giản, nhưng tôi không nghĩ rằng nó có thể là một giải pháp chính xác cho những ai muốn chỉ đặt menu được mở từ phải sang trái và đặt biểu tượng của nó ở bên phải. (Mặc dù, nó phụ thuộc vào mục đích của bạn.) Tuy nhiên, tôi khuyên bạn nên đưa cái toolbarthay vì drawer. Theo cách này, chỉ thanh công cụ đã trở thành RTL. Vì vậy, tôi nghĩ rằng sự kết hợp của 2 câu trả lời này chính xác có thể làm được những gì bạn muốn.

Theo các mô tả này, mã của bạn sẽ như thế này:

(Thêm các dòng này vào phương thức onCreate)

final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); // Set it final to fix the error that will be mention below.

    ViewCompat.setLayoutDirection(toolbar, ViewCompat.LAYOUT_DIRECTION_RTL);

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT))
                drawer.closeDrawer(Gravity.RIGHT);
            else
                drawer.openDrawer(Gravity.RIGHT);
        }
    });

Lưu ý rằng bạn nên đặt ngăn kéo cuối cùng, nếu không bạn sẽ gặp lỗi này:

Biến 'ngăn kéo' được truy cập từ bên trong lớp, cần được khai báo cuối cùng

Và đừng quên sử dụng endthay vì starttrong onNavigationItemSelectedphương thức:

drawer.closeDrawer(GravityCompat.END);

và trong activity_main.xml của bạn

<android.support.v4.widget.DrawerLayout 
   android:id="@+id/drawer_layout"
   tools:openDrawer="end">

   <android.support.design.widget.NavigationView
      android:id="@+id/nav_view"
      android:layout_gravity="end"/>
</android.support.v4.widget.DrawerLayout>

3

Đây là tài liệu về ngăn kéo và có vẻ như bạn có thể định cấu hình nó để kéo ra từ bên trái hoặc bên phải.

Vị trí và bố cục ngăn kéo được kiểm soát bằng cách sử dụng thuộc tính android: layout_gravity trên các chế độ xem con tương ứng với mặt nào của chế độ xem bạn muốn ngăn kéo xuất hiện từ: trái hoặc phải. (Hoặc bắt đầu / kết thúc trên các phiên bản nền tảng hỗ trợ hướng bố cục.)

http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html


Tôi đã xem câu trả lời này trước đây và tôi cũng đã đề cập đến nó trong câu hỏi của mình.
galvan,

Được chứ. Hãy thử sử dụng endthay vì righttrong trọng lực. CHỈNH SỬA: Xóa android:layout_gravity="right"khỏi android.support...DrawerLayoutvà thay đổi android:layout_gravity="right"vào android:layout_gravity="end"bên trongListView
KickAss,

1
tôi vẫn gặp lỗi: không tìm thấy chế độ xem ngăn kéo nào với trọng lực tuyệt đối LEFT. Tôi đã thêm vào tệp kê khai android: supportsRtl = "true" và trong xml dưới ngăn kéoLayout, tôi đã thêm android: layoutDirection = "rtl" và sau đó menu mở ra ở bên phải, nhưng bây giờ nó không đóng khi tôi nhấp vào nút menu (trong thanh tác vụ) khi tôi nhấp vào bất kỳ mục nào trong danh sách hoặc ở bên ngoài danh sách, nó sẽ đóng lại nhưng không có khi tôi nhấp vào nút menu trong thanh tác vụ, bất kỳ ý kiến ​​nào tại sao?
galvan

Tôi không hoàn toàn chắc chắn, nhưng ... vì hướng và vị trí của Ngăn kéo hiện đã được thay đổi, trong Hoạt động của bạn, theo ví dụ trên Android, bạn nên có nút / nút chuyển đổi phương thức chuyển đổi nghe, hãy kiểm tra xem điều đó có cần đã sửa đổi để nó biết đóng lại bằng cách di chuyển sang RightToLeft. Nó có thể nghĩ giữ trên menu đã được đến trái (tức là ẩn) nên nó wont close (nếu điều đó làm cho tinh thần) ...
kickass

Các bạn ơi, mình cũng đang làm kiểu tương tự nhưng nếu dùng laoutDirection = "rtl" thì mình phải đổi minSdk là 17 nhưng ứng dụng của mình cần hỗ trợ API cấp 10. Các bạn có thể giúp mình để ứng dụng của mình có thể hỗ trợ API 10 được không.
Aditya

3

Hãy xem phần này: trượt ExpandableListView tại biểu mẫu DrawerLayout từ phải sang trái

Tôi giả sử bạn đã triển khai ActionBarDrawerToggle, mẹo là ghi đè onOptionsItemSelected(MenuItem item)phương thức bên trong đối tượng ActionBarDrawerToggle bằng:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawer.isDrawerOpen(Gravity.RIGHT)) {
                mDrawer.closeDrawer(Gravity.RIGHT);
            } else {
                mDrawer.openDrawer(Gravity.RIGHT);
            }
            return true;
        }
        return false;
    }

đảm bảo và gọi điều này từ onOptionsItemSelected(MenuItem item)trong Hoạt động:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

if(mDrawerToggle.onOptionsItemSelected(item)) {
    return true;
}

return super.onOptionsItemSelected(item);
}

Điều này sẽ cho phép bạn sử dụng chức năng của nút trang chủ. Để di chuyển nút sang bên phải của thanh tác vụ, bạn sẽ phải triển khai một mục tác vụ tùy chỉnh và có thể một số thứ khác để nó hoạt động như bạn muốn.


3

vấn đề chính với lỗi sau:

không tìm thấy chế độ xem ngăn kéo với trọng lực tuyệt đối LEFT

đó là, bạn đã xác định

android:layout_gravity="right"

cho dạng xem danh sách ở bên phải, nhưng hãy cố gắng mở ngăn kéo từ bên trái, bằng cách gọi hàm này:

mDrawerToggle.syncState();

và nhấp vào biểu tượng bánh hamburger!

chỉ cần bình luận chức năng trên và cố gắng xử lý việc mở / đóng menu như @Rudi đã nói!


3

Tôi đã giải quyết vấn đề này bằng cách thay đổi trọng lực của chế độ xem điều hướng

android: layout_gravity

để kết thúc thay vì bắt đầu

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/activity_drawer" />

Nó đã làm việc cho tôi.


2

Trước tiên, bạn nên đặt mã này vào AppManifest.xml của mình trong thẻ ứng dụng:

android:supportsRtl="true"

thì trong tệp activity_main.xml của bạn, hãy đặt đoạn mã này:

android:layout_direction="rtl"

đó là giải pháp tốt nhất từ ​​trước đến nay, bạn đã tiết kiệm được ngày của tôi nhờ
Ahmed Mousa

2

Tôi đã thực hiện sửa đổi sau ví dụ Hoạt động ngăn điều hướng trong Android Studio. Với các thư viện hỗ trợ 25.3.1.

MainActivity.java:

private DrawerLayout mDrawerLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
}

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
        mDrawerLayout.closeDrawer(GravityCompat.END);
    } else {
        super.onBackPressed();
    }
}

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    switch (itemId) {
        case android.R.id.home:
            finish();
            return true;

        case R.id.action_right_drawer:
            if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
                mDrawerLayout.closeDrawer(GravityCompat.END);
            } else {
                mDrawerLayout.openDrawer(GravityCompat.END);
            }
            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.

    mDrawerLayout.closeDrawer(GravityCompat.END);
    return true;
}

main.xml (tải xuống ic_menu_white_24px từ https://material.io/icons/ ):

<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_right_drawer"
        android:title="Drawer menu"
        android:icon="@drawable/ic_menu_white_24px"
        android:orderInCategory="100"
        app:showAsAction="always" />
</menu>

Trong thay đổi activity_main.xml

android:layout_gravity="start"

đến

android:layout_gravity="end"

2

Mở nó từ rtl không tốt cho trải nghiệm người dùng, để làm cho nó đáp ứng với ngôn ngữ của người dùng, tôi chỉ cần thêm dòng sau vào các thông số DrawerLayout của mình:

android:layoutDirection="locale"

Đã thêm nó vào AppBarLayout của tôi để làm cho bố cục bánh hamburger cũng khớp với hướng mở ngăn kéo.


1

DrawerLayout Thuộc tính android:layout_gravity="right|end"tools:openDrawer="end" NavigationView tài sản android:layout_gravity="end"

XML Layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:layout_gravity="right|end"
    tools:openDrawer="end">

    <include layout="@layout/content_main" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

Java Code

// Appropriate Click Event or Menu Item Click Event

if (drawerLayout.isDrawerOpen(GravityCompat.END)) 
{
     drawerLayout.closeDrawer(GravityCompat.END);
} 
else 
{
     drawerLayout.openDrawer(GravityCompat.END);
}
//With Toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);

drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            //Gravity.END or Gravity.RIGHT
            if (drawer.isDrawerOpen(Gravity.END)) {
                drawer.closeDrawer(Gravity.END);
            } else {
                drawer.openDrawer(Gravity.END);
            }
        }
    });
//...
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.