4

Я пытаюсь повторно использовать NavigationBar из Android ActionBar для перемещения между экранами. Поскольку каждый экран содержит много отдельной логики, я хотел бы иметь Activity для каждого экрана, но каждый экран должен повторно использовать ActionBar, поскольку он содержит навигацию и другие пользовательские представления.Использование Android ActionBar для перемещения между действиями

Для этого я создал базовый класс активности, который генерирует соответствующую панель действий. Следующий код работает так, как я ожидаю, но что-то не совсем правильно. Мне кажется, что я слишком много работаю над тем, что должно быть проще. Кроме того, хотя моя базовая активность повторно использует много кода, она фактически не использует ActionBar в памяти.

Есть ли другой собственный навигационный элемент управления, который я мог бы использовать для достижения этого? Я не хочу, чтобы пользовательский макет раздувал или создавал настраиваемую панель навигации.

Кроме того, я использую Mono для Xamarin для Android.

Базовая навигация активность

public abstract class BaseNavigationActivity : Activity 
{ 
    private NavigationScreens[] _availableScreens = { NavigationScreens.Screen1, NavigationScreens.Screen2 }; 
    private NavigationScreens _currentScreen = NavigationScreens.Unknown; 

    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 

     // Remove ActionBar icon and title. Also allow custom view. 
     ActionBar.SetDisplayShowHomeEnabled(false); 
     ActionBar.SetDisplayShowTitleEnabled(false); 

     // Navigation bar 
     ScreenNavigationAdapter screenAdapter = new ScreenNavigationAdapter(this, _availableScreens); 
     ScreenNavigationListener navigationListener = new ScreenNavigationListener(this, screenAdapter); 

     ActionBar.NavigationMode = ActionBarNavigationMode.List; 
     ActionBar.SetListNavigationCallbacks(screenAdapter, navigationListener); 
    } 

    protected override void OnResume() 
    { 
     base.OnResume(); 

     // Set the navigation item on the action bar to be the current screen 
     ActionBar.SetSelectedNavigationItem(Array.FindIndex(_availableScreens, x => x == _currentScreen)); 
    } 

    public NavigationScreens CurrentScreen 
    { 
     get { return _currentScreen; } 
    } 

    public BaseNavigationActivity(NavigationScreens screen) 
    { 
     _currentScreen = screen; 
    } 

Sample активность

[Activity(Label = "ActionBarTest", MainLauncher = true, Theme = "@style/CustomActionBarStyle", LaunchMode = LaunchMode.SingleInstance)] 
public class ActionBarNavigationTestActivity : BaseNavigationActivity 
{ 
    public ActionBarNavigationTestActivity() 
     : base(NavigationScreens.Screen1) 
    { 
    } 

    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 
     SetContentView(Resource.Layout.ActionBarNavigation); 
    } 
} 

Адаптеры и Слушателей

public class ScreenNavigationAdapter : BaseAdapter 
{ 
    private IEnumerable<NavigationScreens> _screens; 
    private LayoutInflater _layoutInflater; 

    public ScreenNavigationAdapter(Context context, IEnumerable<NavigationScreens> screens) 
    { 
     _screens = screens; 

     // Retrieve the layout inflater from the provided context 
     _layoutInflater = LayoutInflater.FromContext(context); 
    } 

    public override Java.Lang.Object GetItem(int position) 
    { 
     return null; 
    } 

    public override long GetItemId(int position) 
    { 
     return position; 
    } 

    public override View GetView(int position, View convertView, ViewGroup parent) 
    { 
     var view = convertView; 

     // Try to reuse views as much as possible. 
     if (view == null) 
     { 
      // inflate a new layout for the view. 
      view = _layoutInflater.Inflate(Resource.Layout.SpinnerViewLayout, parent, false); 
     } 

     TextView textView = view.FindViewById<TextView>(Resource.Id.MenuText); 
     textView.Text = _screens.ElementAt(position).ToString(); 

     return view; 
    } 

    public override int Count 
    { 
     get { return _screens.Count(); } 
    } 

    public NavigationScreens GetScreenAt(int position) 
    { 
     return _screens.ElementAt(position); 
    } 
} 

public class ScreenNavigationListener : Java.Lang.Object, ActionBar.IOnNavigationListener 
{ 
    private readonly BaseNavigationActivity _currentActivity = null; 
    private readonly ScreenNavigationAdapter _adapter = null; 

    public ScreenNavigationListener(BaseNavigationActivity currentScreen, ScreenNavigationAdapter adapter) 
    { 
     _currentActivity = currentScreen; 
     _adapter = adapter; 
    } 

    public bool OnNavigationItemSelected(int itemPosition, long itemId) 
    { 
     NavigationScreens selectedScreen = _adapter.GetScreenAt(itemPosition); 
     if (_currentActivity.CurrentScreen == selectedScreen) 
     { 
      // Already displaying the selected screen, dont do anything 
      return true; 
     } 

     Intent intent = null; 
     if (selectedScreen == NavigationScreens.Screen1) 
     { 
      intent = new Intent(_currentActivity, typeof(ActionBarNavigationTestActivity)); 
     } 

     if (selectedScreen == NavigationScreens.Screen2) 
     { 
      intent = new Intent(_currentActivity, typeof(ActionBarNavigationTestActivity2)); 
     } 

     if (intent != null) 
     { 
      intent.SetFlags(ActivityFlags.NoAnimation); 
      _currentActivity.StartActivity(intent); 

      return true; 
     } 

     return false; 
    } 
} 

public enum NavigationScreens 
{ 
    Unknown = -1, 
    Screen1 = 0, 
    Screen2 
} 
+4

Вы действительно должны переключиться на использование фрагментов, а не на действия, это сэкономит вам много времени и усилий. – Egor

+1

Я бы воспользовался советом Егора, другой вариант, если бы вы не использовали 'Фрагменты', было бы в основном воссоздать панель навигации для каждой сделанной вами« Деятельности ». – Bryan

+1

Ничего себе, абсолютно правильно. Я должен был больше узнать о Фрагментах. Они имеют свой собственный жизненный цикл отдельно, получают возможность повторно использовать панель действий, а код разделяется. Прототип работает отлично. Может ли кто-нибудь из вас ответить, чтобы я согласился. Благодарю. – Alex

ответ

0

Если у вас меньше экранов, попробуйте использовать этот метод, который объединяет оба фрагмента и ActionBar для обеспечения навигации по экранам. http://www.lucazanini.eu/2012/android/tab-layout-in-android-with-actionbar-and-fragment/?lang=en

+0

Последующая ссылка, если вам хочется продолжить работу с выше. http://www.lucazanini.eu/2013/android/actionbar-fragment-and-screen-rotation/ –

Смежные вопросы