2012-02-03 65 views
0

我有一個片段視圖,需要用另一個片段替換。片段錯誤 - ListFragment不能轉換爲android.app.Activity

當選擇ListFragment項目時,DetailsFragment將被替換爲另一個ListFragment,方法是將其他事件傳遞給活動中新的(或第二個)ListFragment。我的問題是,我得到了「未發現處理意圖{(有額外)}」的活動。當活動首次啓動時,ListFragment可以正常工作,但是當我使用另一個ListFragment進行日期(替換)Details活動時,出現錯誤。

這是我的第一個片段活動,我猜我不知道如何正確傳遞片段之間的其他東西。我肯定沒有正確使用fragment-manager/transaction類(?)。如果有人能糾正我的執行情況,我將不勝感激。

更新:我添加了「i.setClass(getActivity(),ListFragment.class);」在ListFragment類的意圖,現在日誌錯誤已更改爲以下幾點:

UPDTATE 2:我糾正了我的意圖,以參數作爲Devunwired sugested,現在工作得漂亮。 Thnx Devunwired。我現在唯一的問題是,當後退鍵被按下時,後臺堆棧不起作用。校正類如下:

logcat的(修訂版)

 FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.andaero.test/com.andaero.test.fragments.ListFragment}: java.lang.ClassCastException: com.andaero.test.fragments.ListFragment cannot be cast to android.app.Activity 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1739) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831) 
    at android.app.ActivityThread.access$500(ActivityThread.java:122) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:132) 
    at android.app.ActivityThread.main(ActivityThread.java:4123) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:491) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.ClassCastException: com.andaero.test.fragments.ListFragment cannot be cast to android.app.Activity 

的ListFragment類:

public class ListFragment extends android.app.ListFragment { 

    boolean mDualPane; 
    int mCurCheckPosition = 0; 
    protected TextView activityTitle; 

    boolean mExternalStorageAvailable = false; 
    boolean mExternalStorageWriteable = false; 

    String extStorageDirectory = Environment.getExternalStorageDirectory() 
      .toString(); 
    File dbfile = new File(extStorageDirectory + "/Andaero/dB/Andaero.db"); 
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null); 

    private static final String QUERY_KEY = "QUERY_KEY"; 
    private static final String QUERY_ORDER = "QUERY_ORDER"; 

    private View layout; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     layout = inflater.inflate(R.layout.listview, null); 
     return layout; 

    } 

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

     Bundle extras = getActivity().getIntent().getExtras(); 
     Bundle arg = this.getArguments();//**ADDED TO GET THE ARGS 

     /** 
     * Get the query string from last activity and pass it to this 
     * activity----------------------------------------------------- 
     */ 
     String q = null; 
     if (extras != null) { 
      q = extras.getString(QUERY_KEY); 
     } 

     if (arg != null) { 
     q = (String) (getArguments() != null ? getArguments().getString(
       "QUERY_KEY") : 1); 
    } 

     loadQuery(q); 
    } 

    public void loadQuery(String q) { 

     if (Environment.getExternalStorageState().equals(
       Environment.MEDIA_MOUNTED)) { 

      String qO = getActivity().getIntent().getStringExtra("QUERY_ORDER"); 
      Cursor c = db.rawQuery(q + " ORDER BY `_id` " + qO, null); 
      setListAdapter(new QueryAdapter(getActivity(), c)); 
      db.close(); 

     } else { 
      Alerts.sdCardMissing(getActivity()); 
     } 
    } 

    public class QueryAdapter extends CursorAdapter { 

     public QueryAdapter(Context context, Cursor c) { 
      super(context, c); 
      LayoutInflater.from(context); 
     } 

     @Override 
     public void bindView(View v, Context context, final Cursor c) { 

      int tvLabel = c.getColumnIndexOrThrow("label"); 
      String label = c.getString(tvLabel); 
      final TextView labelTxt = (TextView) v.findViewById(R.id.label); 

      if (labelTxt != null) { 
       labelTxt.setText("(" + label + ")"); 
      } 

      int tvTitle = c.getColumnIndexOrThrow("title"); 
      final String title = c.getString(tvTitle); 
      TextView titleTxt = (TextView) v.findViewById(R.id.listTitle); 

      if (titleTxt != null) { 
       titleTxt.setText(title); 
      } 

      int tvDescription = c.getColumnIndexOrThrow("description"); 
      String description = c.getString(tvDescription); 
      TextView descriptionTxt = (TextView) v.findViewById(R.id.caption); 

      if (descriptionTxt != null) { 
       descriptionTxt.setText(description); 
      } 

      int tvDate = c.getColumnIndexOrThrow("date"); 
      String date = c.getString(tvDate); 
      TextView dateTxt = (TextView) v.findViewById(R.id.dateAdded); 

      if (dateTxt != null) { 
       dateTxt.setText(date); 
      } 

      int tvGoto = c.getColumnIndexOrThrow("gotoURL"); 
      final String gotoURL = c.getString(tvGoto); 
      TextView gotoTxt = (TextView) v.findViewById(R.id.dummy); 

      if (gotoTxt != null) { 
       gotoTxt.setText(gotoURL); 
      } 

      gotoTxt.setVisibility(View.GONE); 
      v.setTag(gotoURL); 

      final ListView lv = getListView(); 
      lv.setEnabled(true); 
      lv.setClickable(true); 

      lv.setOnItemClickListener(new OnItemClickListener() { 

       public void onItemClick(AdapterView<?> arg0, View v, int arg2, 
         long arg3) { 

        // Create new fragment and transaction 
        Fragment newFragment = new ListFragment(); 
        FragmentTransaction transaction = getFragmentManager() 
          .beginTransaction(); 

        // Replace whatever is in the fragment_container view with 
        // this fragment, 
        // and add the transaction to the back stack 
        transaction.replace(R.id.detailFragment, newFragment); 
        transaction.addToBackStack(null); 

        String url = ""; 
        url = (String) v.getTag(); 

        int nI = c.getColumnIndexOrThrow("intent"); 
        String intent = c.getString(nI); 
        Class<?> myIntent = null; 
        try { 
         myIntent = Class.forName("com.andaero.test.fragments" 
           + intent); 
        } catch (ClassNotFoundException e) { 
         Log.e("ERROR", "Class Not Found for new intent!"); 
         e.printStackTrace(); 
        } 

        int tvTitle = c.getColumnIndexOrThrow("title"); 
        String title = c.getString(tvTitle); 

        int tvLabel = c.getColumnIndexOrThrow("label"); 
        String label = c.getString(tvLabel); 

        String queryKey = "SELECT * FROM " + label; 
        c.close(); 
        db.close(); 

        Bundle args = new Bundle();//**REPLACED THE INTENTS 
        args.putString("QUERY_KEY", queryKey); 
        args.putString("KEY_URL", url); 
        args.putString("KEY_SUBTITLE", title); 
        args.putString("KEY_LABEL", label); 
        args.putString("KEY_INTENT", intent); 
        args.putString("QUERY_ORDER", "ASC"); 

        newFragment.setArguments(args); 

        // Commit the transaction 
        transaction.commit(); 
       } 
      }); 
     } 

     @Override 
     public View newView(Context context, Cursor cursor, ViewGroup parent) { 
      final View v = LayoutInflater.from(context).inflate(
        R.layout.list_item, parent, false); 
      return v; 
     } 
    } 
} 

