Search code examples
android-custom-view

Passing data to CustomView via method


I've created a custom view that extends LinearLayoutCompat. The view works fine if I hard code the data variables within the constructor, however, I'm wanting to pass data to this view from various different fragments, however I get null object errors when I do this.

fragment_profile:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

...

            <com.topper.topper.ui.profile.ProfileSummaryCardView
                android:id="@+id/friendsummaryclasstest"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:elevation="0dp"
                android:orientation="vertical" />

...

    <data>

        <variable
            name="ProfileViewModel"
            type="com.topper.topper.ui.profile.ProfileViewModel" />
    </data>
</layout>

ProfileFragment:

public class ProfileFragment extends Fragment {

    private ProfileViewModel mViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        FragmentProfileBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_profile, container, false);

        mViewModel = ViewModelProviders.of(this).get(ProfileViewModel.class);
        binding.setProfileViewModel(mViewModel);

        binding.getProfileViewModel();

        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NotNull View view, @Nullable Bundle savedInstanceState) {

        ProfileSummaryCardView friendSummaryCard = view.findViewById(R.id.friendsummaryclasstest);
        friendSummaryCard.setParameters(getString(R.string.title_friends), mViewModel.getFriendNames(), mViewModel.getFriendPics());

    }
}

ProfileSummaryCardView (CustomView):

public class ProfileSummaryCardView extends LinearLayoutCompat {

    private String cardTitle;
    private ArrayList<String> imgURLs;
    private String[] names;
    private Context mContext;

    public ProfileSummaryCardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;

        final ViewProfileSummaryCardBinding binding = ViewProfileSummaryCardBinding.inflate(LayoutInflater.from(mContext), this, true);

        if (imgURLs.size() == 0) {
            binding.profileCard.setVisibility(View.GONE);
        } else if (imgURLs.size() <= 4) {
            binding.profileCardGridrowb.setVisibility(View.GONE);
        }

        binding.profileCardTitle.setText(cardTitle);

        ImageView[] imageViewList = {binding.profileCardIImg,
                binding.profileCardIiImg,
                binding.profileCardIiiImg,
                binding.profileCardIvImg,
                binding.profileCardVImg,
                binding.profileCardViImg,
                binding.profileCardViiImg,
                binding.profileCardViiImg};

        TextView[] textViewList = {binding.profileCardIName,
                binding.profileCardIiName,
                binding.profileCardIiiName,
                binding.profileCardIvName,
                binding.profileCardVName,
                binding.profileCardViName,
                binding.profileCardViiName,
                binding.profileCardViiName};

        for (int i = 0; i < imgURLs.size(); i++) {
            gridImageSetup(imageViewList[i], imgURLs.get(i));
            textViewList[i].setText(names[i]);
        }
    }

    public void setParameters(String pTitle, String[] pNameArray, ArrayList pPicURLArray) {
        this.cardTitle = pTitle;
        this.imgURLs = pPicURLArray;
        this.names = pNameArray;
        invalidate();
    }

    private void gridImageSetup(ImageView target, String url) {

        Glide.with(this)
                .load(url)
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .transform(new FitCenter(), new RoundedCorners(25))
                .into(target);
    }
}

It seems like the customview is initialized before the setParameters method call I make in my fragment as the data objects are null when I try and run the above.

Any help would be greatly appreciated.


Solution

  • So, I figured out the fix for this issue and it's was a face-palm moment as it was a really simple fix.

    I cut and pasted everything in the constructor of the custom view (except the inflate) into the setParameters method, as below:

    public class ProfileSummaryCardView extends LinearLayoutCompat {
    
        private String cardTitle;
        private ArrayList<String> imgURLs;
        private String[] names;
        private Context mContext;
    
        public ProfileSummaryCardView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mContext = context;
    
            final ViewProfileSummaryCardBinding binding = ViewProfileSummaryCardBinding.inflate(LayoutInflater.from(mContext), this, true);
    
        }
    
        public void setParameters(String pTitle, String[] pNameArray, ArrayList pPicURLArray) {
            this.cardTitle = pTitle;
            this.imgURLs = pPicURLArray;
            this.names = pNameArray;
    
            if (imgURLs.size() == 0) {
                binding.profileCard.setVisibility(View.GONE);
            } else if (imgURLs.size() <= 4) {
                binding.profileCardGridrowb.setVisibility(View.GONE);
            }
    
            binding.profileCardTitle.setText(cardTitle);
    
            ImageView[] imageViewList = {binding.profileCardIImg,
                    binding.profileCardIiImg,
                    binding.profileCardIiiImg,
                    binding.profileCardIvImg,
                    binding.profileCardVImg,
                    binding.profileCardViImg,
                    binding.profileCardViiImg,
                    binding.profileCardViiImg};
    
            TextView[] textViewList = {binding.profileCardIName,
                    binding.profileCardIiName,
                    binding.profileCardIiiName,
                    binding.profileCardIvName,
                    binding.profileCardVName,
                    binding.profileCardViName,
                    binding.profileCardViiName,
                    binding.profileCardViiName};
    
            for (int i = 0; i < imgURLs.size(); i++) {
                gridImageSetup(imageViewList[i], imgURLs.get(i));
                textViewList[i].setText(names[i]);
            }
    
            invalidate();
        }
    
        private void gridImageSetup(ImageView target, String url) {
    
            Glide.with(this)
                    .load(url)
                    .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                    .transform(new FitCenter(), new RoundedCorners(25))
                    .into(target);
        }
    }