2013-04-30 58 views
0

以下是我的應用程序的範圍:無法啓動活動ComponentInfo - 我如何解決?

我正在嘗試使用ViewPager和Fragment編寫應用程序。 應用程序的佈局有2個選項卡(主頁/配置)。 其中一個選項卡的片段可以更改爲另一個。例如: * FragmentHome(在TabHome中)被FragmentGraphics替換。用戶按下按鈕,FragmentHome將再次顯示。

問題(1):應用程序在打開之前崩潰並關閉。我不知道可能發生了什麼。 問題(2):如何在視圖尋呼機中用另一個替換片段? (FragmentHome中的button1ClickListener)?

希望有所幫助!

的代碼:

ActivityMain.java

import java.util.List; 
import java.util.Vector; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.view.ViewPager; 
import android.widget.TabHost; 
import android.widget.TabHost.TabSpec; 

public class ActivityMain extends FragmentActivity { 

    private TabHost mTabHost; 
    private PagerAdapter mPagerAdapter; 
    private ViewPager mViewPager; 

    List<Fragment> fragments = new Vector<Fragment>(); 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
    } 

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

     setContentView(R.layout.main); 

     this.setLayout(savedInstanceState); 

    } 

    @Override 
    public void onBackPressed() { 
     if(!mPagerAdapter.back(getSupportFragmentManager())) { 
     super.onBackPressed(); 
     } 
    }  

    public void setLayout(Bundle args){ 

     this.mViewPager = (ViewPager)findViewById(R.id.viewpager); 

     this.mTabHost = (TabHost)findViewById(android.R.id.tabhost);  

     //HomeTab 
     TabSpec tabSpecHome = mTabHost.newTabSpec(getResources().getString(R.string.tab_home_name)); 
     tabSpecHome.setIndicator(getResources().getString(R.string.tab_home_label)); 

     //ConfigTab 
     TabSpec tabSpecConfig = mTabHost.newTabSpec(getResources().getString(R.string.tab_config_name)); 
     tabSpecConfig.setIndicator(getResources().getString(R.string.tab_config_label)); 

     this.mPagerAdapter = new PagerAdapter(this, this.mTabHost,this.mViewPager); 

     //HomeTab 
     this.mPagerAdapter.addTab(tabSpecHome, FragmentHome.class, args); 
     this.mPagerAdapter.addFragment(getSupportFragmentManager(), getResources().getString(R.string.tab_home_name), FragmentHome.class, null); 

     //ConfigTab 
     this.mPagerAdapter.addTab(tabSpecConfig, FragmentConfig.class, args); 
     this.mPagerAdapter.addFragment(getSupportFragmentManager(), getResources().getString(R.string.tab_config_name), FragmentConfig.class, null); 

    } 
} 

PagerAdapter.java

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Stack; 

import android.content.Context; 
import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentTransaction; 
import android.support.v4.view.ViewPager; 
import android.view.ViewGroup; 
import android.widget.TabHost; 
import android.widget.TabHost.TabSpec; 
import android.widget.TabWidget; 

public class PagerAdapter extends FragmentPagerAdapter { 

    private final Context mContext; 
    private final TabHost mTabHost; 
    private final ViewPager mViewPager; 

    private ArrayList<String> mTabTags = new ArrayList<String>(); 
    private HashMap<String, Stack<TabInfo>> mTabStackMap = new HashMap<String, Stack<TabInfo>>(); 

    public interface SaveStateBundle{ 
     public Bundle onRemoveFragment(Bundle outState); 
    } 

