Cùng ngăn kéo điều hướng trong các hoạt động khác nhau


206

Tôi đã tạo một ngăn kéo điều hướng hoạt động giống như nó được hiển thị trong hướng dẫn trên trang web developer.android.com . Nhưng bây giờ, tôi muốn sử dụng một Ngăn kéo Điều hướng, tôi đã tạo trong NavigationDrawer. Class cho nhiều Hoạt động trong Ứng dụng của mình.

Câu hỏi của tôi là, nếu bất cứ ai ở đây có thể thực hiện một Hướng dẫn nhỏ, giải thích, cách sử dụng một ngăn kéo Điều hướng cho nhiều Hoạt động.

Tôi đọc nó đầu tiên tại Câu trả lời này Ngăn kéo điều hướng Android trên nhiều hoạt động

nhưng nó không hoạt động trong dự án của tôi

public class NavigationDrawer extends Activity {
public DrawerLayout drawerLayout;
public ListView drawerList;
private ActionBarDrawerToggle drawerToggle;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) {

        public void onDrawerClosed(View view) {
            getActionBar().setTitle(R.string.app_name);
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(R.string.menu);
        }
    };
    drawerLayout.setDrawerListener(drawerToggle);

    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    layers = getResources().getStringArray(R.array.layers_array);
    drawerList = (ListView) findViewById(R.id.left_drawer);
    View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
    drawerList.addHeaderView(header, null, false);
    drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
            layers));
    View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
            R.layout.drawer_list_footer, null, false);
    drawerList.addFooterView(footerView);

    drawerList.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
            map.drawerClickEvent(pos);
        }
    });
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);

}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    drawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    drawerToggle.onConfigurationChanged(newConfig);
}
}

Trong Hoạt động này, tôi muốn có Ngăn kéo Điều hướng để tôi mở rộng 'NavigationDrawer' và trong một số Hoạt động khác tôi muốn sử dụng cùng ngăn kéo Điều hướng

  public class SampleActivity extends NavigationDrawer {...}

Tôi không biết phải thay đổi gì ...


1
Bạn có thể tìm thấy các ví dụ ở đây .
Naddy

1
bạn có thể tìm thấy từ: stackoverflow.com/questions/33009469/
Ấn

Câu trả lời:


188

Nếu bạn muốn một ngăn kéo điều hướng, bạn nên sử dụng các mảnh. Tôi đã làm theo hướng dẫn này tuần trước và nó hoạt động rất tốt:

http://developer.android.com/training/imâying-navulation / nav -drawer.html

Bạn cũng có thể tải xuống mã mẫu từ hướng dẫn này, để xem cách bạn có thể làm điều này.


Không có mảnh vỡ:

Đây là Mã cơ sở của bạn:

public class BaseActivity extends Activity
{
    public DrawerLayout drawerLayout;
    public ListView drawerList;
    public String[] layers;
    private ActionBarDrawerToggle drawerToggle;
    private Map map;

    protected void onCreate(Bundle savedInstanceState)
    {
        // R.id.drawer_layout should be in every activity with exactly the same id.
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) 
        {
            public void onDrawerClosed(View view) 
            {
                getActionBar().setTitle(R.string.app_name);
            }

            public void onDrawerOpened(View drawerView) 
            {
                getActionBar().setTitle(R.string.menu);
            }
        };
        drawerLayout.setDrawerListener(drawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        layers = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.left_drawer);
        View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
        drawerList.addHeaderView(header, null, false);
        drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
                layers));
        View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.drawer_list_footer, null, false);
        drawerList.addFooterView(footerView);

        drawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                map.drawerClickEvent(pos);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);

    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }
}

Tất cả các Hoạt động khác cần có ngăn kéo điều hướng nên mở rộng Hoạt động này thay vì chính Hoạt động, ví dụ:

public class AnyActivity extends BaseActivity
{
    //Because this activity extends BaseActivity it automatically has the navigation drawer
    //You can just write your normal Activity code and you don't need to add anything for the navigation drawer
}

XML

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <!-- Put what you want as your normal screen in here, you can also choose for a linear layout or any other layout, whatever you prefer -->
    </FrameLayout>
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

Biên tập:

