我正在尝试找出TabActivity与此TabActivity中嵌入的子活动之间的最佳通信实践。
在我的TabActivity中,有一个按钮。单击该按钮时,我希望更新此TabActivity中嵌入的子活动。我编写了如下代码,只是想知道它是否是一个好习惯。感谢。
MyTabActivity.java
public class MyTabActivity extends TabActivity implements OnClickListener {
private TabHost m_tabHost;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ff_tab_activity);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
m_tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;
intent = new Intent().setClass(this, ChildActivity.class);
spec = m_tabHost.newTabSpec("Tab 1");
spec.setContent(intent);
tabView = (TextView) inflater.inflate(R.layout.tab_indicator, null);
spec.setIndicator(tabView);
m_tabHost.addTab(spec);
m_tabHost.setCurrentTab(0);
ImageView nextButtonIv = (ImageView) findViewById(R.id.next_button);
nextButtonIv.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.next_button:
synchronized (ChildActivity.class) {
if (null != ChildActivity.s_childActivity) {
ChildActivity.s_childActivity.changeUI();
}
}
break;
}
}
ChildActivity.java
public class ChildActivity extends Activity {
public static ChildActivity s_childActivity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
synchronized (MatchupsActivity.class) {
s_childActivity = this;
}
setContentView(R.layout.child_activity);
}
public void changeUi() {
code that changes UI
}
protected void onDestroy() {
super.onDestroy();
synchronized (MatchupsActivity.class) {
s_childActivity = null;
}
}
答案 0 :(得分:7)
由于TabActivity是一个ActivityGroup,我会使用以下之一:
返回显示的子选项卡活动。在您的情况下,此方法将返回正在使用的ChildActivity的实例。
ChildActivity childActivity = (ChildActivity) getCurrentActivity();
返回子选项卡活动,给定其ID /选项卡规范名称,无论显示什么活动。
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
我建议在你的ChildActivity中覆盖onNewIntent(Intent):
Intent intent = new Intent();
intent.putExtra("xyz", "whatever"); // or a serializable
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
childActivity.onNewIntent(intent);
让我知道它是否有效!
答案 1 :(得分:2)
似乎很好。几个笔记:
- 我认为没有理由进行同步
- 我会替换
ChildActivity.s_childActivity.changeUI();
与
if(ChildActivity.s_childActivity != null){
ChildActivity.s_childActivity.changeUI();
}
甚至
try{
ChildActivity.s_childActivity.changeUI();
} catch(Exception e){
//log
}
增加了偏执的安全性。 :)
答案 2 :(得分:2)
上面的方法
ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1");
childActivity.onNewIntent(intent);
不是很好。而不是直接调用你的activity方法(它可以为null !!!),最好这样做:
Intent intent = new Intent(this, ChildActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(AlbumBrowser.INTENT_EXTRA_FILTER, mediaTitle);
getLocalActivityManager().startActivity("activityIdHere", intent);
答案 3 :(得分:1)
设计问题很多,但总的来说似乎是合理的。
我会放弃ChildActivity
类中的静态实例。为什么?好吧,想想你正在建模的关系。 TabActivity
有一个 ChildActivity
。这是教科书组合,可以通过向TabActivity类添加ChildActivity字段来完成,如下所示:
public class TabActivity {
private ChildActivity child;
//remember to initialize child in onCreate
//then, call methods using child.changeUI();, for example
}
这样更好,因为A)现在我可以有多个TabActivity和ChildActivity实例,这些实例不会相互干扰(之前,它只是一个静态变量,因此只能使用一个ChildActivity),以及B) ChildActivity被封装在TabActivity类中...之前,它是一个公共字段,意味着任何东西都可以使用和修改它(可能不是理想的;通常会导致一些奇怪的运行时错误以及混乱,捆绑在一起的代码) - 我们将其更改为私有字段,因为我们并不希望其他类以意外的方式访问它。
您可能需要从ChildActivity访问的唯一内容是父(TabActivity)。为此,将以下方法和字段添加到ChildActivity类,并在构造ChildActivity之后调用registerParent()方法:
public class ChildActivity ...{
private TabActivity parent;
public void registerParent(TabActivity newParent){
if (newParent != null){
parent = newParent;
}
}
}
因此,如果您需要从孩子那里访问父TabActivity
,只需调用parent.someMethod();
通过getter和setter访问parent
和child
等字段也是明智之举;从长远来看,它可能会节省你一些时间。
答案 4 :(得分:1)
您可以使用getParent()来避免执行任何操作。
这是我的启动器子类,其中的按钮可在tabHost处理的活动之间切换:
public class LaunchPadActivity extends Activity implements OnClickListener {
private static final int ICON_PROFILE = 0;
private static final int ICON_SEARCH = 1;
private static final int ICON_MAP = 2;
private static final int FAVOURITES = 3;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.launchpad);
GridView launchPad = (GridView) findViewById(R.id.launchpad);
launchPad.setAdapter(new LaunchIconAdapter(this));
}
public class LaunchIconAdapter extends BaseAdapter {
private Context mContext;
// references to our images
private Integer[] mThumbIds = { R.drawable.user, R.drawable.find,
R.drawable.map, R.drawable.favourites, R.drawable.reviews,
R.drawable.news, R.drawable.tutorial, R.drawable.info,
R.drawable.options, };
public String[] texts = { "Profile", "Search", "Map", "Favourites",
"Reviews", "News", "Tutorial", "Info", "Options" };
public LaunchIconAdapter(Context c) {
mContext = c;
}
// Number of thumbs determines number of GridView items
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
// Icon elements
LinearLayout launchIcon;
ImageView launchImage;
TextView launchText;
if (convertView == null) {
launchIcon = (LinearLayout) ((LayoutInflater) mContext
.getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(
R.layout.launchicon, null);
} else {
launchIcon = (LinearLayout) convertView;
}
// Add ClickListener with metadata
launchIcon.setTag(new Integer(position));
launchIcon.setOnClickListener(LaunchPadActivity.this);
// Get subviews
launchImage = (ImageView) launchIcon
.findViewById(R.id.launch_image);
launchText = (TextView) launchIcon.findViewById(R.id.launch_text);
// Configure subviews
launchImage.setImageResource(mThumbIds[position]);
launchText.setText(texts[position]);
return launchIcon;
}
}
@Override
public void onClick(View v) {
int position = ((Integer) v.getTag()).intValue();
switch (position) {
case ICON_PROFILE:
Toast.makeText(this, "Profile", Toast.LENGTH_LONG).show();
break;
case ICON_SEARCH:
Toast.makeText(this, "Search", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(1);
break;
case ICON_MAP:
Toast.makeText(this, "Map", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(2);
break;
case FAVOURITES:
Toast.makeText(this, "Map", Toast.LENGTH_LONG).show();
((TabActivity) getParent()).getTabHost().setCurrentTab(3);
break;
}
}
}
像魅力一样。