从Unity

时间:2019-05-18 15:42:46

标签: java android unity3d nullpointerexception

我需要根据Unity上发生的事情使用一些UI元素。 第一个是Button,第二个是TextView。 这是activity_research.xml。如您所见,我在seContentView中使用了此布局。 button_open_info是我需要根据Unity显示的按钮。

<android.support.constraint.ConstraintLayout
...
    <FrameLayout
        android:id="@+id/unity_player"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_open_info"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="16dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="@+id/guideline2" />
...
</android.support.constraint.ConstraintLayout>

text_view_info位于Dialog的第二布局中。它称为dialog_info_object

<android.support.constraint.ConstraintLayout
...
    <TextView
        android:id="@+id/text_view_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_weight="1"
        android:text="Init text"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

在这里您可以看到onCreate函数

public class UnityPlayerActivity extends Activity
{
    protected UnityPlayer mUnityPlayer;

    protected String m_currentTrackable;

    protected Activity m_currentActivity;

    protected Button m_buttonOpenInfo;

    protected Dialog m_dialogInfoObject;
    protected TextView m_textViewInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        initContentView();

        initUIElements();
    }

其中

    private void initContentView()
    {
        mUnityPlayer = new UnityPlayer(this);
        setContentView(R.layout.activity_research);
        FrameLayout frameLayout = findViewById(R.id.unity_player);
        frameLayout.addView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }

    private void initUIElements)
    {
        m_buttonOpenInfo = findViewById(R.id.button_open_info);

        m_dialogInfoObject = new Dialog(this);
        m_dialogInfoObject.setContentView(R.layout.dialog_info_object);
        m_textViewInfo = m_dialogInfoObject.findViewById(R.id.text_view_info);

        m_buttonOpenInfo.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                m_dialogInfoObject.show();
            }
        });
    }

在Unity中,我调用了三个函数:第一个函数是setActivity,在其中设置当前的Activity

public void setActivity(Activity activity)
    {
        m_currentActivity = activity;
    }

第二个是setCurrentTrackable,我只是在Unity中选择的当前对象设置了一个字符串

public void setCurrentTrackable(String currentTrackable)
    {
        if (m_currentActivity == null)
        {
            return;
        }

        m_currentTrackable = currentTrackable;
    }

第三个是showButton,我只是将按钮的可见性更改为visible。

public void showButton()
    {
        if (m_currentActivity == null)
        {
            return;
        }

        m_currentActivity.runOnUiThread(new Runnable() {
            public void run()
            {
                m_buttonOpenInfo = m_currentActivity.findViewById(R.id.button_open_info);

                if (!m_currentTrackable.isEmpty())
                {
                    m_buttonOpenInfo.setVisibility(View.VISIBLE);
                }
                else
                    m_buttonOpenInfo.setVisibility(View.INVISIBLE);
                }
            }
        });
    }

我不知道这样做是否正确,但是正在运行,我可以引用Button并进行显示。我可以避免在m_buttonOpenInfo = m_currentActivity.findViewById(R.id.button_open_info)上使用showButton()吗?没有它,我将无法引用Button,但是我已经在initUIElemenets()中引用了。

我尝试复制相同的结构以使用TextView,但是当我尝试在其上使用setText()时,总是得到相同的Null引用。

public void setTextView()
    {
        if (m_currentActivity == null)
        { 
            return;
        }

        m_currentActivity.runOnUiThread(new Runnable() {
            public void run()
            {
                if (!m_currentTrackable.isEmpty())
                {
                    m_textViewInfo = m_currentActivity.findViewById(R.id.text_view_info);
                 m_textViewInfo.setText("I am try to put something.");
                }
            }
        });
    }

Logcat错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

我认为我无法复制相同的结构,因为TextView的布局与Button的布局不同,但是我不知道如何解决此问题。我可能需要指定ActivityView?如果我尝试使用m_textViewInfo = m_dialogInfoObject.findViewById(R.id.text_view_info),则会在其中获得空引用(不同的上下文?)

编辑1

如果我将这部分移到setTextView()中,则可以使用setText,但是这种解决方案不是正确的方法。还是我错了?

m_buttonOpenInfo = m_currentActivity.findViewById(R.id.button_open_info);
m_dialogInfoObject = new Dialog(m_currentActivity);
m_dialogInfoObject.setContentView(R.layout.dialog_info_object);
m_textViewInfo = m_dialogInfoObject.findViewById(R.id.text_view_info);

m_buttonOpenInfo.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick(View v)
    {
        m_dialogInfoObject.show();
    }
});

编辑2

此外,如果我在LayoutInflater中使用setTextView(),则可以引用m_textViewInfo并使用setText(),但是m_dialogInfoObject.show()会显示(从侦听器调用)我认为是不同的看法,因为文本没有更新。

LayoutInflater inflater = (LayoutInflater) m_currentActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.dialog_info_object, null);
m_textViewInfo = view.findViewById(R.id.text_view_info);
Log.d("showButton", String.valueOf(m_textViewInfo.getText()));

做这种事情的正确方法是什么?我不明白。

0 个答案:

没有答案