Bản thân tôi đã trải qua một số khó khăn, vì vậy đây là một giải pháp nếu bạn nhận được NullPulumExceptions. Trong BaseActivity thay đổi hàm onCreate thành protected void onCreateDrawer(). Phần còn lại có thể giữ nguyên. Trong các Hoạt động mở rộng BaseActivity, đặt mã theo thứ tự sau:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    super.onCreateDrawer();

Điều này đã giúp tôi khắc phục vấn đề của mình, hy vọng nó sẽ giúp!

Đây là cách bạn có thể tạo ngăn kéo điều hướng với nhiều hoạt động, nếu bạn có bất kỳ câu hỏi nào muốn hỏi.


Chỉnh sửa 2:

Như đã nói bởi @GregDan, bạn BaseActivitycũng có thể ghi đè setContentView()và gọi onCreateDrawer tại đó:

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}

7
Tôi không muốn sử dụng các hoạt động trên các mảnh, tôi chỉ muốn sử dụng các hoạt động khác nhau sử dụng tất cả cùng một ngăn kéo điều hướng. Tôi muốn hoạt động, vì ở đó tôi có thể sử dụng các loại bố cục khác nhau như chế độ xem vuốt, chế độ xem bản đồ ...
MEX

135
Chỉ có một Hoạt động có thể là một nhiệm vụ khó khăn cho bất kỳ ứng dụng khá phức tạp nào. Sử dụng Hoạt động cung cấp cho bạn rất nhiều thứ miễn phí từ hệ thống - vì vậy đây là điểm hợp lệ để sử dụng nhiều Hoạt động. Tôi không thể tưởng tượng một hoạt động xử lý giao tiếp giữa bất kỳ số lượng kết hợp phân đoạn nào - nó sẽ không hoạt động.
slott

1
Tôi xin lỗi phải mất quá lâu để tôi trả lời. Tôi đã chỉnh sửa câu trả lời của mình. Tôi tin rằng đây là hướng dẫn bạn đang tìm kiếm. Hi vọng điêu nay co ich.
Kevin van Mierlo

2
@KevinvanMierlo bạn có thể cho tôi biết ý của bạn là gì không: R.id.drawer_layout nên có trong mọi hoạt động với cùng một id. Bởi vì tôi đã làm chính xác những gì bạn đã nói ở đây và tôi nhận được một NullPulumException trong phương thức onCreate () của Hoạt động mở rộng BaseActivity này ..
Loolooii

1
@KevinvanMierlo btw, tôi nghĩ bạn đã quên 2 dòng này? super.onCreate (yetInstanceState); setContentView (R.layout.activity_base);
Loolooii

34

Tôi đã tìm thấy việc thực hiện tốt nhất. Nó có trong ứng dụng Google I / O 2014 .

Họ sử dụng phương pháp tương tự như của Kevin. Nếu bạn có thể trừu tượng bản thân khỏi tất cả những thứ không cần thiết trong ứng dụng I / O, bạn có thể trích xuất mọi thứ bạn cần và Google đảm bảo rằng đó là cách sử dụng đúng mẫu ngăn kéo điều hướng. Mỗi hoạt động tùy chọn có một DrawerLayoutbố cục chính của nó. Phần thú vị là cách điều hướng đến các màn hình khác được thực hiện. Nó được thực hiện BaseActivitynhư thế này:

