通过方法将数据传递给 CustomView

Passing data to CustomView via method

我创建了一个扩展 LinearLayoutCompat 的自定义视图。如果我在构造函数中硬编码数据变量,视图工作正常,但是,我想将数据从各种不同的片段传递到这个视图,但是当我这样做时我得到空对象错误。

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(自定义视图):

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

自定义视图似乎在我在片段中调用 setParameters 方法之前初始化,因为当我尝试 运行 以上时数据对象为空。

如有任何帮助,我们将不胜感激。

所以,我找到了解决这个问题的方法,这是一个非常简单的修复方法,这让我很吃惊。

我将自定义视图的构造函数(inflate 除外)中的所有内容剪切并粘贴到 setParameters 方法中,如下所示:

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