2012-02-03 5 views
0

私は別のフラグメントとの置換が必要なフラグメントビューを持っています。フラグメントエラー - ListFragmentをandroid.app.Activityにキャストできません

ListFragmentアイテムが選択されている場合、DetailsFragmentは、アクティビティ内の新しい(または2番目の)ListFragmentにExtrasを渡すことによって別のListFragmentに置き換えられます。私の問題は、「Intent {(has extra)}」を処理するためのアクティビティが見つかりませんでした。 ListFragmentは、アクティビティが最初に開始されたときに正常に動作しますが、詳細アクティビティを別のListFragmentで更新(置き換え)すると、エラーが発生します。

これは私の最初の断片アクティビティです。フラグメント間にExtrasを正しく渡す方法はわかりません。私はフラグメントマネージャ/トランザクションクラスを適切に使用していないのは確かです(?)。誰かが私の実装を修正することができれば、私はそれを高く評価します。

更新:「i.setClass(getActivity()、ListFragment.class);」を追加しました。

UPDTATE 2:ListFragmentクラスの意図となりましログのエラーは次のように変更しているに Devunwiredが推薦して私は、引数に自分の意図を修正し、それは今だけで美しく動作します。 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

を行うために探しているものであるようだが、Activityのように別のインスタンスからのデータを渡すためにIntentFragment使用していませんそうです。実際には、に指し示されたIntentを持つstartActivity()を呼び出すと、あなたが見たことがないようなあらゆる種類の花火が発生します。

コンストラクタ内の新しいFragmentにデータを渡すことは大丈夫ですので、転送するデータのパラメータを取るコンストラクタをListFragmentに作成することができます。もう一つの選択肢は、新しいFragmentBundleに入れて、Fragment.setArguments()を使用して、すべての「追加」を引数として設定することです。 Fragmentに添付されている引数にアクセスしたい場合はいつでもに電話して、同じBundleに戻すことができます。だから、基本的に、あなたのonItemClick()方法でIntentを行うに持つすべてのコードを置き換えて、代わりに:

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

newFragment.setArguments(args); 

transaction.commit(); 

をまた、オフトピック、しかし、あなたは、あなたが「ドンように何か他のものにあなたのFragmentの名前を変更したい場合がありますListFragmentとコード内のプラットフォームのバージョンとの違いを示すには、完全修飾パッケージ名を使用する必要があります。

HTH

+0

Thnxはこれに助けをしました。私は今、エラーを取得していないと、アクティビティがロードされますが、それは現在、そこにあったデータをリロードしています:それは、クラスがw/oフラグメントを設定したときにしたように、リストに新しいデータをロードしません。これ以上のヘルプ/ポインタ。 Thnx – CelticParser

+0

もう一度thnxの助けを借りてください。私の変更を見て、あなたが私のArgsを実装すべきより良い方法があるかどうかを見てください、そして、あなたは私のバックスタックがなぜバックキーで動作しないのかを見ますか? – CelticParser

+0

なぜ私はバックアクションがうまくいかないのか分かりません。トランザクションがバックスタックに追加されているので、戻るボタンを押すと、最後のトランザクションが以前の状態にポップされます。 'super'や標準的なバック動作に影響を与える何かを呼び出さずに、あなたのアクティビティで' onBackPressed() 'がオーバーライドされていますか? – Devunwired

0

なぜあなたはちょうどあなたがしたときに値を渡すコンストラクタを作成していけませんフラグメントを作成しますか?それはあなたが別で1 Fragmentを交換するFragmentTransactionを使用して正しい軌道に乗っている

+0

コンストラクタをフラグメントで使用するのが悪いためです。あなたはいつもデフォルトのコンストラクタ(空)を必要とするか、復元時に破損します。 – Warpzit

関連する問題