private void goToNavDrawerItem(int item) {
        Intent intent;
        switch (item) {
            case NAVDRAWER_ITEM_MY_SCHEDULE:
                intent = new Intent(this, MyScheduleActivity.class);
                startActivity(intent);
                finish();
                break;

Điều này khác với cách phổ biến thay thế đoạn hiện tại bằng một giao dịch mảnh. Nhưng người dùng không phát hiện ra một sự khác biệt trực quan.


Điều này ^ Tôi không thể tìm ra cách họ bắt đầu các hoạt động mới và nó hoạt động hoàn hảo. Đây là một ứng dụng lớn để xử lý.
quá giang.united 16/2/2015

@ hitch.united Đó là vì họ sử dụng rất nhiều mảnh vỡ và chỉ một vài hoạt động.
Joaquin Iurchuk

@ hitch.united họ có thể ghi đè lên hình ảnh động của hoạt động với overridePendingTransitions.
EpicPandaForce

Đang tải các đoạn thay vì các hoạt động phân lớp?
Vikas Pandey

Đây là tệp từ tháng 10 năm 2014: github.com/google/iosched/blob/ từ
denvercoder9

8

Vì vậy, câu trả lời này là một vài năm muộn nhưng ai đó có thể đánh giá cao nó. Android đã cung cấp cho chúng tôi một tiện ích mới giúp sử dụng một ngăn kéo điều hướng với nhiều hoạt động dễ dàng hơn.

android.support.design.widget.NavlationView là mô-đun và có bố cục riêng trong thư mục menu. Cách bạn sử dụng là bọc các bố cục xml theo cách sau:

  1. Root Layout là một android.support.v4.widget.DrawerLayout chứa hai con: một <include ... />bố cục được gói (xem 2) và android.support.design.widget.NavlationView.

    <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="start">
    
    <include
        layout="@layout/app_bar_main"
        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="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

nav_header_main chỉ là một linearLayout với direction = vertical cho tiêu đề của Drawar Navigation của bạn.

Activity_main_drawer là một menu xml trong thư mục res / menu của bạn. Nó có thể chứa các mục và nhóm bạn chọn. Nếu bạn sử dụng Thư viện AndroidStudio, trình hướng dẫn sẽ tạo một cơ bản cho bạn và bạn có thể thấy các tùy chọn của mình là gì.

  1. Bố cục thanh ứng dụng thường là android.support.design.widget.CoordinatorLayout và điều này sẽ bao gồm hai con: một android.support.design.widget.AppBarLayout (chứa android.support.v7.widget.Toolbar) và <include ... >cho nội dung thực tế của bạn (xem 3).

    <android.support.design.widget.CoordinatorLayout
        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="yourpackage.MainActivity">
    
     <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    
    </android.support.design.widget.AppBarLayout>
    
    <include layout="@layout/content_main" />

  2. Bố cục nội dung có thể là bất cứ bố cục nào bạn muốn. Đây là bố cục chứa nội dung chính của hoạt động (không bao gồm ngăn điều hướng hoặc thanh ứng dụng).

Bây giờ, điều thú vị về tất cả những điều này là bạn có thể bao bọc từng hoạt động trong hai bố cục này nhưng có NavigationView của bạn (xem bước 1) luôn luôn trỏ đến Activity_main_drawer (hoặc bất cứ điều gì). Điều này có nghĩa là bạn sẽ có (*) Ngăn kéo điều hướng giống nhau trên tất cả các hoạt động.

  • Chúng sẽ không phải là ví dụ tương tự của NavigationView nhưng, công bằng mà nói, điều đó là không thể ngay cả với giải pháp BaseActivity đã nêu ở trên.

stackoverflow đang cắt bỏ một số dấu ngoặc xml kèm theo nhưng những thứ quan trọng đều có ở đó.
jwehrle

Nhưng làm thế nào để bạn đối xử với chức năng như các nút? bạn phải viết cùng một mã trong mọi hoạt động?
Laur89

Có, bởi vì đây là những trường hợp riêng biệt. Tuy nhiên, bạn có thể tạo một siêu hạng cho các hoạt động của mình để mở rộng và đặt mã đó ở đó một lần.
jwehrle

@jwehrle bạn có thể viết một ví dụ về việc tạo ra một siêu lớp cho các hoạt động của chúng tôi không?
CDrosos

public abstract class MyBaseActivity kéo dài AppCompatActivity cụ NavigationView.OnNavigationItemSelectedListener {// thực hiện như sau: public boolean Override onNavigationItemSelected (@NonNull MenuItem item) {}} public class MyActivity kéo dài MyBaseActivity {}
jwehrle

7

Cách dễ nhất để sử dụng lại ngăn kéo Điều hướng chung trong một nhóm các hoạt động

app_base_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

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

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_test"
        />
</android.support.v4.widget.DrawerLayout>

AppBaseActivity.java

/*
* This is a simple and easy approach to reuse the same 
* navigation drawer on your other activities. Just create
* a base layout that conains a DrawerLayout, the 
* navigation drawer and a FrameLayout to hold your
* content view. All you have to do is to extend your 
* activities from this class to set that navigation 
* drawer. Happy hacking :)
* P.S: You don't need to declare this Activity in the 
* AndroidManifest.xml. This is just a base class.
*/
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public abstract class AppBaseActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
    private FrameLayout view_stub; //This is the framelayout to keep your content view
    private NavigationView navigation_view; // The new navigation view from Android Design Library. Can inflate menu resources. Easy
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private Menu drawerMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.app_base_layout);// The base layout that contains your navigation drawer.
        view_stub = (FrameLayout) findViewById(R.id.view_stub);
        navigation_view = (NavigationView) findViewById(R.id.navigation_view);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        drawerMenu = navigation_view.getMenu();
        for(int i = 0; i < drawerMenu.size(); i++) {
          drawerMenu.getItem(i).setOnMenuItemClickListener(this);
        }
        // and so on...
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    /* Override all setContentView methods to put the content view to the FrameLayout view_stub
     * so that, we can make other activity implementations looks like normal activity subclasses.
     */
    @Override
    public void setContentView(int layoutResID) {
        if (view_stub != null) {
            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            View stubView = inflater.inflate(layoutResID, view_stub, false);
            view_stub.addView(stubView, lp);
        }
    }

    @Override
    public void setContentView(View view) {
        if (view_stub != null) {
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            view_stub.addView(view, lp);
        }
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        if (view_stub != null) {
            view_stub.addView(view, params);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                // handle it
                break;
            case R.id.item2:
                // do whatever
                break;
            // and so on...
        }
        return false;
    }
}

Bạn có thể cung cấp một ví dụ về một hoạt động sử dụng hoạt động cơ sở này?
CDrosos

Tôi thực sự không thể nhớ bất kỳ chi tiết nào về điều này, tôi nghĩ chỉ cần mở rộng AppBaseActivity setContentViewcách mặc định sẽ hoạt động.
Levon Petrosyan

6

Đối với bất kỳ ai khác muốn làm những gì người đăng ban đầu đang yêu cầu, vui lòng xem xét sử dụng các đoạn thay vì cách Kevin nói. Đây là một hướng dẫn tuyệt vời về cách làm điều đó:

https://github.com/codepath/android_guides/wiki/Fragment-Navulation-Drawer

Nếu bạn chọn thay vì sử dụng các hoạt động thay vì các đoạn bạn sẽ gặp phải vấn đề về ngăn kéo điều hướng được tạo lại mỗi khi bạn điều hướng đến một hoạt động mới. Điều này dẫn đến một kết xuất xấu xí / chậm của ngăn kéo điều hướng mỗi lần.


5

Đề nghị của tôi là: hoàn toàn không sử dụng các hoạt động, thay vào đó hãy sử dụng các đoạn và thay thế chúng trong vùng chứa (ví dụ Bố cục tuyến tính) nơi bạn hiển thị đoạn đầu tiên của mình.

Mã có sẵn trong Hướng dẫn dành cho nhà phát triển Android, bạn chỉ cần tùy chỉnh.

http://developer.android.com/training/imâying-navulation / nav -drawer.html

Bạn nên sử dụng ngày càng nhiều đoạn trong ứng dụng của mình và chỉ nên có bốn hoạt động cơ bản cục bộ cho ứng dụng của bạn, mà bạn đề cập đến trong AndroidManifest.xml ngoài các hoạt động bên ngoài (ví dụ như FacebookActivity):

  1. SplashActivity: không sử dụng phân đoạn và sử dụng chủ đề FullScreen.

  2. LoginSignUpActivity: Không yêu cầu NavigationDrawer, và cũng không có nút quay lại, vì vậy chỉ cần sử dụng thanh công cụ bình thường, nhưng ít nhất, sẽ cần 3 hoặc 4 đoạn. Sử dụng chủ đề không có hành động

  3. HomeActivity hoặc DashBoard Activity: Sử dụng chủ đề không có hành động. Ở đây bạn yêu cầu ngăn kéo Điều hướng, tất cả các màn hình theo sau sẽ là các mảnh hoặc các mảnh được lồng vào nhau, cho đến khi xem lá, với ngăn kéo được chia sẻ. Tất cả các cài đặt, hồ sơ người dùng và vv sẽ ở đây dưới dạng các đoạn, trong hoạt động này. Các mảnh ở đây sẽ không được thêm vào ngăn xếp phía sau và sẽ được mở từ các mục menu ngăn kéo. Trong trường hợp các mảnh yêu cầu nút quay lại thay vì ngăn kéo, có một loại hoạt động thứ tư dưới đây.

  4. Hoạt động không có ngăn kéo. Hoạt động này có nút quay lại trên đầu và các đoạn bên trong sẽ được chia sẻ cùng một thanh hành động. Những mảnh này sẽ được thêm vào ngăn xếp ngược, vì sẽ có một lịch sử điều hướng.

[Để được hướng dẫn thêm, hãy xem: https://stackoverflow.com/a/51100507/787399 ]

Chúc mừng mã hóa !!


Đây là một bài viết cũ hơn. Bạn có thể sử dụng các đoạn để đảm bảo bạn luôn có một hoạt động. Bạn tiếp tục thay thế các mảnh trong một container dành riêng cho nó. Đặt vào ngăn xếp phía sau khi bạn cần điều hướng lùi hoặc bật tất cả các đoạn khi bạn cần một đoạn được hiển thị như là đoạn đầu tiên.
Abhinav Saxena

@ Cabuxa.Mapache Vui lòng kiểm tra liên kết đính kèm với câu trả lời của tôi để được hỗ trợ thêm. Tôi đã lấy một BaseActivity chung, giúp chia sẻ ActionBar ToolBar và NavigatonDrawer và các thành phần khác trong tất cả các đoạn được đính kèm.
Abhinav Saxena

1

cập nhật mã này trong baseactivity. và đừng quên bao gồm ngăn kéo_list_header trong xml hoạt động của bạn.

super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.drawer_list_header);

và không sử dụng request () trong hoạt động của bạn. nhưng vẫn không thấy ngăn kéo khi nhấp vào hình ảnh..và bằng cách kéo nó sẽ hiển thị mà không có danh sách các mục. Tôi đã cố gắng rất nhiều nhưng không thành công. cần một số bài tập cho việc này ...


1

Với câu trả lời của @Kevin van Mierlo, bạn cũng có khả năng thực hiện một số ngăn kéo. Chẳng hạn, menu mặc định nằm ở phía bên trái (bắt đầu) và một menu tùy chọn khác, nằm ở phía bên phải, chỉ hiển thị khi các đoạn xác định được tải.

Tôi đã có thể làm điều đó.


1
package xxxxxx;



import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.widget.SearchView;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;


public class loginhome extends AppCompatActivity {
    private Toolbar toolbar;
    private NavigationView navigationView;
    private DrawerLayout drawerLayout;

    // Make sure to be using android.support.v7.app.ActionBarDrawerToggle version.
    // The android.support.v4.app.ActionBarDrawerToggle has been deprecated.
    private ActionBarDrawerToggle drawerToggle;

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

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


        //Initializing NavigationView


        navigationView = (NavigationView) findViewById(R.id.nav_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

            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.nav_first_fragment:
                        Toast.makeText(getApplicationContext(),"First fragment",Toast.LENGTH_SHORT).show();
                         FirstFragment fragment = new FirstFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame,fragment);
                        fragmentTransaction.commit();
                        return true;

                    // For rest of the options we just show a toast on click
                    case R.id.nav_second_fragment:
                        Toast.makeText(getApplicationContext(),"Second fragment",Toast.LENGTH_SHORT).show();
                        SecondFragment fragment2 = new SecondFragment();
                        android.support.v4.app.FragmentTransaction fragmentTransaction2 = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction2.replace(R.id.frame,fragment2);
                        fragmentTransaction2.commit();
                        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_layout);
        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close){

            @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();







    }

