java – 强制选项卡内容在异步任务完成后更新

我有一个带有3个标签的TabActivity.有一个异步任务,当通过单击菜单项进行刷新运行时,从服务器检索更新的数据.此数据存储在控制器中,并由所有视图访问,因此模型只需加载一次.

我的问题是,在异步活动运行并更新模型后,如何通知所有三个选项卡以更新其内容?

我的活动

public class DashboardActivity extends TabActivity {
    private ProfileModel profile;
    private TabHost tabHost;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        profile = Controller.getProfile();

        this.setContentView(R.layout.dashboard);

        tabHost = getTabHost();
        setupTab(new TextView(this), "Home", new Intent().setClass(DashboardActivity.this, HomeActivity.class));
        setupTab(new TextView(this), "History", new Intent().setClass(DashboardActivity.this, PaymentsActivity.class));
        setupTab(new TextView(this), "My Wallet", new Intent().setClass(DashboardActivity.this, MyWalletActivity.class));

        tabHost.setCurrentTab(0);

        ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);
        actionBar.setTitle(profile.Name);

    }

    private void setupTab(final View view, final String tag, Intent content) {
        View tabview = createTabView(tabHost.getContext(), tag);
            TabSpec setContent = tabHost.newTabSpec(tag)
                .setIndicator(tabview)
                .setContent(content);
            tabHost.addTab(setContent);
    }

    private static View createTabView(final Context context, final String text) {
        View view = LayoutInflater.from(context).inflate(R.layout.tabs_bg, null);
        TextView tv = (TextView) view.findViewById(R.id.tabsText);
        tv.setText(text);
        return view;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mainmenu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.menu_settings:

            return true;
        case R.id.menu_refresh:
            new RefreshDashboardTask().execute();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }


    private class RefreshDashboardTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute()
        {
            ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);

            if(actionBar != null)
                actionBar.setProgressBarVisibility(View.VISIBLE);
        }

        @Override
        protected Void doInBackground(Void... params) 
        {
            try {
                profile = DataHelper.getProfile();
                Controller.setProfile(profile);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (HttpException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ServerException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result)
        {
            ActionBar actionBar = (ActionBar)findViewById(R.id.actionbar);

            if(actionBar != null)
                actionBar.setProgressBarVisibility(View.GONE);
        }
    }
}

编辑为了进一步详细说明,这里有一些代码.

我的控制器

public class Controller extends Application {
    private static Controller instance;
    private static DefaultHttpClient client;
    private static ProfileModel profile;

    public Controller() {
        instance = this;
        client = new DefaultHttpClient();
        profile = null;
    }

    public static Context getContext() {
        return instance;
    }

    public static DefaultHttpClient getHttpContext() {
        return client;
    }

    public static ProfileModel getProfile() {
        return profile;
    }

    public static void setProfile(ProfileModel profile) {
        Controller.profile = profile;
    }

    @Override
    public void onCreate() 
    {
        super.onCreate();

    }
}

我在标签视图中的一个活动.这个是最简单的一个,因为它只是一个列表.主视图是2个列表,由标题分隔,钱包视图是动态生成的带有标题的列表,从集合中的集合创建.

public class PaymentsActivity extends Activity {
    ProfileModel profile;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.setContentView(R.layout.payment_history);

        profile = Controller.getProfile();

        ListView itemList = (ListView)this.findViewById(R.id.payment_history_list);
        itemList.setTextFilterEnabled(true);
        itemList.clearChoices();
        itemList.setAdapter(new ItemSummaryAdapter(PaymentsActivity.this, R.layout.list_item_payment, profile.Items));
        //statementList.setOnItemClickListener(clickListener);
    }
}

这里的目标是刷新按钮更新控制器中的数据.选项卡内的所有视图都会更新.

解决方法:

更新:

如果我是你,我会Observer pattern.首先,为Controller类添加一组监听器:

public class Controller extends Application {
    private static Controller instance;
    private static DefaultHttpClient client;
    private static ProfileModel profile;
    private static Set<ControllerUpdateListener> updateListeners = new HashSet<ControllerUpdateListener>();

    //...

    public static void addListener(ControllerUpdateListener listener)
    {
        updateListeners.add(listener);
    }

    public static interface ControllerUpdateListener {
        void onControllerUpdate(ProfileModel model);
    }
}

然后让您的各个标签活动实现ControllerUpdateListener.最后,将触发器添加到Controller类:

public static void setProfile(ProfileModel profile) {
    Controller.profile = profile;

    for(ControllerUpdateListener l : updateListeners) {
        l.onControllerUpdate(profile);
    }
}

不要忘记将每个活动注册为Controller的监听器:

public class PaymentsActivity extends Activity implements Controller.ControllerUpdateListener {
    ProfileModel profile;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.setContentView(R.layout.payment_history);

        Controller.addListener(this); // <-- Don't forget this...
        profile = Controller.getProfile();

        ListView itemList = (ListView)this.findViewById(R.id.payment_history_list);
        itemList.setTextFilterEnabled(true);
        itemList.clearChoices();
        itemList.setAdapter(new ItemSummaryAdapter(PaymentsActivity.this, R.layout.list_item_payment, profile.Items));
        //statementList.setOnItemClickListener(clickListener);
    }

    public void onControllerUpdate(ProfileModel model) {
        //update these views...
    }
}

现在,每个单独的选项卡活动都应该在onControllerUpdate(ProfileModel)方法中触发其notifyDataSetChanged()(或其他任何触发其更新的方法).

上一篇:ng6中ngModelChange如何获取change前ngModel绑定的值


下一篇:spring集成hbase