0

I have been attempting to call a method from my home activity which should fire once a button is clicked on my settings fragment. The result of this button click should call the greenTorso() and swap an image on my avatar fragment. I am currently getting a null pointer error, please see the logcat attached. I'm not even sure if this is the right way to go about this, but been stuck for a couple of days now and hoped someone could help. Thanks in advance.

My home activity:

public class Home extends AppCompatActivity implements SettingsFragment.Communicator {

private TextView name, email;
Button LogoutButton;
UserSessionManager sessionManager;
Button button;
ImageView Torso;

public void communicateWith(){
    AvatarFragment avatarFragment = (AvatarFragment)getSupportFragmentManager().findFragmentById(R.id.nav_avatar);
    avatarFragment.greenTorso();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);
    getWindow().setBackgroundDrawableResource(R.drawable.background2); // sets background to background2.png
    this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); // hides keyboard on boot

    sessionManager = new UserSessionManager(getApplicationContext());

    TextView lblName = (TextView) findViewById(R.id.lblName);
    TextView lblEmail = (TextView) findViewById(R.id.lblEmail);

    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
    bottomNav.setOnNavigationItemSelectedListener(navListener);
    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
            new HomeFragment()).commit();

    if(sessionManager.checkLogin())
        finish();

    // get user data from session
    HashMap<String, String> user = sessionManager.getUserDetails();

    // get name
    String name = user.get(UserSessionManager.KEY_NAME);

    // get email
    String email = user.get(UserSessionManager.KEY_EMAIL);


    //lblName.setText(Html.fromHtml("Name: <b>" + name + "</b>"));
    lblEmail.setText(Html.fromHtml("Welcome: <b>" + email + "</b>"));

    LogoutButton=(Button)findViewById(R.id.LogoutButton);
    Toast.makeText(getApplicationContext(),
            "User Login Status: " + sessionManager.isUserLoggedIn(),
            Toast.LENGTH_LONG).show();

    LogoutButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            // Clear the User session data
            // and redirect user to LoginActivity
            sessionManager.logoutUser();
        }
    });
    }

    private BottomNavigationView.OnNavigationItemSelectedListener navListener =
        new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                Fragment selectedFragment = null;
                switch (menuItem.getItemId()) {
                    case R.id.nav_steps:
                        selectedFragment = new HomeFragment();
                        break;
                    case R.id.nav_avatar:
                        selectedFragment = new AvatarFragment();
                        break;
                    case R.id.nav_settings:
                        selectedFragment = new SettingsFragment();
                        break;

                }



 getSupportFragmentManager()
.beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();
                return true;
            }
        };
}

My settings fragment:

public class SettingsFragment extends Fragment {

public Button button;
public ImageView Torso;
public ImageView ShopGreenTorso;
private Communicator interfaceImplementor;

public interface Communicator
{
    public void communicateWith();

}

@Override
public void onAttach(Activity context) {
    super.onAttach(context);
    this.interfaceImplementor = (Communicator)context;

}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_settings, container, false);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Button button = (Button) getActivity().findViewById(R.id.button1);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           // ImageView torso = (ImageView) getActivity().findViewById(R.id.Torso);
            interfaceImplementor.communicateWith();

        }
    });
}
}

My avatar fragment:

public class AvatarFragment extends Fragment {
public ImageView IV;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
    View rootView = inflater.inflate(R.layout.fragment_avatar, container, false);

   return rootView;


}

public void greenTorso()
{
    ImageView IV =(ImageView) getActivity().findViewById(R.id.Torso);
    IV.setBackgroundResource(R.drawable.torso2green);
}
}

Avatar layout:

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

<ImageView
    android:layout_width="500dp"
    android:layout_height="530dp"
    android:layout_centerInParent="true"
    android:orientation="vertical"
    android:layout_marginStart="30dp"
    android:layout_marginEnd="30dp"
    android:id="@+id/Torso"
    android:src="@drawable/torso2" >

