在RecyclerViewHolder中调用notifyDataSetChange的问题

时间:2018-04-24 11:32:50

标签: java android android-fragments android-viewholder

我在使用新数据更新RecyclerView时遇到问题。如果我在第一个选项卡中按下CardView上的确认按钮,该卡应该被添加到第二个选项卡,但它不会在那里更新它,直到我旋转屏幕。我通过阅读文本文件获取卡的数据。我建议在将新数据添加到文本文件后如何调用notifyDataSetChange方法。我已经尝试了一切,我得到的是NullPointerExceptions。 RecyclerViews是碎片,我使用FragementStatePagerAdapter。

我会把我的一些课程放在这里。询问您是否需要更多信息。

RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
    private List<String> mListTitle;
    private List<String> mListDesc;
    private List<String> mListPoints;
    private List<String> mListDates;
    private String fragment_tag;

    public RecyclerViewAdapter() {
    }

    public RecyclerViewAdapter(List<List<String>> super_list, String tag) {
        this.mListTitle = super_list.get(0);
        this.mListDesc = super_list.get(1);
        this.mListPoints = super_list.get(2);
        this.mListDates = super_list.get(3);
        fragment_tag = tag;
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        return new RecyclerViewHolder(inflater, parent, fragment_tag);


    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        holder.mTitleText.setText(mListTitle.get(position));
        holder.mDescText.setText(mListDesc.get(position));
        holder.mPointsText.setText(mListPoints.get(position));
        if (fragment_tag.equals("completed")) {
            holder.mDateText.setText(mListDates.get(position));
        }

    }

    @Override
    public int getItemCount() {
        return mListTitle.size();
    }


}

class RecyclerViewHolder extends RecyclerView.ViewHolder {
    RecyclerView recyclerView;
    RecyclerViewAdapter mAdapter;
    public TextView mTitleText, mDescText, mDateText, mPointsText, popupTitle;
    public Button mConfButton, popCancelBtn, popAcceptBtn;

    public RecyclerViewHolder(View itemView) {
        super(itemView);
    }

    public RecyclerViewHolder(final LayoutInflater inflater, final ViewGroup container, String tag) {
        // Inflating the card layout depending on the tag parameter.
        super(inflater.inflate
                ((tag.equals("challenges")) ? R.layout.card_view_chall : R.layout.card_view_comp, container,
                        false));
        mTitleText = itemView.findViewById(R.id.title_holder);
        mDescText = itemView.findViewById(R.id.desc_holder);
        mPointsText = itemView.findViewById(R.id.points_holder);
        mDateText = itemView.findViewById(R.id.date_holder);


        if (tag.equals("challenges")) {
            mConfButton = itemView.findViewById(R.id.card_conf_button);

            mConfButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Setting the layout inflater for popup window.
                    LayoutInflater pInflater = (LayoutInflater) itemView.getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
                    ViewGroup container1 = (ViewGroup) pInflater.inflate(R.layout.confirmation_popup, null);
                    final PopupWindow popupWindow = new PopupWindow(container1, 700, 600, true);

                    popupTitle = container1.findViewById(R.id.popuptext);
                    popAcceptBtn = container1.findViewById(R.id.accept_button);
                    popCancelBtn = container1.findViewById(R.id.cancel_button);
                    popupTitle.setText(mTitleText.getText().toString());

                    // Dismisses the popup window
                    popCancelBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            popupWindow.dismiss();
                        }
                    });

                    // Click listener for dialog accept button.
                    popAcceptBtn.setOnClickListener(new View.OnClickListener() {
                        String date;

                        @Override
                        public void onClick(View view) {
                            List<String> list = new ArrayList<>();
                            list.add(mTitleText.getText().toString());
                            list.add(mDescText.getText().toString());
                            list.add(mPointsText.getText().toString());
                            list.add(date = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date()));
                            // Saving data from current card into the completed challenges list.
                            TempDataReader reader = new TempDataReader(itemView.getContext());
                            new TempDataReader(itemView.getContext()).saveFile(list);
                            // I want to notify the dataset change here if possible!

                            popupWindow.dismiss();
                        }
                    });
                    popupWindow.showAtLocation(itemView, Gravity.CENTER, 25, 100);
                }
            });

        }

    }
}

SectionsPagerAdapter.java

public class SectionsPagerAdapter extends FragmentStatePagerAdapter{
    private ViewPager viewPager;
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();



    public void addFragment(Fragment fragment, String title){
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }


    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();


    }
}

CompletedFragment.java

public class CompletedFragment extends Fragment {
    RecyclerView recyclerView;
    RecyclerViewAdapter adapter;
    public Fragment newInstance() {
        return new CompletedFragment();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.completed_fragment, container, false);
        recyclerView = view.findViewById(R.id.completed_frag);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        TempDataReader reader = new TempDataReader(getActivity());
        List<List<String>> super_list = reader.readCompFile();

        if(super_list == null || super_list.size() < 1){
            return null;
        } else{
            adapter = new RecyclerViewAdapter(super_list,"completed");
            recyclerView.setAdapter(adapter);
            return view;
        }
    }
}

编辑:
添加了第二个片段的代码,该代码应该在RecyclerViewHolder类的onClick之后更新。

2 个答案:

答案 0 :(得分:0)

您必须在适配器中添加一个用于添加数据的功能:

public void addData(String title, String desc, String point, String date) {
    this.mListTitle.add(title);
    this.mListDesc.add(desc);
    this.mListPoints.add(point);
    this.mListDates.add(date);

    notifyDataSetChanged();
}