    public PagerAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager){ 

     super(activity.getSupportFragmentManager()); 
     this.mContext = activity; 

     this.mTabHost = tabHost; 
     this.mTabHost.setOnTabChangedListener(tabChangeListener); 

     this.mViewPager = pager; 
     this.mViewPager.setAdapter(this); 
     this.mViewPager.setOnPageChangeListener(viewPagerChangeListener); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     Stack<TabInfo> tabStack = mTabStackMap.get(mTabTags.get(position)); 
     TabInfo info = tabStack.peek(); 
     return Fragment.instantiate(mContext, info.getClass().getName(), info.getArgs()); 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     ArrayList<Class<?>> positionNoneHack = new ArrayList<Class<?>>(); 

     for(Stack<TabInfo> tabStack: mTabStackMap.values()){ 
      positionNoneHack.add(tabStack.peek().getClass()); 
     } 

     if(positionNoneHack.contains(object.getClass())){ 
      return POSITION_UNCHANGED; 
     } 

     return POSITION_NONE; 
    } 

    public void addTab(TabSpec tabSpec, Class<?> clss, Bundle args){ 

     try{ 

      this.mTabHost.setup(); 

      Stack<TabInfo> tabStack = new Stack<TabInfo>(); 

      tabSpec.setContent(new TabContent(this.mContext)); 
      this.mTabHost.addTab(tabSpec); 
      String tag = tabSpec.getTag(); 
      TabInfo info = new TabInfo(tag, clss, args); 

      this.mTabTags.add(tag); 
      tabStack.add(info); 
      this.mTabStackMap.put(tag, tabStack); 
      notifyDataSetChanged(); 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
    }  

    public void addFragment(FragmentManager fm, String _tag, Class<?> _class, Bundle _args){ 

     try{ 

      TabInfo info = new TabInfo(_tag, _class, _args); 
      Stack<TabInfo> tabStack = mTabStackMap.get(_tag); 

      Fragment frag = fm.findFragmentByTag("android:switcher:" + mViewPager.getId() + ":" + mTabTags.indexOf(_tag)); 
      if(frag instanceof SaveStateBundle){ 
       Bundle b = new Bundle(); 
       ((SaveStateBundle) frag).onRemoveFragment(b); 
       tabStack.peek().setArgs(b); 
      } 
      tabStack.add(info); 

      FragmentTransaction ft = fm.beginTransaction(); 

      ft.remove(frag); 

      ft.addToBackStack(null); 

      ft.commit(); 

      notifyDataSetChanged(); 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
    } 

    public boolean popFragment(FragmentManager fm, String _tag){ 
     Stack<TabInfo> tabStack = mTabStackMap.get(_tag); 
     if(tabStack.size()>1){ 
      tabStack.pop(); 
      Fragment frag = fm.findFragmentByTag("android:switcher:" + mViewPager.getId() + ":" + mTabTags.indexOf(_tag)); 

      FragmentTransaction ft = fm.beginTransaction(); 

      ft.remove(frag); 

      ft.addToBackStack(null); 

      ft.commit(); 

      notifyDataSetChanged(); 

      return true; 
     } 
     return false; 
    } 

    public boolean back(FragmentManager fm) { 
     int position = mViewPager.getCurrentItem(); 
     return popFragment(fm, mTabTags.get(position)); 
    } 

    @Override 
    public int getCount() { 
     return mTabStackMap.size(); 
    } 

    @Override 
    public void notifyDataSetChanged(){ 
     super.notifyDataSetChanged(); 
    } 

    private final ViewPager.OnPageChangeListener viewPagerChangeListener = new ViewPager.OnPageChangeListener(){ 

     @Override 
     public void onPageScrollStateChanged(int arg0) { 
      // TODO Auto-generated method stub 
     } 

     @Override 
     public void onPageScrolled(int arg0, float arg1, int arg2) { 
      // TODO Auto-generated method stub 
     } 

     @Override 
     public void onPageSelected(int position) { 
      // TODO Auto-generated method stub 
      TabWidget widget = mTabHost.getTabWidget(); 
      int oldFocusability = widget.getDescendantFocusability(); 
      widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 
      mTabHost.setCurrentTab(position); 
      widget.setDescendantFocusability(oldFocusability); 
     } 
    }; 

    private final TabHost.OnTabChangeListener tabChangeListener = new TabHost.OnTabChangeListener(){ 

     @Override 
     public void onTabChanged(String tabId) { 
      int pos = mTabHost.getCurrentTab(); 
      mViewPager.setCurrentItem(pos);   
     } 

    }; 
} 

TabContent.java

import android.content.Context; 
import android.view.View; 
import android.widget.TabHost.TabContentFactory; 

public class TabContent implements TabContentFactory{ 

    private final Context mContext; 

    public TabContent(Context context){ 
     mContext = context; 
    } 

    @Override 
    public View createTabContent(String tag) { 
     View v = new View(mContext); 
     v.setMinimumWidth(0); 
     v.setMinimumHeight(0);   
     return v; 
    } 
} 

TabInfo.java

import android.os.Bundle; 
import android.support.v4.app.Fragment; 

public class TabInfo { 

    private String tag; 
    private Class<?> clss; 
    private Bundle args; 
    private Fragment fragment; 

    public TabInfo(String tag, Class<?> clazz, Bundle args) { 
     this.tag = tag; 
     this.clss = clazz; 
     this.args = args; 
    } 

    public void setTag(String tag){ 
     this.tag = tag; 
    } 

    public String getTag(){ 
     return this.tag; 
    } 

    public void setClazz(Class<?> clzz){ 
     this.clss = clzz; 
    } 

    public Class<?> getClazz(){ 
     return this.clss; 
    } 

    public void setArgs(Bundle args){ 
     this.args = args; 
    } 

    public Bundle getArgs(){ 
     return this.args; 
    } 

    public Fragment getFragment(){ 
     return this.fragment; 
    } 

} 

FragmentHome.java

import android.support.v4.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 

public class FragmentHome extends Fragment{ 

    Button button1; 
    View view; 

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

     if(container == null){ 
      return null; 
     } 

     this.view = inflater.inflate(R.layout.home, container, false); 

     this.setItens(); 

     return this.view; 
    } 

    private void setItens(){ 

     button1 = (Button)this.view.findViewById(R.id.button1); 
     button1.setOnClickListener(button1OnClickListener); 
    } 

    private final View.OnClickListener button1OnClickListener = new View.OnClickListener(){ 

     public void onClick(View v) { 
      showFragmentGraphics(); 
     } 
    }; 

    public void showFragmentGraphics(){ 
     //the code for replace fragment home 
    } 

} 

