마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

actionbar tab 도와주세요

0 추천

actionbar 를 이용하여 4개의 tab을 구현하였습니다. 그리고 하나의 tab안에서 검색버튼을 누르면 새로운 fragment 가 뜨면서 검색한 대상의 정보가 나옵니다. 여기서 에러가 납니다. 새로운 fragment 가 뜬 상태에서 다른 tab클릭시 앱이 죽어버립니다.                                       Error : java.lang.IllegalArgumentException: No view found for id 0x7f070052 (org.jsb.busgod.busgod:id/pager) for fragment BusStop{42a68a00 #7 id=0x7f070052 BusStop} 라도 뜹니다.

MainActivity.class

public class MainActivity extends ActionBarActivity implements LineNumber.InfoListener 
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Log.d(TAG,"MainActivity onCreate Called.");

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new TabViewPager()).commit();
        }

  @Override
    public void searchInfo(String busRouteId,String busRouteNm, String routeType, String stStationNm, String edStationNm, String term, String lastBusTm, String firstBusTm) {
     
        if(busRouteId.length() != 0 && busRouteNm.length() != 0 && routeType.length() != 0 && stStationNm.length() != 0 && edStationNm.length() != 0 && term.length() != 0 && lastBusTm.length() != 0 && firstBusTm.length() != 0) {

            InfoFragment infoFragment = new InfoFragment();

            /생략/

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.container, infoFragment);
            ft.addToBackStack(null);
            ft.commit();
            
        } else {
            Toast.makeText(MainActivity.this,"검색 결과가 없습니다.", Toast.LENGTH_SHORT).show();
        }
    }

activity_main.xml

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container"
xmlns:android="http://schemas.android.com/apk/res/android">
</FrameLayout>

TabViewPager.class

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


        Log.d(TAG,"TabViewPager onCreate Called.");

    if(view == null) {
        view = inflater.inflate(R.layout.tabpager,container,false);
        mActionBar = ((ActionBarActivity) activity).getSupportActionBar();
        mActionBar.setIcon(new ColorDrawable(Color.TRANSPARENT));
        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        mActionBar.setDisplayShowTitleEnabled(true);

        mTabPagerAdapter = new ActionBarTabPagerAdapter(((ActionBarActivity) activity).getSupportFragmentManager());
        mPager = (ViewPager) view.findViewById(R.id.pager);
        mPager.setAdapter(mTabPagerAdapter);

        mPager.setOnPageChangeListener(new PagerListener());
        // 1
        bmTab = mActionBar.newTab();
        bmTab.setText("즐겨찾기");
        bmTab.setTabListener(new TabListener<BookMark>(activity, "BookMark", BookMark.class));
        mActionBar.addTab(bmTab);
        //2
        lnTab = mActionBar.newTab();
        lnTab.setText("노선번호");
        lnTab.setTabListener(new TabListener<LineNumber>(activity, "LineNumber", LineNumber.class));
        mActionBar.addTab(lnTab);
        //3
        bsTab = mActionBar.newTab();
        bsTab.setText("정류소");
        bsTab.setTabListener(new TabListener<BusStop>(activity, "BusStop", BusStop.class));
        mActionBar.addTab(bsTab);
        //4
        nbsTab = mActionBar.newTab();
        nbsTab.setText("주변정류소");
        nbsTab.setTabListener(new TabListener<NearbyBusStop>(activity, "NearbyBusStop", NearbyBusStop.class));
        mActionBar.addTab(nbsTab);

    } else {
        ((ViewGroup)view.getParent()).removeView(view);
    }

        if (savedInstanceState != null) {
            mActionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
        }

        return view;
    }

     /생략/


    //TabListener
    private class TabListener <T> implements ActionBar.TabListener{
        private Activity mActivity;
        private String mTag;
        private Class<T> mClass;
        private Bundle mBundle;
        private Fragment mFragment;

        public TabListener(Activity mActivity, String mTag, Class<T> mClass){
            this(mActivity,mTag,mClass,null);
        }

        public TabListener(Activity mActivity,String mTag, Class<T> mClass, Bundle mBundle){
            super();
            this.mActivity = mActivity;
            this.mTag = mTag;
            this.mClass = mClass;
            this.mBundle = mBundle;

            FragmentManager fm = ((ActionBarActivity)activity).getSupportFragmentManager();
            mFragment = fm.findFragmentByTag(mTag);

            if(mFragment != null && !mFragment.isDetached()){
                FragmentTransaction ft = ((ActionBarActivity)activity).getSupportFragmentManager().beginTransaction();
                ft.detach(mFragment);
                ft.commit();
            }
        }
        @Override
        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
            Log.d(TAG, "onTabSelected() Called.");
            int position = tab.getPosition();

          /생략/

            if(mFragment == null){
                mFragment = Fragment.instantiate(mActivity,mClass.getName(),mBundle);
                fragmentTransaction.add(R.id.pager,mFragment,mTag);

            }else{
                fragmentTransaction.attach(mFragment);
            }
            mPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
            Log.d(TAG,"onTabUnselected() Called.");
            if(mFragment != null){
                fragmentTransaction.detach(mFragment);
                mFragment = null;
            }
        }
        @Override
        public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
            Log.d(TAG,"onTabReselected() Called.");
        }
    }

