片段错误 - ListFragment不能转换为android.app.Activity [英] Fragment Error - ListFragment cannot be cast to android.app.Activity

查看:182
本文介绍了片段错误 - ListFragment不能转换为android.app.Activity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要与另一个片段置换的片段视图。

在ListFragment项被选中,则DetailsFragment是由沿附加传递到新的(或第二)ListFragment在活动被替换为另一个ListFragment。我的问题是,我得到一个无活动来处理意向{(有临时演员)}。该ListFragment工作正常活动的第一次启动的时候,但是当我起来日期(替换)与另一ListFragment详细信息活动中,我得到的错误。

这是我的第一个片段的活动,我想我不知道如何通过附加适当的片段之间。我最肯定不会使用的片段经理/事务类正常(?)。如果任何人都可以纠正我的实现,我将不胜AP preciate吧。

更新:我补充说:i.setClass(getActivity(),ListFragment.class);到的意图在ListFragment类和现在的记录错误已经改变为以下:

UPDTATE 2:我纠正了我的意图,以参数为Devunwired sugested,它工作得漂亮了。日Thnx Devunwired。在onlyn问题我现在是,当返回键是pressed的backstack不工作。修正后的类如下:

LogCat中的(修订版)

 致命异常:主要
 java.lang.RuntimeException的:无法实例活动ComponentInfo {com.andaero.test / com.andaero.test.fragments.ListFragment}:java.lang.ClassCastException:com.andaero.test.fragments.ListFragment无法转换到Android。 app.Activity
    在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1739)
    在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
    在android.app.ActivityThread.access $ 500(ActivityThread.java:122)
    在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1024)
    在android.os.Handler.dispatchMessage(Handler.java:99)
    在android.os.Looper.loop(Looper.java:132)
    在android.app.ActivityThread.main(ActivityThread.java:4123)
    在java.lang.reflect.Method.invokeNative(本机方法)
    在java.lang.reflect.Method.invoke(Method.java:491)
    在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:841)
    在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
    在dalvik.system.NativeStart.main(本机方法)
 致:java.lang.ClassCastException:com.andaero.test.fragments.ListFragment不能转换为android.app.Activity
 

在ListFragment类:

 公共类ListFragment扩展android.app.ListFragment {

    布尔mDualPane;
    INT mCurCheckPosition = 0;
    受保护的TextView activityTitle;

    布尔mExternalStorageAvailable = FALSE;
    布尔mExternalStorageWriteable = FALSE;

    字符串extStorageDirectory = Environment.getExternalStorageDirectory()
            的ToString();
    文件DBFILE =新的文件(extStorageDirectory +/Andaero/dB/Andaero.db);
    SQLiteDatabase DB = SQLiteDatabase.openOrCreateDatabase(DBFILE,NULL);

    私有静态最后弦乐QUERY_KEY =QUERY_KEY;
    私有静态最后弦乐QUERY_ORDER =QUERY_ORDER;

    私人浏览布局;

    @覆盖
    公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
            捆绑savedInstanceState){
        布局= inflater.inflate(R.layout.listview,NULL);
        返回布局;

    }

    @覆盖
    公共无效onActivityCreated(包savedInstanceState){
        super.onActivityCreated(savedInstanceState);

        捆绑额外= getActivity()getIntent()getExtras()。
        捆绑ARG = this.getArguments(); // **加入到得到ARGS

        / **
         *从去年活动的查询字符串,并将其传递给此
         * 活动 -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - -----
         * /
        串Q = NULL;
        如果(临时演员!= NULL){
            Q = extras.getString(QUERY_KEY);
        }

        如果(ARG!= NULL){
        Q =(字符串)(getArguments()!= NULL?getArguments()的getString(
                QUERY_KEY):1);
    }

        loadquery子(Q);
    }

    公共无效loadquery子(串Q){

        如果(Environment.getExternalStorageState()。等于(
                Environment.MEDIA_MOUNTED)){

            串QO = getActivity()getIntent()getStringExtra(QUERY_ORDER)。。;
            光标C = db.rawQuery(Q +ORDER BY`_id`+ QO,NULL);
            setListAdapter(新QueryAdapter(getActivity(),C));
            db.close();

        } 其他 {
            Alerts.sdCardMissing(getActivity());
        }
    }

    公共类QueryAdapter扩展的CursorAdapter {

        公共QueryAdapter(上下文的背景下,光标C){
            超(背景下,C);
            LayoutInflater.from(上下文);
        }

        @覆盖
        公共无效bindView(视图V,上下文的背景下,最终的光标C){

            INT tvLabel = c.getColumnIndexOrThrow(标签);
            字符串标签= c.getString(tvLabel);
            最后的TextView labelTxt =(TextView中)v.findViewById(R.id.label);

            如果(labelTxt!= NULL){
                labelTxt.setText((+标签+));
            }

            INT tvTitle = c.getColumnIndexOrThrow(标题);
            最后字符串标题= c.getString(tvTitle);
            TextView的titleTxt =(TextView中)v.findViewById(R.id.listTitle);

            如果(titleTxt!= NULL){
                titleTxt.setText(职称);
            }

            INT tvDescription = c.getColumnIndexOrThrow(说明);
            字符串描述= c.getString(tvDescription);
            TextView的descriptionTxt =(TextView中)v.findViewById(R.id.caption);

            如果(descriptionTxt!= NULL){
                descriptionTxt.setText(介绍);
            }

            INT tvDate = c.getColumnIndexOrThrow(日);
            字符串日期= c.getString(tvDate);
            TextView的dateTxt =(TextView中)v.findViewById(R.id.dateAdded);

            如果(dateTxt!= NULL){
                dateTxt.setText(日期);
            }

            INT tvGoto = c.getColumnIndexOrThrow(gotoURL);
            最后弦乐gotoURL = c.getString(tvGoto);
            TextView的gotoTxt =(TextView中)v.findViewById(R.id.dummy);

            如果(gotoTxt!= NULL){
                gotoTxt.setText(gotoURL);
            }

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

            最终的ListView LV = getListView();
            lv.setEnabled(真正的);
            lv.setClickable(真正的);

            lv.setOnItemClickListener(新OnItemClickListener(){

                公共无效onItemClick(适配器视图<>为arg0,视图V,INT ARG2,
                        长ARG3){

                    //创建新的片段和交易
                    片段newFragment =新ListFragment();
                    FragmentTransaction交易= getFragmentManager()
                            .beginTransaction();

                    //取代无论是在与fragment_container视图
                    //这个片段,
                    //和事务添加到背叠
                    transaction.replace(R.id.detailFragment,newFragment);
                    transaction.addToBackStack(空);

                    字符串URL =;
                    URL =(字符串)v.getTag();

                    INT NI = c.getColumnIndexOrThrow(意图);
                    字符串意图= c.getString(NI);
                    类<> myIntent = NULL;
                    尝试 {
                        myIntent =的Class.forName(com.andaero.test.fragments
                                +意向);
                    }赶上(ClassNotFoundException异常E){
                        Log.e(错误,找不到类新的意图!);
                        e.printStackTrace();
                    }

                    INT tvTitle = c.getColumnIndexOrThrow(标题);
                    字符串标题= c.getString(tvTitle);

                    INT tvLabel = c.getColumnIndexOrThrow(标签);
                    字符串标签= c.getString(tvLabel);

                    字符串queryKey =SELECT * FROM+标签;
                    c.close();
                    db.close();

                    捆绑的args =新包(); // **取代意图
                   args.putString(QUERY_KEY,queryKey);
                   args.putString(KEY_URL,网址);
                   args.putString(KEY_SUBTITLE称号);
                   args.putString(KEY_LABEL,标签);
                   args.putString(KEY_INTENT,意图);
                   args.putString(QUERY_ORDER,ASC);

                   newFragment.setArguments(参数);

                    //提交事务
                    器transaction.commit();
                }
            });
        }

        @覆盖
        公共查看NewView的(上下文的背景下,光标光标的ViewGroup父){
            最终的视图V = LayoutInflater.from(上下文).inflate(
                    R.layout.list_item,父母,假);
            返回伏;
        }
    }
}
 