清單

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="br.com.my.app" 
    android:versionCode="1" 
    android:versionName="1.0.0" 
    android:installLocation="internalOnly"> 

    <uses-sdk 
     android:minSdkVersion="7" 
     android:targetSdkVersion="17" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 

     <activity 
      android:name=".ActivityMain" 
      android:screenOrientation="portrait" 
      android:configChanges="keyboardHidden|orientation"> 
      <intent-filter android:label="@string/app_name"> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity>   

    </application> 

</manifest> 

現在,錯誤日誌

04-30 18:56:19.591: E/AndroidRuntime(1275): FATAL EXCEPTION: main 
04-30 18:56:19.591: E/AndroidRuntime(1275): java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.my.app/br.com.my.app.ActivityMain}: java.lang.NullPointerException 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.os.Handler.dispatchMessage(Handler.java:99) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.os.Looper.loop(Looper.java:123) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at java.lang.reflect.Method.invoke(Method.java:507) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at dalvik.system.NativeStart.main(Native Method) 
04-30 18:56:19.591: E/AndroidRuntime(1275): Caused by: java.lang.NullPointerException 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:651) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:551) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.Activity.performStart(Activity.java:3791) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1620) 
04-30 18:56:19.591: E/AndroidRuntime(1275):  ... 11 more 

回答

0

對於第一個問題,你可以嘗試從

改變3210
this.mTabHost = (TabHost)findViewById(android.R.id.tabhost); 

this.mTabHost = (TabHost)findViewById(R.id.tabhost); 

對於第二個問題,你可以檢查Replace Fragment inside a ViewPager

說實話,你的代碼和你的設計很混亂。你應該花一些時間閱讀關於ViewPager和Tab。

+0

。我遵循了引用第二個問題的那個頁面上的示例。我所做的是將工作人員內部放置的一些類(靜態類)分離到FragmentPagerAdapter中。只有這樣。沒有biggie.Problem 1我發現了問題。還有2'm仍在研究如何解決。 – Ludiaz 2013-04-30 20:40:32

+0

@Ludiaz沒有冒犯。我感到困惑的部分是「用戶按下按鈕後,FragmentHome將再次顯示。」你在同一個標​​籤中是否有2個片段? – pt2121 2013-04-30 20:44:06

+0

無論如何,很高興聽到你已經修復了第一部分。 – pt2121 2013-04-30 20:45:40

相關問題