如何在已设置ContentView的BridgeScene中显示Ennemy1的Canvas绘制内容?
解决自定义View与原有布局共存的问题
嘿,你现在的核心问题出在**重复调用setContentView()**上!第二次调用setContentView(ennemy1)会完全替换掉你第一次设置的R.layout.activity_bridge_scene布局,这不仅会导致你找不到原来的ImageView控件,还没法同时显示布局里的按钮和敌人View。下面给你两种简单可行的解决方案:
方法一:直接在布局文件中添加自定义View
这是最直观的方式,把Ennemy1作为子View写到布局里,让它和原有控件共存:
- 打开
res/layout/activity_bridge_scene.xml,用FrameLayout作为根容器(支持层叠显示),添加自定义View标签:
<?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:id="@+id/root_layout"> <!-- 你原来的ImageView和按钮 --> <ImageView android:id="@+id/imvStickman" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/stickmanreturnkick0"/> <ImageView android:id="@+id/imvJump" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/your_jump_icon"/> <!-- 添加自定义敌人View,替换com.yourpackage为你的实际包名 --> <com.yourpackage.Ennemy1 android:id="@+id/ennemy1" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
- 修改
BridgeScene的onCreate方法,去掉第二次setContentView(),直接从布局中获取自定义View:
public class BridgeScene extends AppCompatActivity { private static final int[] ALL_DRAWABLE_RES_EAGLE = new int[]{ R.drawable.stickmanreturnkick0, R.drawable.stickmanreturnkick1, }; private Ennemy1 ennemy1; private Handler handler = new Handler(); private final static long Interval = 30; private Runnable updateImageTask; private int currentDrawableResIndex; private static long IMAGE_UPDATE_DELAY_MILLIS = 30; private ImageView imvStickman; private ImageView imvJump; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bridge_scene); // 直接从布局获取自定义View ennemy1 = findViewById(R.id.ennemy1); updateImageTask = new UpdateImageTask(); imvJump = findViewById(R.id.imvJump); imvStickman = findViewById(R.id.imvStickman); imvJump.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 你的点击逻辑 } }); } // 补充你的UpdateImageTask实现 private class UpdateImageTask implements Runnable { @Override public void run() { // 更新帧逻辑 handler.postDelayed(this, IMAGE_UPDATE_DELAY_MILLIS); } } }
方法二:代码中动态添加自定义View到布局容器
如果不想修改布局文件,可以在代码中找到布局根容器,把Ennemy1作为子View动态添加:
修改BridgeScene的onCreate方法:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bridge_scene); // 初始化自定义View ennemy1 = new Ennemy1(this); // 获取布局根容器(需确保布局根视图有id: root_layout) FrameLayout rootLayout = findViewById(R.id.root_layout); // 设置自定义View的布局参数,让它充满整个容器 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ); // 将自定义View添加到根容器 rootLayout.addView(ennemy1, params); // 剩下的原有逻辑不变 updateImageTask = new UpdateImageTask(); imvJump = findViewById(R.id.imvJump); imvStickman = findViewById(R.id.imvStickman); imvJump.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 你的点击逻辑 } }); }
原理说明
setContentView()的作用是设置Activity的根视图,每次调用都会替换掉之前的根视图。我们的需求是同时显示原有布局控件和自定义View,所以正确的做法是把自定义View作为子View添加到已有的根布局中,而不是替换整个根视图。
这样修改后,你的Ennemy1会绘制在原有布局的上方(FrameLayout默认层叠顺序),同时原来的ImageView和按钮也能正常显示和交互!
内容的提问来源于stack exchange,提问作者Noudy Daher
相关产品推荐
相关产品推荐

