다른 활동에서 동일한 탐색 창


206

developer.android.com 웹 사이트 의 자습서에 표시된 것처럼 작동하는 탐색 드로어를 작성했습니다 . 그러나 이제 내 응용 프로그램의 여러 활동을 위해 NavigationDrawer.class에서 만든 하나의 Navigation Drawer를 사용하고 싶습니다.

내 질문은, 여기 누군가가 작은 튜토리얼을 만들 수 있다면, 여러 활동에 하나의 탐색 서랍을 사용하는 방법을 설명합니다.

여러 활동에 대한 이 Answer Android Navigation Drawer에서 처음 읽었습니다.

하지만 내 프로젝트에서 작동하지 않았습니다.

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);
}
}

이 활동에서 나는 탐색 서랍을 갖고 싶어서 'NavigationDrawer'를 확장하고 다른 활동에서는 동일한 탐색 서랍을 사용하려고합니다.

  public class SampleActivity extends NavigationDrawer {...}

무엇을 바꿔야할지 모르겠습니다 ...


1
여기 에서 예제를 찾을 수 있습니다 .
Naddy

1
다음에서 찾을 수 있습니다 : stackoverflow.com/questions/33009469/…
varotariya vajsi

답변:


188

탐색 드로어를 원하면 조각을 사용해야합니다. 지난주에이 튜토리얼을 따랐으며 훌륭하게 작동합니다.

http://developer.android.com/training/implementing-navigation/nav-drawer.html

이 튜토리얼에서 샘플 코드를 다운로드하여이를 수행하는 방법을 확인할 수도 있습니다.


파편없이 :

이것은 BaseActivity 코드입니다.

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);
    }
}

탐색 드로어가 필요한 다른 모든 활동은 활동 자체 대신이 활동을 확장해야합니다. 예 :

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>

편집하다:

나는 약간의 어려움을 겪었으므로 NullPointerExceptions를 얻는다면 여기에 해결책이 있습니다. BaseActivity에서 onCreate 함수를로 변경하십시오 protected void onCreateDrawer(). 나머지는 동일하게 유지 될 수 있습니다. BaseActivity를 확장하는 활동에서 코드를 다음 순서로 넣으십시오.

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

이것은 내 문제를 해결하는 데 도움이되었습니다. 도움이되기를 바랍니다.

질문이 있으시면 여러 활동이 포함 된 탐색 창을 만드는 방법입니다.


편집 2 :

@GregDan이 말했듯이 onCreateDrawer를 BaseActivity재정의 setContentView()하고 호출 할 수 있습니다 .

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

7
조각보다 활동을 사용하고 싶지 않고 동일한 탐색 드로어를 모두 사용하는 다른 활동을 사용하고 싶습니다. 스 와이프보기,지도보기 등 다양한 유형의 레이아웃을 사용할 수 있기 때문에 활동이 필요합니다.
MEX

135
하나의 활동 만 갖는 것은 상당히 복잡한 응용 프로그램에게는 어려운 작업이 될 수 있습니다. 활동을 사용하면 시스템에서 많은 무료 항목을 얻을 수 있으므로 여러 활동을 사용하는 방법이 유효합니다. 여러 조각 조합 사이의 통신을 처리하는 하나의 활동을 상상할 수 없습니다. 작동하지 않습니다.
slott

1
답변하는 데 시간이 오래 걸렸습니다. 내 답변을 편집했습니다. 나는 이것이 당신이 찾고있는 튜토리얼이라고 생각합니다. 도움이 되었기를 바랍니다.
Kevin van Mierlo

2
@KevinvanMierlo 당신은 당신이 무슨 뜻인지 말해 줄 수 있습니다 : R.id.drawer_layout은 정확히 동일한 ID를 가진 모든 활동에 있어야합니다. 당신이 여기서 말한 것을 정확하게했기 때문에이 BaseActivity를 확장하는 Activity의 onCreate () 메소드에서 NullPointerException이 발생합니다.
Loolooii

1
트윗 담아 가기 super.onCreate (savedInstanceState); setContentView (R.layout.activity_base);
Loolooii

34

