java– 第二个FragmentTransaction.replace()调用的Android Fragment转换错误

java– 第二个FragmentTransaction.replace()调用的Android Fragment转换错误,第1张

概述我在我的mainActivity.java的classic_menu.xml中的fragment_container中保存了3种类型的片段.我从片段A开始,按下按钮,通过我使用FragmentTransaction.replace(R.id.fragment_container,B)的方法转到片段B.当我希望使用相同的方法从B转到片段C时,问题出现了.我使用你在下面看到的内

我在我的mainActivity.java的classic_menu.xml中的fragment_container中保存了3种类型的片段.我从片段A开始,按下按钮,通过我使用FragmentTransaction.replace(R.ID.fragment_container,B)的方法转到片段B.当我希望使用相同的方法从B转到片段C时,问题出现了.我使用你在下面看到的内容得到了一个投射错误.编辑我通过使用findFragmentByTag()而不是findFragmentByID()得到一个空指针.

以下是有问题的片段:

片段A:

    import androID.os.Bundle;    import androID.support.annotation.Nullable;    import androID.support.v4.app.Fragment;    import androID.vIEw.LayoutInflater;    import androID.vIEw.VIEw;    import androID.vIEw.VIEwGroup;    import com.example.R;    public class MainMenuFragment extends Fragment{    @OverrIDe    public VIEw onCreateVIEw(LayoutInflater inflater, @Nullable VIEwGroup container, @Nullable Bundle onSavedInstanceState){        VIEw vIEw = inflater.inflate(R.layout.main_menu_fragment, container, false);        return vIEw;        }    }

片段B:

    import androID.os.Bundle;    import androID.support.annotation.Nullable;    import androID.support.v4.app.Fragment;    import androID.vIEw.LayoutInflater;    import androID.vIEw.VIEw;    import androID.vIEw.VIEwGroup;    import com.example.R;    public class ClassicmenuFragment extends Fragment{    @OverrIDe    public VIEw onCreateVIEw(LayoutInflater inflater, @Nullable VIEwGroup container, @Nullable Bundle onSavedInstanceState){        VIEw vIEw = inflater.inflate(R.layout.classic_menu_fragment, container, false);        return vIEw;        }    }

片段C:

    import androID.os.Bundle;    import androID.support.annotation.Nullable;    import androID.support.v4.app.Fragment;    import androID.vIEw.LayoutInflater;    import androID.vIEw.VIEw;    import androID.vIEw.VIEwGroup;    import com.example.MainActivity;    import com.example.R;    import com.example.Widgets.TextVIEwPlus;    public class OnePlayerFragment extends Fragment{    private static TextVIEwPlus topscore;    private static TextVIEwPlus bottomscore;    @OverrIDe    public VIEw onCreateVIEw(LayoutInflater inflater, @Nullable VIEwGroup container, @Nullable Bundle onSavedInstanceState){        VIEw vIEw = inflater.inflate(R.layout.one_player_fragment, container, false);        topscore = (TextVIEwPlus) vIEw.findVIEwByID(R.ID.topPlayerscore1P);        bottomscore = (TextVIEwPlus) vIEw.findVIEwByID(R.ID.bottomPlayerscore1P);        return vIEw;    }    /**     * Changes the text of certain textVIEwPlus objects based on the given score     * @param vIEw int value that determines which vIEw to update     * @param score value to set the text to     */    public voID setscore(int vIEw, int score){        if(vIEw == MainActivity.top_PLAYER_1P) topscore.setText("" + score);        else if(vIEw == MainActivity.BottOM_PLAYER) bottomscore.setText("" + score);    }}

正在使用的按钮:

// in main_menu_fragment.xml<com.example.Widgets.buttonPlus    androID:ID="@+ID/classicB"        androID:onClick="StartClassicmenu"/>// in classic_menu_fragment.xml<com.example.Widgets.buttonPlus    androID:ID="@+ID/onePlayerB"        androID:onClick="StartGame"/>

MainActivity.java:

