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에서
내가 수정 한 조각에서 다음 onCreate
과 onOptionsItemSelected
같이 :
에서는 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);
}
}