2010-06-28 6 views
3

TabActivity와이 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; 
     } 
} 

답변

2

잘 보인다. 몇 노트 :
- 동기화 할 이유가 없습니다.
- 나는

if(ChildActivity.s_childActivity != null){ 
    ChildActivity.s_childActivity.changeUI(); 
} 

또는 추가 편집증 환자 안전을위한 심지어

try{ 
    ChildActivity.s_childActivity.changeUI(); 
} catch(Exception e){ 
    //log 
} 

ChildActivity.s_childActivity.changeUI(); 

을 대체 할 것입니다. :)

+0

알겠습니다. 그들은 같은 스레드에 있습니다. 내가 선호하는 경우 (ChildActivity.s_childActivity! = null) { ChildActivity.s_childActivity.changeUI(); } 감사합니다. – user256239

1

디자인 문제의 몇 가지가 있지만 전반적으로 합리적인 것으로 보입니다.

ChildActivity 클래스의 정적 인스턴스는 사용하지 않습니다. 왜? 모델링하는 관계에 대해 생각해보십시오. TabActivityChildActivity입니다. 이 교과서 구성이기 때문에처럼 TabActivity 클래스에 ChildActivity 필드를 추가하여 수행 할 것이다 : A)가 지금은 TabActivity와 ChildActivity의 여러 인스턴스를 가질 수 있기 때문에,

public class TabActivity { 

    private ChildActivity child; 

    //remember to initialize child in onCreate 

    //then, call methods using child.changeUI();, for example 

} 

이 더 나은입니다하지 않습니다 (이전에는 정적 변수 였기 때문에 하나의 ChildActivity 만 사용할 수있었습니다.) B) ChildActivity는 TabActivity 클래스 내에 캡슐화되었습니다. 이전에는 공용 필드 였으므로 아무 것도 사용할 수없고 다른 클래스가 예기치 않은 방식으로 액세스하는 것을 원하지 않기 때문에 개인 필드로 변경했습니다. (바람직하지 않을 수도 있으며, 종종 이상한 런타임 버그와 지저분한 묶인 코드로 이어질 수 있습니다.)

ChildActivity에서 액세스해야 할 필요가있는 것은 부모 (TabActivity)뿐입니다. 당신이 방금 전화 아이의 부모 TabActivity에 액세스해야하는 경우, 그래서

public class ChildActivity ...{ 

private TabActivity parent; 

public void registerParent(TabActivity newParent){ 
    if (newParent != null){ 
     parent = newParent; 
    } 
} 
} 

:이 작업을 수행하려면 ChildActivity을 구성 후 registerParent() 메서드를 ChildActivity 클래스에 다음 메소드와 필드를 추가하고, 전화 parent.someMethod();

getters 및 setters를 통해 parentchild과 같은 필드에 액세스하는 것이 좋습니다. 장기간에 걸쳐 시간을 절약 할 수 있습니다.TabActivity는 ActivityGroup이기 때문에

+0

이와 같이 탭을 만들면 어떻게 활동을합니까? 'setHand.addTab (tabHost.newTabSpec ("foo") .setIndicator (indicator1) .setContent (새로운 의도 (this, Foo.class))); –

+2

Android가 이미 우리에게 Activity.getParent 당신이 하나에 포함 된 경우 정확히 부모 TabActivity, 그래서 이것의 아무도 필요하지 않습니다. –

7

, 나는 다음 중 하나를 사용합니다 :

  • getCurrentActivity()를

가 하위 탭 활동을 반환 표시된다. 귀하의 경우,이 메서드는 사용중인 ChildActivity의 인스턴스를 반환합니다.

ChildActivity childActivity = (ChildActivity) getCurrentActivity(); 
  • 는 getLocalActivityManager(). getActivity (문자열)

하위 탭 활동이 표시되는 어떤 활동의 ID/탭 사양의 이름을 주어 돌려줍니다.

ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1"); 

나는 당신의 ChildActivity에 최우선 onNewIntent (의도)를 제안한다

Intent intent = new Intent(); 
intent.putExtra("xyz", "whatever"); // or a serializable 

ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1"); 
childActivity.onNewIntent(intent); 

날 작동하는지 알아 보자!

2

ChildActivity childActivity = (ChildActivity) getLocalActivityManager().getActivity("Tab 1"); 
childActivity.onNewIntent(intent); 

와 위의 방법은 아주 좋은하지 않습니다. 대신 직접 활동 방법을 호출하는 (널 (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); 
1

이 중 하나를 수행 할 필요성을 미연에 방지의 getParent()를 사용할 수 있습니다. 마법처럼

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; 

    } 

} 

} 

작품 :

다음은 tabHost에 의해 처리 활동 사이에서 전환 버튼을 사용하여 내 런처 자식 클래스입니다.

관련 문제