sử dụng cái này cho thanh công cụ của bạn

<?xml version="1.0" encoding="utf-8"?>

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:elevation="4dp"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark"


        >

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

sử dụng điều này cho tiêu đề điều hướng nếu muốn sử dụng

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:id="@+id/navhead"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:textColor="#ffffff"
            android:text="tanya"
            android:textSize="14sp"
            android:textStyle="bold"

            />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="5dp"
            android:text="tanya.com"
            android:textSize="14sp"
            android:textStyle="normal"

            />
    </LinearLayout>
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_below="@+id/imageView"
        android:layout_marginTop="15dp"

        android:src="@drawable/face"
        android:id="@+id/circleView"
        />



</RelativeLayout>

1

Tôi làm điều đó trong Kotlin như thế này:

open class BaseAppCompatActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

protected lateinit var drawerLayout: DrawerLayout
protected lateinit var navigationView: NavigationView
@Inject
lateinit var loginService: LoginService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("BaseAppCompatActivity", "onCreate()")
    App.getComponent().inject(this)
    drawerLayout = findViewById(R.id.drawer_layout) as DrawerLayout

    val toolbar = findViewById(R.id.toolbar) as Toolbar
    setSupportActionBar(toolbar)

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

    val toggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)

    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()
    toggle.isDrawerIndicatorEnabled = true

    val navigationViewHeaderView = navigationView.getHeaderView(0)
    navigationViewHeaderView.login_txt.text = SharedKey.username
}
private inline fun <reified T: Activity> launch():Boolean{
    if(this is T) return closeDrawer()
    val intent = Intent(applicationContext, T::class.java)
    startActivity(intent)
    finish()
    return true
}

