
我在我的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转换错误所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)