如果您想启用动画,请致电notifyItemInserted()而不是notifyDataSetChanged();

为每个列表添加String非常重要,因为在onBindViewHolder()中,您可以使用list.get(position)从每个列表中显示项目。否则你会得到IndexOutOfBoundsException

答案 1 :(得分:0)

您可以创建一个界面并用作回调。将其作为RecyclerViewAdapter的参数发送,然后发送到RecyclerViewHolder。当应该添加项目时,您可以调用回调函数,该回调函数将返回到您的片段。在那里,您可以再次读取该文件并调用notifyDataSetChanged。

我知道我的解释非常糟糕,所以我会尝试更改你的代码,以便我按照我说的那样做:

这将是您的RecyclerViewAdapter:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
    private List<String> mListTitle;
    private List<String> mListDesc;
    private List<String> mListPoints;
    private List<String> mListDates;
    private String fragment_tag;

    private Runnable callback;

    public RecyclerViewAdapter() {
    }

    public RecyclerViewAdapter(List<List<String>> super_list, String tag, Runnable callBack) { 
//add the callback here(Runnable) and save it into a local variable

        this.callback=callback;

        this.mListTitle = super_list.get(0);
        this.mListDesc = super_list.get(1);
        this.mListPoints = super_list.get(2);
        this.mListDates = super_list.get(3);
        fragment_tag = tag;
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        return new RecyclerViewHolder(inflater, parent, fragment_tag, callback);
//send the callback to your viewHolder


    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        holder.mTitleText.setText(mListTitle.get(position));
        holder.mDescText.setText(mListDesc.get(position));
        holder.mPointsText.setText(mListPoints.get(position));
        if (fragment_tag.equals("completed")) {
            holder.mDateText.setText(mListDates.get(position));
        }

    }

    @Override
    public int getItemCount() {
        return mListTitle.size();
    }


}

class RecyclerViewHolder extends RecyclerView.ViewHolder {
    RecyclerView recyclerView;
    RecyclerViewAdapter mAdapter;
    public TextView mTitleText, mDescText, mDateText, mPointsText, popupTitle;
    public Button mConfButton, popCancelBtn, popAcceptBtn;

    public RecyclerViewHolder(View itemView) {
        super(itemView);
    }

    public RecyclerViewHolder(final LayoutInflater inflater, final ViewGroup container, String tag, Runnable callback) {
//ADD the callback to the parameters list here

        // Inflating the card layout depending on the tag parameter.
        super(inflater.inflate
                ((tag.equals("challenges")) ? R.layout.card_view_chall : R.layout.card_view_comp, container,
                        false));
        mTitleText = itemView.findViewById(R.id.title_holder);
        mDescText = itemView.findViewById(R.id.desc_holder);
        mPointsText = itemView.findViewById(R.id.points_holder);
        mDateText = itemView.findViewById(R.id.date_holder);


        if (tag.equals("challenges")) {
            mConfButton = itemView.findViewById(R.id.card_conf_button);

            mConfButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Setting the layout inflater for popup window.
                    LayoutInflater pInflater = (LayoutInflater) itemView.getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
                    ViewGroup container1 = (ViewGroup) pInflater.inflate(R.layout.confirmation_popup, null);
                    final PopupWindow popupWindow = new PopupWindow(container1, 700, 600, true);

                    popupTitle = container1.findViewById(R.id.popuptext);
                    popAcceptBtn = container1.findViewById(R.id.accept_button);
                    popCancelBtn = container1.findViewById(R.id.cancel_button);
                    popupTitle.setText(mTitleText.getText().toString());

                    // Dismisses the popup window
                    popCancelBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            popupWindow.dismiss();
                        }
                    });

                    // Click listener for dialog accept button.
                    popAcceptBtn.setOnClickListener(new View.OnClickListener() {
                        String date;

                        @Override
                        public void onClick(View view) {
                            List<String> list = new ArrayList<>();
                            list.add(mTitleText.getText().toString());
                            list.add(mDescText.getText().toString());
                            list.add(mPointsText.getText().toString());
                            list.add(date = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date()));
                            // Saving data from current card into the completed challenges list.
                            TempDataReader reader = new TempDataReader(itemView.getContext());
                            new TempDataReader(itemView.getContext()).saveFile(list);
                            // I want to notify the dataset change here if possible!
//call the callback
callback.run();

                            popupWindow.dismiss();
                        }
                    });
                    popupWindow.showAtLocation(itemView, Gravity.CENTER, 25, 100);
                }
            });

        }

    }
}

这将是你的片段:

public class CompletedFragment extends Fragment {
    RecyclerView recyclerView;
    RecyclerViewAdapter adapter;
    public Fragment newInstance() {
        return new CompletedFragment();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.completed_fragment, container, false);
        recyclerView = view.findViewById(R.id.completed_frag);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        TempDataReader reader = new TempDataReader(getActivity());
        List<List<String>> super_list = reader.readCompFile();

        if(super_list == null || super_list.size() < 1){
            return null;
        } else{
            adapter = new RecyclerViewAdapter(super_list,"completed", new Runnable() {
        @Override
        public void run() {
            //here read the list again and call notifyDataSetChanged on your recycler
        }
    });
);
            recyclerView.setAdapter(adapter);
            return view;
        }
    }
}

希望它有所帮助,它适合你。如果我做错了什么,请告诉我,我现在无法运行代码......

已编辑,我忘了在回调中添加代码