</ImageView>
</RelativeLayout>

Settings layout:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:orientation="vertical"
android:background="#D3D3D3"
android:weightSum="10"
tools:context=".Home">



<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

<TextView
    android:layout_marginTop="100dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Shop"
    android:textSize="26sp"
    android:textStyle="bold"
    android:gravity="center"
    android:layout_marginBottom="10dp"/>


    <androidx.cardview.widget.CardView
        android:id="@+id/cardview1"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_below="@+id/cardview"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="16dp"
        app:cardBackgroundColor="@color/white"
        app:cardCornerRadius="15dp"
        app:cardElevation="10dp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

        </LinearLayout>

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center_horizontal"
            android:paddingLeft="10dp"
            android:text="Green Torso"
            android:textColor="@color/cardview_dark_background"
            android:textSize="20sp"
            android:textStyle="bold" />

        <ImageView
            android:id="@+id/ShopGreenTorso"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/torso2green" />

        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_gravity="bottom"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginBottom="10dp"
            android:background="@drawable/register_button"
            android:shadowColor="@color/colorPrimary"
            android:text="10,000S Buy"
            android:textColor="@color/white">
        </Button>

    </androidx.cardview.widget.CardView>

My navigation:

 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 <item
 android:id="@+id/nav_steps"
 android:icon="@drawable/ic_directions_walk_black_24dp"
 android:title="Steps" />
 <item
    android:id="@+id/nav_avatar"
    android:icon="@drawable/ic_face_black_24dp"
    android:title="Avatar" />
 <item
    android:id="@+id/nav_settings"
    android:icon="@drawable/ic_build_black_24dp"
    android:title="Settings" />

 </menu>

enter image description here

Greg
  • 476
  • 9
  • 23
  • Did you forget to set layout via `setContentView` or commit the fragment on your home activity? – Aaron Nov 26 '19 at 20:08
  • Hi, i've updated my home activity. Not really sure, quite new to fragments so followed a tutorial. – Greg Nov 26 '19 at 20:15
  • 1
    Where is the definition of `nav_avatar`? – greeble31 Nov 26 '19 at 20:26
  • Hi, its defined in my navigation xml file i think, just added it – Greg Nov 26 '19 at 20:33
  • 1
    Yeah I don't think that's the right ID. That's the ID of a menu item. The fragment manager has no way of associating it with your `AvatarFragment`. Try looking up `R.id.fragment_container` instead. See [here](https://stackoverflow.com/questions/10833666/findfragmentbyid-always-returns-null) for more info. – greeble31 Nov 26 '19 at 21:59
  • Only mention i could find was in my home activity which i have attached :) – Greg Nov 26 '19 at 22:08
  • 1
    No, I mean, that's the original mistake you made in your code. I wasn't referring to your edit; that was fine. – greeble31 Nov 26 '19 at 22:19
  • Okiee so i need to add something like :MyFragment myFragment = new MyFragment(); fragmentTransaction.add(R.id.fragment_container, myFragment); fragmentTransaction.commit(); somewhere. Sorry for being a noob – Greg Nov 26 '19 at 22:32
  • 1
    That's OK. I don't think you even have to add anything. I think if you just switch `findFragmentById(R.id.nav_avatar)` to `findFragmentById(R.id.fragment_container)` it will work. Not 100% sure though. – greeble31 Nov 26 '19 at 22:35
  • That did something, my exception is now: java.lang.ClassCastException: app.capaa.SettingsFragment cannot be cast to app.capaa.AvatarFragment at app.capaa.Home.communicateWith(Home.java:34) at app.capaa.SettingsFragment$1.onClick(SettingsFragment.java:83) – Greg Nov 26 '19 at 22:43
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/203138/discussion-between-greeble31-and-fusiozii). – greeble31 Nov 26 '19 at 22:48

0 Answers0