최고의 구현을 찾았습니다. 그것은에서의 구글 I / O 2014 응용 프로그램.

그들은 Kevin과 같은 접근법을 사용합니다. I / O 앱의 불필요한 모든 항목에서 자신을 추상화 할 수 있다면 필요한 모든 것을 추출 할 수 있으며 Google은 탐색 드로어 패턴의 올바른 사용법을 보장합니다. 각 활동에는 선택적 DrawerLayout으로 기본 레이아웃이 있습니다. 흥미로운 부분은 다른 화면으로 이동하는 방법입니다. 다음 BaseActivity과 같이 구현됩니다 .

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

이것은 현재 조각을 조각 트랜잭션으로 대체하는 일반적인 방법과 다릅니다. 그러나 사용자는 시각적 차이를 발견하지 못합니다.


^ 나는 그들이 새로운 활동을 시작하는 방법을 알아낼 수 없으며 그것이 완벽하게 작동합니다. 작업하기에 큰 앱입니다.
hitch.united

@ hitch.united 많은 조각과 몇 가지 활동을 사용하기 때문입니다.
Joaquin Iurchuk

@ hitch.united로 아마도 활동의 애니메이션을 재정의합니다 overridePendingTransitions.
EpicPandaForce 13:14에

서브 클래 싱 활동 대신 프래그먼트를 로딩 하는가?
Vikas Pandey

여기 년 10 월 2014 파일입니다 : github.com/google/iosched/blob/...
denvercoder9은

8

따라서이 답변은 몇 년 늦었지만 누군가는 그것을 감사 할 것입니다. Android는 여러 활동이 포함 된 하나의 탐색 창을보다 쉽게 ​​사용할 수있는 새로운 위젯을 제공했습니다.

android.support.design.widget.NavigationView는 모듈 식이며 메뉴 폴더에 자체 레이아웃이 있습니다. 사용하는 방법은 다음과 같은 방식으로 xml 레이아웃을 래핑하는 것입니다.

  1. 루트 레이아웃은 <include ... />랩핑되는 레이아웃 (2 참조)과 android.support.design.widget.NavigationView의 두 자식을 포함 하는 android.support.v4.widget.DrawerLayout입니다.

    <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은 Navigation Drawar의 헤더에 방향 = 수직 인 LinearLayout입니다.

activity_main_drawer는 res / menu 디렉토리의 메뉴 xml입니다. 선택한 항목과 그룹을 포함 할 수 있습니다. AndroidStudio Gallery를 사용하는 경우 마법사가 기본 마법사를 만들고 옵션이 무엇인지 확인할 수 있습니다.

  1. 앱 바 레이아웃은 일반적으로 android.support.design.widget.CoordinatorLayout이며 여기에는 android.support.design.widget.AppBarLayout (android.support.v7.widget.Toolbar 포함) 및 <include ... >for. 실제 내용 (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. 콘텐츠 레이아웃은 원하는 레이아웃이 될 수 있습니다. 이것은 활동의 주요 내용을 포함하는 레이아웃입니다 (탐색 서랍이나 앱 바는 포함되지 않음).

이제이 모든 것의 멋진 점은이 두 레이아웃으로 각 활동을 래핑 할 수 있지만 NavigationView (1 단계 참조)가 항상 activity_main_drawer (또는 무엇이든)를 가리 키도록한다는 것입니다. 즉, 모든 활동에 대해 동일한 (*) 탐색 창을 갖게됩니다.

  • 그것들은 NavigationView 의 동일한 인스턴스 는 아니지만 공정하게 말하면 위에서 설명한 BaseActivity 솔루션으로는 불가능했습니다.

stackoverflow는 xml 괄호 중 일부를 차단하지만 중요한 것은 모두 있습니다.
jwehrle

그러나 버튼과 같은 기능을 어떻게 취급합니까? 모든 활동에 동일한 코드를 작성해야합니까?
Laur89

예, 이들은 별도의 인스턴스이기 때문입니다. 그러나 활동에 대한 슈퍼 클래스를 만들어 해당 코드를 한 번 확장하고 넣을 수 있습니다.
jwehrle

@jwehrle 활동을위한 슈퍼 클래스 만들기에 대한 예를 작성할 수 있습니까?
CDrosos

public abstract class MyBaseActivity 확장 AppCompatActivity가 NavigationView.OnNavigationItemSelectedListener 구현 {// 다음을 구현합니다. public boolean onNavigationItemSelected (@NonNull MenuItem item) {}} 구현 public class MyActivity는 MyBaseActivity를 확장합니다. {}
jwehrle

7

활동 그룹간에 공통 탐색 드로어를 재사용하는 가장 쉬운 방법

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;
    }
}