回答

0

你是在正確的軌道上使用FragmentTransaction更換一次Fragment與其他的東西,但Fragment不使用Intent從一個實例的數據傳遞到另一個像Activity確實。事實上,撥打startActivity()Intent指向Fragment將導致你不想要的各種煙花(如你所見過的)。

在構造函數中將數據傳遞給新的Fragment是完全可以的,因此您可以爲您的ListFragment創建一個構造函數,該構造函數接受要轉發的任何數據參數。另一種選擇是將所有「額外」設置爲新的Fragment上的參數,方法是將它們放入Bundle並使用Fragment.setArguments()。只要您想訪問您附加到Fragment的參數,您只需撥打即可獲取相同的Bundle。此外

Bundle args = new Bundle(); 
args.putString("QUERY_KEY", queryKey); 
//...add all the extras to the bundle 

newFragment.setArguments(args); 

transaction.commit(); 

,偏離主題,但你可能想使你不給你Fragment重命名爲別的東西:所以基本上,替換所有具有帶有Intent做的代碼在你的onItemClick()方法,而是不得不依賴完全限定的軟件包名稱來區分ListFragment和代碼中的平臺版本。

HTH

+0

Thnx在這方面有幫助。我現在沒有得到錯誤,並且活動加載了,但是它所做的只是重新加載當前存在的數據:它不會將新數據加載到列表中,就像當類設置了w/o片段時一樣。任何更多的幫助/指針。 Thnx – CelticParser 2012-02-06 21:38:35

+0

再次thnx幫助與此。你可以看看我的改變,看看是否有更好的方法來實現我的參數,並且你是否明白爲什麼我的後退堆棧不能使用後退鍵? – CelticParser 2012-02-07 00:17:08

+0

我沒有看到任何明顯的後退動作不起作用。該事務正被添加到後退堆棧,因此點擊後退按鈕應該將最後一個事務彈出到其先前的狀態。你是否在你的Activity中覆蓋了'onBackPressed()'而不調用'super'或其他會影響標準回退行爲的東西? – Devunwired 2012-02-07 15:05:17

0

你爲什麼不只是創建您傳遞的價值觀進入,當你一個構造函數創建片段?這似乎是你正在尋找做

+0

因爲它不好使用片段中的構造函數。你總是需要默認的構造函數(空),或者它會在恢復時破壞... – Warpzit 2012-06-15 10:22:22

相關問題