// cut a lot of stuff for brevityimport androID.os.Bundle;import androID.support.v4.app.Fragment;import androID.support.v4.app.FragmentActivity;import androID.support.v4.app.FragmentTransaction;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.Widget.TextVIEw;import com.example.fragments.ClassicmenuFragment;import com.example.fragments.MainMenuFragment;import com.example.fragments.OnePlayerFragment;public class MainActivity extends FragmentActivity {@OverrIDeprotected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.classic_menu);    // cut more stuff    theVIEw = (GameVIEw)findVIEwByID(R.ID.theVIEw);         // get reference to the GameVIEw    // begin the game in Animation mode and pass this MainActivity to the GameVIEw so it can be passed along    theVIEw.initiateGameThread(GameState.ANIMATION_MODE, this);    theThread = theVIEw.getThread();                        // get reference to the GameThread    theGame = theThread.getGameState();                     // get reference to the GameState    if (findVIEwByID(R.ID.fragment_container) != null) {        if (savedInstanceState != null) return;        MainMenuFragment mMenu = new MainMenuFragment();        // Add the fragment to the 'fragment_container' FrameLayout        getSupportFragmentManager().beginTransaction().add(R.ID.fragment_container, mMenu).commit();    }}public voID StartClassicmenu(VIEw v){    changetoFragment(new ClassicmenuFragment(), "Classicmenu");    inFragment = true;}public voID StartGame(VIEw v){    switch (v.getID()){    case R.ID.onePlayerB:        theGame.setMode(GameState.ONE_PLAYER_MODE);        changetoFragment(new OnePlayerFragment(), "OnePlayer");        Log.d("MainActivity", "StartGame() for 1P mode called");        break;    // other cases here but cut out    theGame.reset();}// called from gamestate when vIEws need to be updatedpublic voID setVIEwscore(int vIEw, int score){    if(theGame.getMode() == GameState.ONE_PLAYER_MODE){        Log.d("MainActivity", "setVIEwscore() for 1P mode called");        OnePlayerFragment f = (OnePlayerFragment) getSupportFragmentManager().findFragmentByID(R.ID.fragment_container);        if(f == null) Log.d("OnePlayerFragment", "null!!!");        f.setscore(vIEw, score);    }    // other cases cut out}/** * Handles creating and managing a uniform FragmentTransaction for the entire app * @param newFragment the new Fragment that will fade in, replacing whichever fragment was in use  */public voID changetoFragment(Fragment newFragment, String tag){    Log.d("MainActivity", "changetoFragment() Called with tag \"" + tag + "\"");    // Create the standard fade in/out transaction    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();    transaction.setCustomAnimations(androID.R.anim.fade_in, androID.R.anim.fade_out);    // Replace the old fragment in the relative Layout vIEw with the new one    transaction.replace(R.ID.fragment_container, newFragment, tag);    transaction.commit(); // Commit the transaction}

MainActivity的xml布局文件:

<?xml version="1.0" enCoding="utf-8"?><FrameLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"androID:layout_wIDth="match_parent"androID:layout_height="match_parent"androID:background="@color/back_grey"><com.example.GameVIEw    androID:ID="@+ID/theVIEw"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"     androID:layout_gravity="center" /><relativeLayout    androID:ID="@+ID/rLayout"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:scaleType="centerCrop">    <FrameLayout        androID:ID="@+ID/fragment_container"        androID:layout_wIDth="match_parent"        androID:layout_height="match_parent">    </FrameLayout></relativeLayout>

而现在最好的部分:

07-18 16:30:01.999: D/Openglrenderer(12335): Enabling deBUG mode 007-18 16:30:02.259: D/GameVIEw(12335): surfaceCreated() Called07-18 16:30:02.649: I/Timeline(12335): Timeline: Activity_IDle ID: androID.os.BinderProxy@1f1e5333 time:47586109307-18 16:30:13.179: D/VIEwRootImpl(12335): VIEwPostImeinputStage ACTION_DOWN07-18 16:30:13.389: D/MainActivity(12335): changetoFragment() Called with tag "Classicmenu"07-18 16:30:14.099: D/VIEwRootImpl(12335): VIEwPostImeinputStage ACTION_DOWN07-18 16:30:14.169: D/MainActivity(12335): changetoFragment() Called with tag "OnePlayer"07-18 16:30:14.169: D/MainActivity(12335): StartGame() for 1P mode called07-18 16:30:14.179: D/MainActivity(12335): setVIEwscore() for 1P mode called07-18 16:30:14.219: D/AndroIDRuntime(12335): Shutting down VM07-18 16:30:14.249: E/AndroIDRuntime(12335): FATAL EXCEPTION: main07-18 16:30:14.249: E/AndroIDRuntime(12335): Process: com.brownapps.battlepong, PID: 1233507-18 16:30:14.249: E/AndroIDRuntime(12335): java.lang.IllegalStateException: Could not execute method of the activity07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.vIEw.VIEw.onClick(VIEw.java:4222)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.vIEw.VIEw.performClick(VIEw.java:5156)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.vIEw.VIEw$PerformClick.run(VIEw.java:20755)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.os.Handler.handleCallback(Handler.java:739)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.os.Handler.dispatchMessage(Handler.java:95)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.os.Looper.loop(Looper.java:145)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.app.ActivityThread.main(ActivityThread.java:5835)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at java.lang.reflect.Method.invoke(Native Method)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at java.lang.reflect.Method.invoke(Method.java:372)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:1194)07-18 16:30:14.249: E/AndroIDRuntime(12335): Caused by: java.lang.reflect.InvocationTargetException07-18 16:30:14.249: E/AndroIDRuntime(12335):    at java.lang.reflect.Method.invoke(Native Method)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at java.lang.reflect.Method.invoke(Method.java:372)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.vIEw.VIEw.onClick(VIEw.java:4217)07-18 16:30:14.249: E/AndroIDRuntime(12335):    ... 10 more07-18 16:30:14.249: E/AndroIDRuntime(12335): Caused by: java.lang.classCastException: com.example.fragments.ClassicmenuFragment cannot be cast to com.example.fragments.OnePlayerFragment07-18 16:30:14.249: E/AndroIDRuntime(12335):    at com.example.MainActivity.setVIEwscore(MainActivity.java:325)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at com.example.GameState.run(GameState.java:650)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at androID.app.Activity.runOnUiThread(Activity.java:5517)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at com.example.GameState.reset(GameState.java:647)07-18 16:30:14.249: E/AndroIDRuntime(12335):    at com.example.MainActivity.StartGame(MainActivity.java:146)07-18 16:30:14.249: E/AndroIDRuntime(12335):    ... 13 more

您可能需要的唯一其他信息是,在游戏的reset()方法中,它通过VIEw.initiateGameThread(GameState.ANIMATION_MODE,this)调用传递给它的MainActivity对象上的setVIEwscore();通过使用runOnUiThread().

所以,我的问题是,为什么我第一次调用changetoFragment()会将MainMenuFragment更改为ClassicmenuFragment,但是当它应该将ClassicmenuFragment更改为OnePlayerFragment时第二次搞砸了?

感谢您花时间考虑我的这个问题.

解决方法:

ClassCastException是正确的 – 您无法将ClassicmenuFragment强制转换为OnePlayerFragment.在继承方面,你不能将一个兄弟转换为另一个兄弟(这两个类都是兄弟姐妹,有一个共同的父片段).一个类比是Orange和Apple都是一类Fruit的孩子,但是你不能把橘子扔给Apple(这没有意义!)

相反,将您的强制转换移除到OnePlayerFragment并使用instanceof关键字,只有在您确定片段是哪个子实例时才进行强制转换:

Fragment f = getSupportFragmentManager().findFragmentByID(R.ID.fragment_container);if (f == null) Log.d("Fragment", "null!!!");if (f instanceof OnePlayerFragment) {    ((OnePlayerFragment) f).setscore(vIEw, score);}
总结

以上是内存溢出为你收集整理的java – 第二个FragmentTransaction.replace()调用的Android Fragment转换错误全部内容,希望文章能够帮你解决java – 第二个FragmentTransaction.replace()调用的Android Fragment转换错误所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1119217.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存