private fun closeDrawer(): Boolean {
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val id = item.itemId

    when (id) {
        R.id.action_tasks -> {
            return launch<TasksActivity>()
        }
        R.id.action_contacts -> {
            return launch<ContactActivity>()
        }
        R.id.action_logout -> {
            createExitDialog(loginService, this)
        }
    }
    return false
}
}

Các hoạt động cho ngăn kéo phải kế thừa điều này BaseAppCompatActivity, gọi super.onCreatesau khi nội dung được đặt (thực tế, có thể được chuyển sang một số phương thức init) và có các phần tử tương ứng cho id trong bố cục của chúng


Tôi muốn thử giải pháp của bạn nhưng tôi gặp lỗi này: "Hoạt động này đã có thanh hành động được cung cấp bởi trang trí cửa sổ". Tôi muốn chuyển đổi giữa 3 hoạt động và nhau có thanh ứng dụng riêng. Bạn có nghĩ rằng điều đó là có thể?
davoid

Tôi nghĩ rằng, bạn cần di chuyển thanh hành động của mình thành các mảnh trong trường hợp đó. Trong ứng dụng của chúng tôi, chúng tôi đã sử dụng chủ đề NoActionBar và cung cấp thanh công cụ để tương thích, theo như tôi nhớ.
Pavlus