이 기본 활동을 사용하는 활동의 예를 제공 할 수 있습니까?
CDrosos

실제로 이것에 대한 세부 사항을 기억할 수는 없지만 확장 AppBaseActivity setContentViewind 기본 방법이 작동해야 한다고 생각 합니다.
Levon Petrosyan

6

원래 포스터가 요구하는 것을 수행하려는 다른 사람은 Kevin이 말한 방식 대신 조각을 사용하는 것이 좋습니다. 이를 수행하는 방법에 대한 훌륭한 자습서는 다음과 같습니다.

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

프래그먼트 대신 액티비티를 사용하도록 선택하면 새 액티비티로 이동할 때마다 탐색 드로어가 다시 작성되는 문제가 발생합니다. 이로 인해 매번 탐색 서랍이보기 흉하고 느리게 렌더링됩니다.


5

내 제안은 : 활동을 전혀 사용하지 말고 조각을 사용하고 첫 번째 조각을 표시하는 컨테이너 (예 : 선형 레이아웃)에서 교체하십시오.

코드는 Android Developer Tutorials에서 사용할 수 있습니다. 사용자 정의하면됩니다.

http://developer.android.com/training/implementing-navigation/nav-drawer.html

애플리케이션에서 점점 더 많은 프래그먼트를 사용해야하며 외부 애플리케이션과 별도로 AndroidManifest.xml에서 언급 한 네 가지 기본 활동 만 애플리케이션에 국한되어야합니다 (FacebookActivity).

  1. SplashActivity : 조각을 사용하지 않고 FullScreen 테마를 사용합니다.

  2. LoginSignUpActivity : NavigationDrawer를 전혀 필요로하지 않고 뒤로 단추도 필요하지 않으므로 일반 도구 모음을 사용하기 만하면 최소한 3 개 또는 4 개의 조각이 필요합니다. 액션 바없는 테마 사용

  3. HomeActivity 또는 DashBoard Activity : 액션 바 없음 테마를 사용합니다. 여기에는 탐색 드로어가 필요하며, 그 다음에 나오는 모든 화면은 공유 드로어와 함께 리프보기까지 프래그먼트 또는 중첩 된 프래그먼트입니다. 이 액티비티에서는 모든 설정, 사용자 프로필 등이 조각으로 표시됩니다. 여기의 조각은 백 스택에 추가되지 않으며 서랍 메뉴 항목에서 열립니다. 서랍 대신 뒤로 버튼이 필요한 조각의 경우 아래에 네 번째 종류의 활동이 있습니다.

  4. 서랍이없는 활동. 이 액티비티에는 상단에 뒤로 버튼이 있으며 내부 조각은 동일한 작업 표시 줄을 공유합니다. 탐색 내역이 있으므로 이러한 조각은 백 스택에 추가됩니다.

