如何在NDK项目中在GL上绘制android UI元素

时间:2014-10-14 12:57:34

标签: android c++ opengl-es android-ndk

我有一个NDK项目,我使用opengl进行渲染。我正在用c ++处理这一切。我也能够使用jni创建一个android.widget.Button并挂钩它的回调。当我按下屏幕时,回调会触发,所以我知道我有一个有效的UI元素。

问题是该按钮不可见。我假设它被GL隐藏了。我需要一些在顶级GL上绘制UI的方法。

由于ndk中的GL没有glsurfaceview,我只能在一些Android布局中粘贴它和按钮,让它处理问题。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我找到了解决方案here,但我在这里复制了重点。非常感谢mkandula的出色解释

  1. 创建一个GUIActivity类,它将处理交互并将使用它们或将它们传递给底层的AppInterface类

    public class GUIActivity extends Activity
    
  2. 在您的主要活动的onCreate方法中,创建GUIActivity

    // Inside AppInterface
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this.getApplication().getApplicationContext();
        Intent startNewActivityOpen = new Intent(this, GUIActivity.class);
        startActivity(startNewActivityOpen);
    }
    
  3. 将新活动添加到您的清单

    <activity android:name="GUIActivity"
              android:label="GUIActivity"
              android:theme="@style/Theme.Transparent"
              android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize">
    </activity>
    
  4. 在res / values / styles.xml下为项目添加透明主题

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
      <style name="Theme.Transparent" parent="android:Theme">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">false</item>
      </style>
    </resources>
    
  5. 这将使您能够对原生活动进行透明活动,而无需更改本机代码的任何工作方式。

    您可能想要传递触摸事件,并且此类mkandula建议使用以下内容。我还没有对此进行过测试,但我毫不怀疑它是有效的,因为其余的答案都是现场的。

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isViewInGameMode == true) {
            if (ev.getAction() == MotionEvent.ACTION_DOWN)
                AppInterface.OnTouchStart(ev.getX(), ev.getY());
            else if (ev.getAction() == MotionEvent.ACTION_MOVE)
                AppInterface.OnTouchUpdate(ev.getX(), ev.getY());
            else if (ev.getAction() == MotionEvent.ACTION_UP)
                AppInterface.OnTouchEnd(ev.getX(), ev.getY());
            else {
                System.out.println("action " + ev.getAction()
                                   + " unaccounted for in OnTouchEvent");
            }
        }
        return super.onTouchEvent(ev);
    }