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.
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);
}
}