[추가 지침은 https://stackoverflow.com/a/51100507/787399 참조 ]

행복한 코딩!


이것은 오래된 게시물입니다. 프래그먼트를 사용하여 항상 하나의 활동을 가질 수 있습니다. 전용 컨테이너 하나에서 조각을 계속 교체합니다. 뒤로 탐색해야 할 경우 스택을 다시 배치하거나 조각을 첫 번째 조각으로 표시해야 할 경우 모든 조각을 팝하십시오.
Abhinav Saxena 2016 년

@ Cabuxa.Mapache 추가 지원을 받으려면 답변에 첨부 된 링크를 확인하십시오. ActionBar ToolBar 및 NavigatonDrawer 및 기타 모든 구성 요소를 첨부하는 데 도움이되는 일반적인 BaseActivity를 사용했습니다.
아비 나브 삭 세나

1

기본 활동에서이 코드를 업데이트하십시오. 그리고 활동 XML에 drawer_list_header를 포함시키는 것을 잊지 마십시오.

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

활동에 request ()를 사용하지 마십시오. 그러나 여전히 이미지를 클릭하면 서랍이 보이지 않습니다. 드래그하면 목록 항목이 없어도 서랍이 보입니다. 나는 많이 시도했지만 성공하지 못했습니다. 이를 위해 운동이 필요합니다 ...


1

@Kevin van Mierlo의 답변으로 여러 서랍을 구현할 수도 있습니다. 예를 들어, 왼쪽에있는 기본 메뉴 (시작)와 오른쪽에있는 추가 옵션 메뉴는 결정적 조각이로드 된 경우에만 표시됩니다.

나는 그것을 할 수 있었다.


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







    }

툴바에 이것을 사용하십시오.

<?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>

사용하려면 탐색 헤더에 이것을 사용하십시오.

<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

나는 Kotlin에서 다음과 같이합니다.

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
}
}

서랍에 대한 활동은 이것을 상속하고 내용이 설정된 후 BaseAppCompatActivity호출 super.onCreate(실제로 일부 init 메소드로 이동할 수 있음)하고 레이아웃에 id에 해당하는 요소가 있어야합니다


귀하의 솔루션을 시도하고 싶지만 "이 활동에는 이미 창 장식에서 제공하는 작업 표시 줄이 있습니다"라는 오류가 발생합니다. 3 가지 활동을 전환하고 서로에게 고유 한 앱 바가 있습니다. 가능하다고 생각하십니까?
davoid

이 경우 작업 표시 줄을 조각으로 이동해야한다고 생각합니다. 우리 앱에서 우리는 NoActionBar 테마를 사용하고 호환성을 위해 툴바를 제공했습니다.
Pavlus

@Pavlus 두 번째 활동에서 코드는 어떻게 생겼습니까? trackActivity 클래스 : BaseAppCompatActivity () {?
Craig P

0

내 대답은 소스 코드가없는 개념적 것입니다. 나와 같은 일부 독자에게는 이해하는 것이 유용 할 수 있습니다.

앱의 아키텍처에 대한 초기 접근 방식에 따라 다릅니다. 기본적으로 두 가지 접근 방식이 있습니다.

  1. 하나의 활동 (기본 활동)을 작성하고 다른 모든보기 및 화면은 조각이됩니다. 해당 기본 활동에는 드로어 및 코디네이터 레이아웃에 대한 구현이 포함됩니다. 작은 자체 포함 된 조각을 사용하면 앱 개발이 더 쉽고 원활 해지 기 때문에 실제로 선호하는 방법입니다.

  2. 각 화면마다 하나씩 액티비티로 앱 개발을 시작한 경우 기본 액티비티를 만들고 다른 모든 액티비티에서 확장 할 수 있습니다. 기본 활동에는 드로어 및 코디네이터 구현을위한 코드가 포함됩니다. 드로어 구현이 필요한 모든 활동은 기본 활동에서 확장 될 수 있습니다.

나는 개인적으로 조직없이 혼합 된 조각과 활동을 사용하지 않는 것을 선호합니다. 그로 인해 개발이 더욱 어려워지고 결국 막힐 수 있습니다. 완료 한 경우 코드를 리 팩터하십시오.


-1

단편을 사용하여 MainActivity에서 탐색 드로어를 작성하십시오.
MainActivity에서 Navigation Drawer를 초기화하십시오.
이제 모든 다른 활동에서 동일한 Navigation Drawer를 사용하여 DrawerLayout을 기본으로 사용하고 탐색 창으로 사용하십시오. 프래그먼트 Java 파일을 가리키는 프래그먼트에서 android : name을 설정하십시오. 다른 활동에서 프래그먼트를 초기화 할 필요는 없습니다.
Google Play 스토어 앱과 같은 다른 활동에서 스 와이프하여 탐색 창에 액세스 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.