프래그먼트를 사용할 때 Android Navigation Drawer 이미지와 Up caret 간 전환 조각을 대체하기 위해 새

Navigation Drawer를 사용할 때 Android 개발자는 ActionBar에서 “Navigation Drawer에 표시되는 화면에만 실제로 Navigation Drawer 이미지가 있어야하며”다른 모든 화면에는 전통적인 업 캐럿이 있어야합니다.

자세한 내용은 여기를 참조하십시오 : http://youtu.be/F5COhlbpIbY

하나의 활동을 사용하여 여러 레벨의 조각을 제어하고 탐색 드로어 이미지를 모든 레벨에서 표시하고 작동시킬 수 있습니다.

낮은 수준의 조각을 만들 때 ActionBarDrawerToggle setDrawerIndicatorEnabled(false)탐색 창 이미지를 숨기고 위로 캐럿을 표시하도록 호출 할 수 있습니다

LowerLevelFragment lowFrag = new LowerLevelFragment();

//disable the toggle menu and show up carat
theDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportFragmentManager().beginTransaction().replace(R.id.frag_layout,
lowFrag, "lowerFrag").addToBackStack(null).commit();

내가 겪고있는 문제는 원래 탐색 서랍 이미지 대신 여전히 업 캐럿이 표시하는 최상위 조각으로 돌아갈 때입니다. Navigation Drawer 이미지를 다시 표시하기 위해 최상위 조각에서 ActionBar를 “새로 고침”하는 방법에 대한 제안 사항이 있습니까?


해결책

톰의 제안이 나를 위해 일했습니다. 내가 한 일은 다음과 같습니다.

주요 활동

이 활동은 앱의 모든 조각을 제어합니다.

다른 조각을 대체하기 위해 새 조각을 준비 할 때 DrawerToggle을 다음 setDrawerIndicatorEnabled(false)과 같이 설정 했습니다.

LowerLevelFragment lowFrag = new LowerLevelFragment();

//disable the toggle menu and show up carat
theDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportFragmentManager().beginTransaction().replace(R.id.frag_layout,
lowFrag).addToBackStack(null).commit();

다음으로의 재정의 onBackPressed에서 DrawerToggle을 다음 setDrawerIndicatorEnabled(true)과 같이 설정하여 위의 내용을 되돌 렸습니다 .

@Override
public void onBackPressed() {
    super.onBackPressed();
    // turn on the Navigation Drawer image; 
    // this is called in the LowerLevelFragments
    setDrawerIndicatorEnabled(true)
}

LowerLevelFragments에서

내가 수정 한 조각에서 다음 onCreateonOptionsItemSelected같이 :

에서는 onCreate추가 setHasOptionsMenu(true)옵션 메뉴를 구성 할 수 있도록. 또한 작업 표시 줄 setDisplayHomeAsUpEnabled(true)에서 < 을 활성화하도록 설정하십시오 .

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // needed to indicate that the fragment would 
    // like to add items to the Options Menu        
    setHasOptionsMenu(true);
    // update the actionbar to show the up carat/affordance 
    getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
}

그런 다음 < 을 누를 onOptionsItemSelected때마다 액티비티에서를 호출 하여 계층 구조에서 한 수준 위로 이동하고 탐색 창 이미지를 표시합니다.onBackPressed()

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Get item selected and deal with it
    switch (item.getItemId()) {
        case android.R.id.home:
            //called when the up affordance/carat in actionbar is pressed
            getActivity().onBackPressed();
            return true;
        
    }



답변

하위 레벨 단편을 구현하기 위해 새 활동에서 하위 레벨 단편을 구현하는 것과는 반대로 기존 단편을 대체하고 있습니다.

그런 다음 뒤로 기능을 수동으로 구현해야한다고 생각합니다. 사용자가 뒤로 밀면 스택을 팝업하는 코드가 있습니다 (예 : Activity::onBackPressed재정의). 그래서, 당신이 그것을하는 곳마다, 당신은를 바꿀 수 있습니다 setDrawerIndicatorEnabled.


답변

1-2-3처럼 쉽습니다.

달성하려는 경우 :

1) 드로어 표시기 -백 스택에 조각이 없거나 드로어가 열린 경우

2) 화살표 -일부 조각이 백 스택에있을 때

private FragmentManager.OnBackStackChangedListener
        mOnBackStackChangedListener = new FragmentManager.OnBackStackChangedListener() {
    @Override
    public void onBackStackChanged() {
        syncActionBarArrowState();
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    getSupportActionBar().setDisplayShowHomeEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    mDrawerToggle = new ActionBarDrawerToggle(
            this,
            mDrawerLayout,
            R.drawable.ic_navigation_drawer,
            0,
            0
    ) {

        public void onDrawerClosed(View view) {
            syncActionBarArrowState();
        }

        public void onDrawerOpened(View drawerView) {
            mDrawerToggle.setDrawerIndicatorEnabled(true);
        }
    };

    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getSupportFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
}

@Override
protected void onDestroy() {
    getSupportFragmentManager().removeOnBackStackChangedListener(mOnBackStackChangedListener);
    super.onDestroy();
}

private void syncActionBarArrowState() {
    int backStackEntryCount =
        getSupportFragmentManager().getBackStackEntryCount();
    mDrawerToggle.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}

3) 모양에 따라 작동하는 두 지표

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (mDrawerToggle.isDrawerIndicatorEnabled() &&
        mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    } else if (item.getItemId() == android.R.id.home &&
               getSupportFragmentManager().popBackStackImmediate()) {
        return true;
    } else {
        return super.onOptionsItemSelected(item);
    }
}