@Pavlus mã sẽ trông như thế nào trên hoạt động thứ hai? theo dõi lớpActivity: BaseAppCompatActivity () {?
Craig P

0

Câu trả lời của tôi chỉ là một khái niệm mà không có bất kỳ mã nguồn nào. Nó có thể hữu ích cho một số độc giả như tôi hiểu.

Nó phụ thuộc vào cách tiếp cận ban đầu của bạn về cách bạn kiến ​​trúc ứng dụng của bạn. Về cơ bản có hai cách tiếp cận.

  1. Bạn tạo một hoạt động (hoạt động cơ bản) và tất cả các chế độ xem và màn hình khác sẽ là các đoạn. Hoạt động cơ sở đó chứa triển khai cho Bố cục ngăn kéo và điều phối viên. Đó thực sự là cách làm ưa thích của tôi vì có những mảnh nhỏ khép kín sẽ giúp việc phát triển ứng dụng trở nên dễ dàng và mượt mà hơn.

  2. Nếu bạn đã bắt đầu phát triển ứng dụng của mình bằng các hoạt động, một hoạt động cho mỗi màn hình, thì có thể bạn sẽ tạo hoạt động cơ bản và tất cả các hoạt động khác đều mở rộng từ đó. Các hoạt động cơ sở sẽ chứa mã để thực hiện ngăn kéo và điều phối viên. Bất kỳ hoạt động nào cần thực hiện ngăn kéo có thể mở rộng từ hoạt động cơ sở.

Cá nhân tôi muốn tránh sử dụng các mảnh vỡ và các hoạt động trộn lẫn mà không có bất kỳ tổ chức. Điều đó làm cho sự phát triển khó khăn hơn và cuối cùng bạn bị mắc kẹt. Nếu bạn đã làm điều đó, cấu trúc lại mã của bạn.


-1

Tạo ngăn điều hướng trong MainActivity của bạn bằng cách sử dụng đoạn.
Khởi tạo Ngăn điều hướng trong MainActivity
ngay bây giờ trong tất cả các hoạt động khác mà bạn muốn sử dụng cùng một Ngăn kéo Điều hướng, đặt DrawerLayout làm cơ sở và phân đoạn làm ngăn kéo điều hướng. Chỉ cần đặt android: name trong đoạn của bạn trỏ đến tệp Java đoạn của bạn. Bạn sẽ không cần phải khởi tạo đoạn trong các Hoạt động khác.
Bạn có thể truy cập Nav Drawer bằng cách vuốt trong các hoạt động khác như trong ứng dụng Cửa hàng Google Play

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.