首页 > 解决方案 > 从 Android 中的外部 XML 文件访问元素

问题描述

我正在开发一个 Android 应用程序。我为布局创建了另一个 XML 文件:-

聊天文件.XML

  <?xml version="1.0" encoding="utf-8"?>
  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/suitableblack"
    android:orientation="vertical">

    <Button
    android:id="@+id/signout"
    android:layout_width="422dp"
    android:layout_height="64dp"
    android:text="Button" />

<ListView
    android:id="@+id/Msgdisplay"
    android:layout_width="374dp"
    android:layout_height="593dp"
    android:layout_below="@id/signout"
    android:layout_marginLeft="20dp"
    android:forceDarkAllowed="false" />

<LinearLayout
    android:layout_width="390dp"
    android:layout_height="83dp"
    android:layout_below="@id/Msgdisplay"
    android:layout_marginLeft="20dp"
    android:orientation="horizontal">


    <EditText
        android:id="@+id/Msginput"
        android:layout_width="482dp"
        android:layout_height="67dp"
        android:layout_weight="1"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name" />

    <Button
        android:id="@+id/Sendbtn"
        android:layout_width="match_parent"
        android:layout_height="68dp"
        android:layout_weight="1"
        android:text="Button" />
</LinearLayout>

所以我想在我的 MainActivity.java 文件中使用 ID-Sendbtn 访问按钮,该部分的代码在这里:-

    Button sendbtn=findViewById(R.id.Sendbtn);
    sendbtn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
          String msg=message.getText().toString();
          if(msg.length()==0)
        {
            Toast.makeText(getApplicationContext(),"Blank message detected",Toast.LENGTH_SHORT);
        }
        else
        {
            FirebaseDatabase.getInstance().getReference().push().setValue(new chatcolumns(msg,FirebaseAuth.getInstance().getCurrentUser().getDisplayName()));
        }

    }
  });

但是每当我运行此代码时,它都会给我以下错误:-

 Process: com.example.anochatzone, PID: 18398
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.anochatzone/com.example.anochatzone.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
    at android.app.ActivityThread.-wrap12(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6119)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
    at com.example.anochatzone.MainActivity.onCreate(MainActivity.java:87)
    at android.app.Activity.performCreate(Activity.java:6679)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
    at android.app.ActivityThread.-wrap12(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6119) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

我的主要问题是如何从 MainActivity.java 中的 chatfile.xml 访问按钮

更新 MainActivity.java

  package com.example.anochatzone;

    import androidx.annotation.NonNull;
    import androidx.appcompat.app.AppCompatActivity;

    import android.os.Bundle;
    import android.text.Layout;    
    import android.util.Log;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.*;

    import com.google.android.gms.tasks.OnCompleteListener;
    import com.google.android.gms.tasks.Task;
    import com.google.firebase.auth.AuthResult;
    import com.google.firebase.auth.FirebaseAuth;
    import com.google.firebase.database.FirebaseDatabase;

    import java.util.Objects;


    public class MainActivity extends AppCompatActivity {
    private FirebaseAuth authenticate;
        private String email_str="";
     private String password_str="";
    private EditText email,password,message;
    private Button loginbtn,resetbtn,sendbtn;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE); //will hide the title
            Objects.requireNonNull(getSupportActionBar()).hide(); // hide the title bar
            this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN); //enable full screen
            setContentView(R.layout.activity_main);
           email=findViewById(R.id.EmailInput);
           password=findViewById(R.id.Passwordinput);
           message=findViewById(R.id.Msginput);

    loginbtn=findViewById(R.id.Loginbtn);
           resetbtn= findViewById(R.id.ResetBtn);
       sendbtn=findViewById(R.id.Sendbtn);


        authenticate=FirebaseAuth.getInstance();


       loginbtn.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
     Toast.makeText(getApplicationContext(),"Please wait while we are processing your request........",Toast.LENGTH_SHORT).show();
                email_str=email.getText().toString();
                password_str=password.getText().toString();
            if(email_str.length()==0||password_str.length()==0)
            {
                Toast.makeText(getBaseContext(),"Please check email and password",Toast.LENGTH_LONG).show();
            }
            else
            {
                authenticate.signInWithEmailAndPassword(email_str,password_str).addOnCompleteListener(MainActivity.this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                       if(task.isSuccessful()){
    Log.d("User display name" , FirebaseAuth . getInstance() . getCurrentUser().getDisplayName());
                         Toast.makeText(getApplicationContext(),"Welcome "+email_str+" you have sucessfully logged in",Toast.LENGTH_LONG).show();
                         setContentView(R.layout.chatfile);

                       }
                       else
                       {
                           Toast.makeText(getApplicationContext(),"Failed to sign in .Please check internet connection or try again later",Toast.LENGTH_SHORT).show();
                       }


                    }
                });
            }
           }
       });


    sendbtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String msg=message.getText().toString();
        if(msg.length()==0)
        {
            Toast.makeText(getApplicationContext(),"Blank message detected",Toast.LENGTH_SHORT);
        }
        else
        {
             FirebaseDatabase.getInstance().getReference().push().setValue(new        chatcolumns(msg,FirebaseAuth.getInstance().getCurrentUser().getDisplayName()))    ;
        }
    }
    });
    }
}

标签: javaandroid

解决方案


根据您的目的,当您启动或启动应用程序时,会出现登录页面。如果登录成功,就会出现聊天页面。

因此,您需要将您的活动分为两个活动,例如LoginActivity启动器活动和ChatActivity(MainActivity),如下所示。

对于登录页面,可能是一个activity_login.xmlLoginActivity.java

activity_login.xml

   <!-- You need one button for login action. -->
   <Button
      android:id="@+id/btnLogin"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:text="Login"
      />

LoginActivity.java

@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // This line is important to access your resource id
    setContentView(R.layout.activity_login);

    findViewById(R.id.btnLogin).setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        // isLoginSuccess is an example condition for you
        if (isLoginSuccess) {
          // Navigate to mainpage
          startActivity(new Intent(LoginActivity.this, MainActivity.class));

          // Terminate the login activity for one time show.
          finish();
        } else {
          // TODO: Try again implementations
        }
      }
    });
  }

对于主页,像上面一样,你需要一个activity_main.xml和一个MainActivity.java

Chatfile.xml

      // other codes....
      <Button
        android:id="@+id/Sendbtn"
        android:layout_width="match_parent"
        android:layout_height="68dp"
        android:layout_weight="1"
        android:text="Button" />
      // other codes....

MainActivity.java

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // This line is important for your 'chatfile.xml'
    setContentView(R.layout.Chatfile);

    // You can access id `SendBtn` right now.
    findViewById(R.id.SendBtn).setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
          // TODO: implement something here.
      }
    });
  }

AndroidManifest.xml中,您需要将启动器活动更改为LoginActivity

<application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">
    <activity android:name=".LoginActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

    <activity
        android:name=".MainActivity"/>
  </application>

根据我的解决方案,您不必考虑登录成功或失败时应该隐藏什么 ui 元素。

如果我的回答有任何问题,请随时告诉我。


推荐阅读