skip to Main Content

I’m sure it’s going to be a something very obvious that my stupid self couldn’t find even after staring at the code for an hour.

I am trying to call the updateImages method in FragmentHome from HomeActivity. I have also created an instance of the class in onCreate but for reasons of my primitive coding knowledge, I am not able to call it. Any help would be greatly appreciated 🙂

Class that contains said method:

package com.example.youtubethumbnailapp;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.squareup.picasso.Picasso;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import static android.app.Activity.RESULT_OK;
public class FragmentHome extends Fragment {
    private FragmentHomeListener listener;

    public interface FragmentHomeListener{
        void onInputHomeSent(ArrayList<Uri> input);
    }

    private ImageView video1;
    private ImageView video2;
    private ImageView video3;
    private ImageView video4;
    private ImageView video5;
    private ImageView video6;
    private ImageView video7;
    private ImageView video8;
    private ImageView video9;
    private ImageView video10;
    private ImageView addImageButton;
    public Uri imageUri;
    ArrayList<Uri> uriArrayList = new ArrayList<Uri>();
    ArrayList<ImageView> imageViews = new ArrayList<ImageView>();
    private int imagesSelected = 0;

    @Nullable
    @org.jetbrains.annotations.Nullable
    @Override
    public View onCreateView(@NonNull @org.jetbrains.annotations.NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_home,container,false);

        //initialize variables
        video1 = v.findViewById(R.id.video1);
        imageViews.add(video1);
        video2 = v.findViewById(R.id.video2);
        imageViews.add(video2);
        video3 = v.findViewById(R.id.video3);
        imageViews.add(video3);
        video4 = v.findViewById(R.id.video4);
        imageViews.add(video4);
        video5 = v.findViewById(R.id.video5);
        imageViews.add(video5);
        video6 = v.findViewById(R.id.video6);
        imageViews.add(video6);
        video7 = v.findViewById(R.id.video7);
        imageViews.add(video7);
        video8 = v.findViewById(R.id.video8);
        imageViews.add(video8);
        video9 = v.findViewById(R.id.video9);
        imageViews.add(video9);
        video10 = v.findViewById(R.id.video10);
        imageViews.add(video10);
        addImageButton = v.findViewById(R.id.changeViewButton);
        addImageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                choosePicture();
            }
        });
        return v;
    }//end of onCreate

    private void choosePicture() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, 1);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode==1 && resultCode==RESULT_OK && null != data && data.getData()!=null){
            imageUri = data.getData();
            addPicture();
            uriArrayList.add(imageUri);
            imagesSelected++;
        }
    }

    @Override
    public void onAttach(@NonNull @NotNull Context context) {
        super.onAttach(context);
        if (context instanceof FragmentHomeListener){
            listener = (FragmentHomeListener) context;
        } else {
            throw new RuntimeException(context.toString()
            + "must implement FragmentHomeListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        listener = null;
    }

//this is the method I want to call
    public void updateImages(ArrayList<Uri> imagesArrayList){
        for (int i = 0; i < imagesArrayList.size(); i++){
            Picasso.get()
                    .load(imagesArrayList.get(i))
                    .fit().centerCrop()
                    .into(imageViews.get(i));
        }
    }

    private void addPicture(){
        Picasso.get()
                .load(imageUri)
                .fit().centerCrop()
                .into(imageViews.get(imagesSelected));
    }

    private void dataSent(){
        listener.onInputHomeSent(uriArrayList);
    }
}

Class where I want to call the method from:

package com.example.youtubethumbnailapp;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import com.squareup.picasso.Picasso;

import java.util.ArrayList;

public class HomeActivity extends AppCompatActivity implements FragmentHome.FragmentHomeListener, FragmentHistory.FragmentHistoryListener, FragmentSuggested.FragmentSuggestedListener {

    private ImageView homeButton;
    private ImageView historyButton;
    private ImageView playButton;

    private Fragment fragmentHome;
    private Fragment fragmentHistory;
    private Fragment fragmentSuggested;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        homeButton = findViewById(R.id.homeButton);
        historyButton = findViewById(R.id.historyButton);
        playButton = findViewById(R.id.playButton);

        fragmentHome = new FragmentHome();
        fragmentHistory = new FragmentHistory();
        fragmentSuggested = new FragmentSuggested();

        switchToFragmentHome();

        homeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switchToFragmentHome();
            }
        });
        historyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switchToFragmentHistory();
            }
        });
        playButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switchToFragmentSuggested();
            }
        });

    }//end of onCreate

    public void switchToFragmentHome(){
        FragmentManager manager = getSupportFragmentManager();
        manager.beginTransaction().replace(R.id.flFragment, fragmentHome).commit();
    }

    public void switchToFragmentSuggested(){
        FragmentManager manager = getSupportFragmentManager();
        manager.beginTransaction().replace(R.id.flFragment, fragmentSuggested).commit();
    }

    public void switchToFragmentHistory(){
        FragmentManager manager = getSupportFragmentManager();
        manager.beginTransaction().replace(R.id.flFragment, fragmentHistory).commit();
    }

    @Override
    public void onInputHistorySent(ArrayList<Uri> input) {
        //I want to call it from here
    }

    @Override
    public void onInputHomeSent(ArrayList<Uri> input) {

    }

    @Override
    public void onInputSuggestedSent(ArrayList<Uri> input) {

    }
}

Since I have instantiated the class, I tried fragmentHome.update but it doesn’t show up.

2

Answers


  1. you are creating new instance of fragment. Please check below code:

    FragmentHome fragmentHome = new FragmentHome();
    

    You should use it like this:

    fragmentHome = new FragmentHome();
    
    Login or Signup to reply.
  2. Currently, your updateImages method is part of an instance of the class FragmentHome. Since the method doesn’t seem to depend on anything, e.g., state, you can make the method static as follows:

    public static void updateImages(//args...){
        // Your method here
    }
    

    Within HomeActivity, you can access this static inner method directly as:

    FragmentHome.updateImages(//args...);
    

    P.S.: At the moment, you are likely getting a Non-static method 'updateImages()' cannot be referenced from a static context error.


    Note that creating and using updateImages() in this manner is not good practice. It is not "wrong", but it is not efficient in the long run and can cause bugs. (E.g., even if you just declared the method static, you’d likely get a NullPointerException because updateImages() contains a reference to imageViews, an object inside FragmentHome, which may not have been initialized when the method is called in HomeActivity.)

    If possible, you should put the independent method updateImages() in a separate utilities class, such that your UI code is as separate from your logic code as possible. This is called "separation of concerns".

    I see that you need to use Picasso to set a source image to an ImageView. To do this, you could pass in the ImageView as an argument into the method (disclaimer: if it makes sense for your use case; if it is not going to leak context; etc.), so that the updateImages() method doesn’t contain a reference to the imageViews ArrayList that sits in your FragmentHome. Also note that imageViews is currently private, since you’ve not declared it public.
    If you employ this method, your updateImages() or other methods can be reused with higher generality. But of course, there are cases where you just want a wrapper for a method you just can’t make very generalized, and that’s okay too.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search