PS 3 줄 표시기 동작에 대한 다른 팁은 Android 개발자 에서 탐색 창 만들기를 참조하십시오 .


답변

나는 다음을 사용했다 :

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
            @Override
            public void onBackStackChanged() {
                if(getSupportFragmentManager().getBackStackEntryCount() > 0){
                    mDrawerToggle.setDrawerIndicatorEnabled(false);
                    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                }
                else {
                    getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                    mDrawerToggle.setDrawerIndicatorEnabled(true);
                }
            }
        });


답변

업 액션 바 버튼이 작동하지 않으면 리스너를 추가하는 것을 잊지 마십시오.

// Navigation back icon listener
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onBackPressed();
        }
});

홈 버튼으로 서랍 탐색을 구현하는 데 문제가 있습니다. 작업 버튼을 제외한 모든 것이 작동했습니다.


답변

DrawerToggle의 상태에 따라 MainActivity에서 홈 항목 선택을 처리하십시오. 이렇게하면 모든 조각에 동일한 코드를 추가 할 필요가 없습니다.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Only handle with DrawerToggle if the drawer indicator is enabled.
    if (mDrawerToggle.isDrawerIndicatorEnabled() &&
            mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action buttons
    switch (item.getItemId()) {
        // Handle home button in non-drawer mode
        case android.R.id.home:
            onBackPressed();
            return true;

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


답변

팔로우

@dzeikei가 제공 한 솔루션은 깔끔하지만 조각을 사용할 때 확장되어 백 스택이 비어있을 때 서랍 표시기 설정을 자동으로 처리 할 수 ​​있습니다.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Only handle with DrawerToggle if the drawer indicator is enabled.
    if (mDrawerToggle.isDrawerIndicatorEnabled() &&
            mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action buttons
    switch (item.getItemId()) {
        // Handle home button in non-drawer mode
        case android.R.id.home:
            // Use getSupportFragmentManager() to support older devices
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.popBackStack();
            // Make sure transactions are finished before reading backstack count
            fragmentManager.executePendingTransactions();
            if (fragmentManager.getBackStackEntryCount() < 1){
                mDrawerToggle.setDrawerIndicatorEnabled(true);
            }
            return true;

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

편집하다

@JJD의 질문에.

조각은 활동에서 유지 / 관리됩니다. 위의 코드는 해당 활동에서 한 번 작성되었지만의 업 캐럿 만 처리합니다 onOptionsItemSelected.

내 앱 중 하나에서 뒤로 버튼을 눌렀을 때 업 캐럿의 동작을 처리해야했습니다. 이를 재정 의하여 처리 할 수 ​​있습니다 onBackPressed.

@Override
public void onBackPressed() {
    // Use getSupportFragmentManager() to support older devices
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.executePendingTransactions();
    if (fragmentManager.getBackStackEntryCount() < 1){
        super.onBackPressed();
    } else {
        fragmentManager.executePendingTransactions();
        fragmentManager.popBackStack();
        fragmentManager.executePendingTransactions();
        if (fragmentManager.getBackStackEntryCount() < 1){
            mDrawerToggle.setDrawerIndicatorEnabled(true);
        }
    }
};

사이의 코드 중복을 참고 onOptionsItemSelected하고 onBackPressed있는이 방법을 생성하고 두 곳에서 해당 메소드를 호출하여 피할 수 있습니다.

또한 executePendingTransactions필자의 경우 필요하거나 때로는 업 캐럿의 이상한 행동을했던 두 번 더 추가 합니다.


답변

햄버거 메뉴의보기 상태를 업데이트하기 위해 호스팅 활동에 대한 인터페이스를 만들었습니다. 최상위 조각의 경우 토글을 설정 true하고 위쪽 <화살표를 표시하려는 조각의 토글을로 설정했습니다 false.

public class SomeFragment extends Fragment {

    public interface OnFragmentInteractionListener {
        public void showDrawerToggle(boolean showDrawerToggle);
    }

    private OnFragmentInteractionListener mListener;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            this.mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        mListener.showDrawerToggle(false);
    }
}

그런 다음 내 활동에서 …

public class MainActivity extends Activity implements SomeFragment.OnFragmentInteractionListener {

    private ActionBarDrawerToggle mDrawerToggle;

    public void showDrawerToggle(boolean showDrawerIndicator) {
        mDrawerToggle.setDrawerIndicatorEnabled(showDrawerIndicator);
    }

}