简体   繁体   English

提取正在启动新活动并用于许多不同活动的函数

[英]Extract function which is starting new Activity and is used in many different activities

I've started to learn Xamarin few days ago and now I'm facing a refactoring problem.几天前我开始学习 Xamarin,现在我面临重构问题。

Currently I've got multiple screen layout with bottom navigation bar for TABs to switch between screens.目前我有多个屏幕布局,底部导航栏用于选项卡在屏幕之间切换。 Every activity's layout is adding BottomNavigationBarView at the bottom and every activity's .cs initialize NavigationItemSelected inside their OnCreate methods in this way:每个 Activity 的布局都在底部添加BottomNavigationBarView ,并且每个 Activity 的.cs以这种方式在其 OnCreate 方法中初始化NavigationItemSelected

var bottomNavigationBar = FindViewById<BottomNavigationView>(Resource.Id.bottomNavigationBar);

bottomNavigationBar.SelectedItemId = Resource.Id.navigationBarMain; //This id is different for every activity
bottomNavigationBar.NavigationItemSelected += (sender, e) =>
{
    switch (e.Item.ItemId)
    {
        case Resource.Id.navigationBarMain:
            StartActivity(typeof(MainActivity));
            break;
        case Resource.Id.navigationBarHistory:
            StartActivity(typeof(HistoryActivity));
            break;
        case Resource.Id.navigationBarSettings:
            StartActivity(typeof(SettingsActivity));
            break;
    }
};

I would like to extract this piece of code into external function and just call it from every activity only with Resource.Id... parameter.我想将这段代码提取到外部函数中,并且只使用 Resource.Id... 参数从每个活动中调用它。

How can I do that?我怎样才能做到这一点?

You could create a "BaseActivity" which inherits from the Android activity class, and all your activities inherit from.您可以创建一个从 Android 活动类继承的“BaseActivity”,并且您的所有活动都继承自。 Then you could put a method in the base activity to do what you want.然后您可以在基本活动中放置一个方法来执行您想要的操作。 If you set your Activities to inherit from this activity you will be able to easily call it.如果您将活动设置为从该活动继承,您将能够轻松调用它。

Your base activity would look something like this:您的基本活动如下所示:

 [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar")]
    public class BaseActivity : AppCompatActivity
    {

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            
    }

protected virtual void SetBottomNavigationBar(int id)
    {
        var bottomNavigationBar = FindViewById<BottomNavigationView>(id);

        bottomNavigationBar.SelectedItemId = Resource.Id.navigationBarMain; //This id is different for every activity
        bottomNavigationBar.NavigationItemSelected += (sender, e) =>
        {
            switch (e.Item.ItemId)
            {
                case Resource.Id.navigationBarMain:
                    StartActivity(typeof(MainActivity));
                    break;
                case Resource.Id.navigationBarHistory:
                    StartActivity(typeof(HistoryActivity));
                    break;
                case Resource.Id.navigationBarSettings:
                    StartActivity(typeof(SettingsActivity));
                    break;
            }
        };
    }
}

Then in your other activities you would do something like this:然后在你的其他活动中你会做这样的事情:

[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
    public class MainActivity :BaseActivity 
    {

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

            //other code

            SetBottomNavigationBar(Resource.Id.bottomNavigationBar);
        }

} }

Instead of the inheritance that David Christopher Reynolds suggests here.而不是大卫克里斯托弗雷诺兹在这里建议的继承。 I would instead consider using composition instead.相反,我会考虑使用组合来代替。 This way you don't accidentally end up creating this "God"-object of a base class that you start inheriting from everywhere.这样你就不会意外地创建一个你开始从任何地方继承的基类的“上帝”对象。

Instead, make a strategy:相反,制定一个策略:

public interface INavigationStrategy
{
    void Navigate(int selectedItem);
}

public class BottomBarNavigationStrategy : INavigationStrategy
{
    private Context _context;

    public BottomBarNavigationStrategy(Context context)
    {
        _context = context;
    }

    public void Navigate(int selectedItem)
    {
        switch(selectedItem)
        {
            case Resource.Id.navigationBarMain:
                _context.StartActivity(typeof(MainActivity));
                break;
            case Resource.Id.navigationBarHistory:
                _context.StartActivity(typeof(HistoryActivity));
                break;
            case Resource.Id.navigationBarSettings:
                _context.StartActivity(typeof(SettingsActivity));
                break;
        }
    }
}

Then you can use it in your code like:然后你可以在你的代码中使用它,比如:

var navigationStrategy = new BottomBarNavicationStrategy(this);
bottomNavigationBar.NavigationItemSelected += OnItemSelected;

void OnItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e)
{
    navigationStrategy.Navigate(this, e.Item.ItemId);
}

This way you can easily share code across classes, without inheritance and limiting yourself to using a Base class for everything.通过这种方式,您可以轻松地跨类共享代码,而无需继承并限制自己对所有内容使用基类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 单击按钮时从 MainActivity 启动不同的活动 - Starting different activities from MainActivity on button click Azure持久功能。 编排产生了许多不需要的活动 - Azure Durable function. orchestration spawns many unwanted activities Enumerable.SortBy-使用哪种排序功能? - Enumerable.SortBy - Which sorting function is used? 查找使用哪个函数分配变量(通过分配的变量) - Finding which function was used to assign the variable (Through variable which is assigned) 在函数中启动新任务会导致程序崩溃? - Starting a new task inside a function can crash a program? 在 .NET 中启动/运行/调用任务时默认使用哪个任务调度程序? - Which task scheduler is used by default when starting/running/invoking tasks in .NET? 如何处理在工人中以不同时间间隔重复的许多独立任务? - How to handle many independent tasks which are repeated at different intervals in a worker? 重构树控制器,可与许多不同类型一起使用 - Refactor tree controller which works with many different types 无法从异步功能启动新的Intent活动 - Can not start new Intent activity from async function 如何模拟在单元测试功能中使用的SmtpClient对象 - how to mock the SmtpClient object which is used inside a function for Unit Testing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM