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
you are creating new instance of fragment. Please check below code:
You should use it like this:
Currently, your
updateImages
method is part of an instance of the classFragmentHome
. Since the method doesn’t seem to depend on anything, e.g., state, you can make the method static as follows:Within
HomeActivity
, you can access this static inner method directly as: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 aNullPointerException
becauseupdateImages()
contains a reference toimageViews
, an object insideFragmentHome
, which may not have been initialized when the method is called inHomeActivity
.)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 theimageViews
ArrayList that sits in yourFragmentHome
. Also note thatimageViews
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.