【问题标题】:Android BottomSheetDialogFragment data changes the data in parent FragmentAndroid BottomSheetDialogFragment 数据更改父 Fragment 中的数据
【发布时间】:2022-10-25 18:55:54
【问题描述】:

问题陈述
每当在BottomSheetDialogFragment 中修改数据时,我都会遇到数据在片段中被更改的问题

应用说明
在我的应用程序中,我有 MainActivity,它在它的 ViewPager 中托管 2 个 Fragment。应用内容的第一个片段和显示画廊视图的第二个片段(我们称之为GalleryFragment)。用户可以点击加载BottomSheet的画廊项目(我们称之为GalleryBottomSheet) - 托管RecyclerView以全屏显示画廊项目。现在,最初应用程序使用 ArrayList 提供 GalleryFragment 以显示图库项目。当用户单击 Gallery 项目时,此 ArrayList 将传递给 GalleryBottomSheet

那么发生了什么
发生的情况是,每当我从GalleryBottomSheetArrayList 中删除一个项目时,它也会自动删除GalleryFragmentArrayList 中的该项目。简而言之,来自GalleryBottomSheetArraylist 中的任何更新都会影响GalleryFragment 中的ArrayList

你想要什么
我想要分离关注点。我不希望GalleryBottomSheetArrayList 中所做的更改影响GalleryFragment 的原始ArrayList

给我看看该死的代码
为了使这个问题简洁,我只添加了代码的重要部分。

~GalleryFragment.java


    public class GalleryFragment extends Fragment {

        private RecyclerView recyclerView;
        private ArrayList<String> arrayList = new ArrayList<>(); //This is the one which will be passed to the GalleryBottomSheet
        private GalleryAdapter galleryAdapter;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_gallery, container, false);

            //setting up all the UI work...

            arrayList = FindFiles(); //FindFiles is a private function searching for all file in the dir and adding the path as a string to the arraylist
            galleryAdapter = new GalleryAdapter(getActivity()); //init the adapter
            recyclerView.setAdapter(galleryAdapter); //setting the adapter

            return view;
        }
    }

    private class GalleryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private final Activity activity;


        GalleryAdapter(Activity context) {
            this.activity = context;
        }

        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gallery_content_item, parent, false);
            return new ItemViewHolder(view);
            

        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            if(holder instanceof ItemViewHolder){
               //setting up stuff..
            }
        }

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



        private class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
            ImageView imageView;
            ItemViewHolder(View itemView) {
                super(itemView);
                imageView = itemView.findViewById(R.id.imageView);
                itemView.setOnClickListener(this);
            }

            @Override
            public void onClick(View view) {
                

                Bundle bundle = new Bundle();
                bundle.putStringArrayList("list", arrayList);

                GalleryBottomSheet galleryBottomSheet= GalleryBottomSheet.newInstance();
                galleryBottomSheet.setOnRefreshListener( new GalleryBottomSheet.GalleryInterface() {
                    @Override
                    public void onRefresh() {
                        //here the actual arrayList size reduced even though the arrayList that was modified exist in GalleryBottomSheet
                        System.out.println("CURRENT LIST SIZE: " + arrayList.size());
                    }
                });
                galleryBottomSheet.setArguments(bundle);
                galleryBottomSheet.show(getParentFragmentManager(), "galleryPager");

                
            }



    }


~GalleryBottomSheet.java

public class GalleryBottomSheet extends BottomSheetDialogFragment {

    static GalleryBottomSheet newInstance() {
        return new GalleryBottomSheet();
    }

    public interface GalleryInterface {
        void onRefresh();
    }

    private RecyclerView recyclerView;
    private ViewAdapter viewAdapter;
    private Button deleteBtn;
    private GalleryInterface galleryInterface;

    public void setOnRefreshListener( GalleryInterface galleryInterface){
        this.galleryInterface = galleryInterface;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        //.. setting up sheetDialog
        return bottomSheetDialog;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(BottomSheetDialogFragment.STYLE_NO_FRAME, R.style.GalleryBottomStyle);
    }

   @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.gallery_sheet, container, false);

        Bundle bundle = getArguments();
        ArrayList<String> filePathArr = bundle.getStringArrayList("list"); //here arrayList from GalleryFragment
        
        //Setting up all UI views...

        deleteBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int positionPager = recyclerView.computeVerticalScrollOffset(); //just for demo, in the actual app we are using addOnScrollListener for position
                filePathArr.remove(positionPager);
                viewAdapter.notifyItemRemoved(positionPager);
                galleryInterface.onRefresh(); //this is where GalleryFragment shows that the arraylist is modified too.
                Toast.makeText(getActivity(), "Deleted Successfully",Toast.LENGTH_SHORT).show();
            }
        });
        
        return view;
    }


    //setting up viewAdapter and other stuff


}

【问题讨论】:

    标签: java android android-fragments bottomsheetdialogfragment


    【解决方案1】:

    好吧,事实证明主要问题是对象通过引用存储在内存中。通过从GalleryBottomSheet 修改arrayList,它还更改了原始arrayList,因为在GalleryBottomSheet 中引用了GalleryFragment 中的确切arrayList。解决方案是在GalleryBottomSheet 中简单地初始化一个新的ArrayList

    变化自:

    ArrayList<String> filePathArr = bundle.getStringArrayList("list");
    

    至:

    ArrayList<String> filePathArr = new ArrayList<>(bundle.getStringArrayList("list"));
    
    

    【讨论】:

      猜你喜欢
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      相关资源
      最近更新 更多