解决方案

您是在正确的轨道上使用 FragmentTransaction 来替换一个片段与另一个,但片段不使用意图从一个传递数据比如另一个像活动一样。事实上,调用 startActivity()意图指着一个片段会引起各种烟花爆竹的,你不想要的(就像你看到的那样)。

这是完全没有问题将数据传递到一个新的片段在其构造,这样你就可以创建一个构造函数为你的 ListFragment 这需要数据要转发任何参数。另一种选择是把他们设置所有的额外的争论在新的片段 A 捆绑和使用 Fragment.setArguments()。任何时候你要访问您连接到片段,你可以调用参数 getArguments()返回同样捆绑。所以基本上,更换所有有做与code的意图 onItemClick()法,而不是:

 捆绑的args =新包();
args.putString(QUERY_KEY,queryKey);
//...add所有的演员将捆绑

newFragment.setArguments(参数);

器transaction.commit();
 

此外,偏离主题,但你可能要重新命名你的片段其他的东西,这样你就不必依赖完全合格的包名告诉在code本 ListFragment 和平台的版本之间的差异。

心连心

I have a fragment view that needs replacement with another fragment.

When the ListFragment item is selected, the DetailsFragment is to be replaced with another ListFragment by passing along Extras to the new ( or 2nd) ListFragment in the activity. My problem is that I am getting a "No Activity found to handle Intent {(has extras)}". The ListFragment works fine when the activity first starts, but when i up date (replace) the Details activity with another ListFragment, I get the error.

This is my first Fragment activity and I guess I don't know how to pass Extras properly between the fragment. I am most surely not using the fragment-manager/transaction classes properly(?). If anyone could correct my implementation, I would greatly appreciate it.

UPDATE: I added "i.setClass(getActivity(), ListFragment.class);" to the intent in the ListFragment class and now the Log error has changed to the following:

UPDTATE 2: I corrected my intents to Arguments as Devunwired sugested and it works just beautifully now. Thnx Devunwired. the onlyn issue I have now is that the backstack doesnt work when the back key is pressed. The corrected class is below:

LogCat (UPDATED):

     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

The ListFragment Class:

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;
        }
    }
}

解决方案

You're on the right track with using the FragmentTransaction to replace one Fragment with another, but Fragment doesn't use an Intent to pass data from one instance to another like Activity does. In fact, calling startActivity() with an Intent pointed at a Fragment will cause all kinds of fireworks that you don't want (like you've seen).

It is perfectly okay to pass data to a new Fragment in its constructor, so you can create a constructor for your ListFragment that takes any parameters of data you want to forward. Another option is to set all of your "extras" as arguments on the new Fragment by putting them in a Bundle and using Fragment.setArguments(). Any time you want to access the arguments you attached to the Fragment, you can just call getArguments() to get back that same Bundle. So basically, replace all the code having to do with an Intent in your onItemClick() method, and instead:

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

newFragment.setArguments(args);

transaction.commit();

Also, off-topic, but you might want to rename your Fragment to something else so that you don't have to rely on the fully qualified package name to tell the difference between your ListFragment and the platform's version in your code.

HTH

这篇关于片段错误 - ListFragment不能转换为android.app.Activity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