LineNumber.class

@Override
    public void onAttach(Activity activity) {
        this.activity = activity;

        try {
            mCallback = (InfoListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "LineNumber onCreateView() Called.");
        View view = inflater.inflate(R.layout.linenumber,container,false);

        LineSearch = (EditText) view.findViewById(R.id.lineSearch);
        view.findViewById(R.id.lineSearchBtn).setOnClickListener(bHandler);

        return view;
    }

InfoFragment.class

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.info,container,false);

메인액티비티 setContent(activity_main.xml) -> TabViewPager -> TabViewPager 의 fragment중 LineNumber 검색버튼 클릭-> InfoFragment 해당 정보 보여 -> 다른 탭 클릭 앱 죽음 

같은 container를 사용해서 죽는걸까요? 도와주세요 ㅠㅠ

우랴 (3,680 포인트) 님이 2014년 6월 5일 질문
우랴님이 2014년 6월 5일 수정

TabViewPager 부분에 뷰가 null이 아니면 remove해버리는데 그거 때문에 그런거 아닌가요...?

저기서 remove를 안해버리면 기기 백버튼클릭시 actionbar tab이 한번더 생성되어버립니다.ㅠㅠ
저기서 remove안하면 오류는 안생기나요?
생깁니다. 그래서 구조를 한번바꿔봤는데요. 지금 TabViewPager가 클래스로 빠져있고 메인엑티비티.xml에 있는 프레임레이아웃에 붙어서 view를 보여주는 구조잖아요. 그리고 InfoFragment 클래스도 프레임레이아웃에 붙어서 보여주고요. 그래서 TabViewPager클래스를 지우고 안에있는 코드를 메인엑티비티 onCreate메서드 안으로 옮겼구요. 메인엑티비티.xml레이아웃에 프레임레이아웃 안에 <viewpager android:id="@+id/xxxx>를 만들어서 탭+viewpager화면은 viewpager에 붙어서 보여주게끔하고 디테일한 정보를 보여주는 프래그먼트들은 프레임레이아웃에 붙어서 보여주게끔 구조를 바꿔봤는데요. 일단 디테일한정보를 보여주는 화면이 보여진상태에서 다른 탭을 클릭시 죽지는 않고 이동은 잘됩니다. 근데 프레임레이아웃이라서 그런지 내용이 겹쳐서보이네요.. 지금 또 다른 난관에 부딪혔습니다.
이렇게 하는것도 아닌것같습니다..
ActionBar로는 tab을 만들어 본 경험이 없어서 죄송하지만 확답을 드리기 어렵군요..
http://coolkim.tistory.com/343
일단 제가 찾은 곳을 이곳인데..왠지 살펴 보셨을 듯하고...죄송합니다 제가 답변을 드리긴 힘드네요ㅎㅎ;; 다른분의 답변을 달기 쉽게 댓글로 변환 시켰습니다~
님께서 죄송하다뇨 전혀 아닙니다. 답변 해주신것만해도 감사드립니다. 알려주신 홈페이지를 참고해 가면서 해결해보도록 해보겠습니다. 다시 한번 감사드립니다.
좋은 하루 보내세요 ^^

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...