有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在片段内创建RecylerView,而无需在Android中设置片段

我有一个片段'FR_MyItems',在它里面我使用ArrayList'myItemsList'创建了一个RecyclerView'myItemsRecyclerView'。当我导航到片段RecyclerView时,片段被创建,RecyclerView被设置好,并且工作正常

但是,现在我想使用静态方法“publicstaticvoidinsertItem(stringitemtype,stringitemname)”,从另一个类向这个Recyclerview添加项。问题是,如果我以前没有导航到framentt“FR_MyItems”,则不会设置RecyclerView,并且在尝试使用RecyclerView执行某些操作时,我会得到一个空指针预期值

所以我现在的问题是,我如何在没有导航到承载它的片段的情况下创建这个RecyclerView?在我的初始类中,所有RecyclerView变量都不是静态的,但现在我必须使它们成为静态的,这样我就可以从其他类访问它们

这里您可以看到“FR_MyItems”的Java代码:

package com.example.td.bapp;

import 安卓.content.res.Resources;
import 安卓.os.Bundle;

import 安卓x.fragment.app.Fragment;
import 安卓x.recyclerview.widget.LinearLayoutManager;
import 安卓x.recyclerview.widget.RecyclerView;

import 安卓.view.LayoutInflater;
import 安卓.view.View;
import 安卓.view.ViewGroup;

import com.example.td.bapp.databinding.MyItemsBinding;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;


public class FR_MyItems extends Fragment {




    private static RecyclerView myItemsRecyclerView;
    private static MyItemsAdapter myItemsAdapter;
    private static RecyclerView.LayoutManager myItemsLayoutManager;

    private static ArrayList<MyItemsItem> myItemsList;

    public FR_MyItems() {

    }


    public static FR_MyItems newInstance(String param1, String param2) {
        FR_MyItems fragment = new FR_MyItems();
        Bundle args = new Bundle();

        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



    }


    private MyItemsBinding binding;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        binding = MyItemsBinding.inflate(inflater, container, false);
        createExampleList();
        buildRecyclerView();
        return binding.getRoot();

    }
    public void createExampleList () {
        myItemsList = new ArrayList<MyItemsItem>();
        myItemsList.add(new MyItemsItem(R.drawable.ic_安卓, "Item 1", "C", "20:34, 12.12.20"));
        myItemsList.add(new MyItemsItem(R.drawable.ic_安卓, "Item 2", "A", "21:34"));
        myItemsList.add(new MyItemsItem(R.drawable.ic_安卓, "Item 3", "B", "20:34"));
    }

    public  void buildRecyclerView () {
        myItemsRecyclerView = binding.recyclerView;
        myItemsRecyclerView.setHasFixedSize(true);
        myItemsLayoutManager = new LinearLayoutManager(this.getContext());
        myItemsAdapter = new MyItemsAdapter(myItemsList);

        myItemsRecyclerView.setLayoutManager(myItemsLayoutManager);
        myItemsRecyclerView.setAdapter(myItemsAdapter);

        myItemsAdapter.setOnItemClickListener(new MyItemsAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                changeItemStatus(position, "Clicked");
            }
        });
    }


    public static void insertItem(String ItemType, String ItemName) {

        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm z, dd-MM-yyyy");
        sdf.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
        int position =myItemsList.size();

        String status = "good";
        if(FR_LanguageSelection.currentLanguageOfTheApp.equals(FR_LanguageSelection.LANGUAGE_GERMAN)) {
            status = "gut";
        }

        if (ItemType.equals(DataBaseEntries.ITEM2)) {
            myItemsList.add(position, new MyItemsItem(R.drawable.ic_安卓, ItemName, status, sdf.format(new Date())));
            myItemsAdapter.notifyItemInserted(position);
        }

    }



    public void removeItem (int position) {
        myItemsList.remove(position);
        myItemsAdapter.notifyItemRemoved(position);

    }

    public void changeItemStatus (int position, String newStatus) {
        myItemsList.get(position).setStatusProperty(newStatus);
        myItemsAdapter.notifyItemChanged(position);
    }
}

我非常感谢你的每一句话,也非常感谢你的帮助


共 (1) 个答案

  1. # 1 楼答案

    这个问题不是很清楚,但我会尽力帮助你

    正如其他人所说,最好使用Viewmodel、livedata和room。一开始有点困难,但后来工作起来容易多了,速度也快多了

    如果不想使用房间,可以使用viewmodel将更改通知活动中的片段

    例如:

    1. 像这样创建ViewModel类

       public class MyItemsViewModel extends AndroidViewModel {
      
           private final MutableLiveData<Boolean> refresh;
      
           public MyItemsViewModel(@NonNull Application application) {
               super(application);
               this.refresh  = new MutableLiveData<>();
           }
      
           public void setRefresh(Boolean ref) {
               this.refresh.setValue(ref);;
           }
      
           public MutableLiveData<Boolean> getRefresh() {
               return this.refresh;
           }
      
      
      
      
           public static class Factory extends ViewModelProvider.NewInstanceFactory {
      
               private final Application application;
      
               public Factory(@NonNull Application application) {
                   this.application = application;
               }
      
               @NonNull
               @Override
               public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
                   //noinspection unchecked
                   return (T) new MyItemsViewModel(this.application);
               }
           }
      
       }
      

    在活动中,你的FR_MyItems片段在哪里(可能是你的主要活动)复制/粘贴此代码(注释中只有TODO下面的代码)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
         //TODO copy this in onCreate method
         MyItemsViewModel.Factory factory = new MyItemsViewModel.Factory(getApplication());
         viewModel = new ViewModelProvider(this, factory).get(MyItemsViewModel.class);
         subscribe();
    }
    

    并复制/粘贴完成此方法

    private void subscribe() {
            viewModel.getRefresh().observe(this, refreshed -> {
                if(refreshed){
                    Toast.makeText(this, "Refreshed", Toast.LENGTH_SHORT).show();
                }
            });
        }
    
    1. 在FR_MyItems Frgament中

    复制此(竞争功能)

        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            if(getActivity() == null) return;
            MyItemsViewModel.Factory factory = new MyItemsViewModel.Factory(requireActivity().getApplication());
            viewModel = new ViewModelProvider(requireActivity(), factory).get(MyItemsViewModel.class);
            subscribe();
        }
    
        private void subscribe() {
            viewModel.getRefresh().observe(getViewLifecycleOwner(), refreshed -> {
                if(refreshed){
                    //TODO load data from sqlite database and update your MyItemsAdapter with new data list 
                    Toast.makeText(getContext(), "Refreshed Fragment", Toast.LENGTH_SHORT).show();
                    viewModel.setRefresh(false);
                }
            });
        }
    
    1. 在片段中创建新项目(如果存在)

    收到

        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
                if(getActivity() == null) return;
                MyItemsViewModel.Factory factory = new MyItemsViewModel.Factory(requireActivity().getApplication());
                viewModel = new ViewModelProvider(requireActivity(), factory).get(MyItemsViewModel.class); 
            }
        
    

    最后,当你插入新的项目时,一定要这样做

    插入后将此复制到方法中

    viewModel.setRefresh(true);
    

    它将重新加载adata并刷新你在FR_MyItems中的列表

    另外,如果不想在数据库中插入项,可以在MyItemsViewModel中创建List myItemsList创建get、set、add方法,并从片段中观察它

    将此添加到MyItemsViewModel类中

        private List<MyItemsItem>> items
        private final MutableLiveData<List<MyItemsItem>> myItemsList;
            public MyItemsViewModel(@NonNull Application application) {
                super(application);
                items= new ArrayList();
                this.refresh  = new MutableLiveData<>();
                this.myItemsList  = new MutableLiveData<>();
            }
        public addItem(MyItemsItem item){
                items.add(item);
                myItemsList.setValue(items);
            }
    //TODO create set, get and add methods for list
    

    并在你的活动或片段中观察它

    viewModel.getMyItemsList().observe(getViewLifecycleOwner(), list -> { 
        //TODO update adapter with list
    });
    

    如果希望使用notifyItemChanged,并且不希望每次都交换适配器中的数据,也可以通过其他方式使用它

    这在活动及其片段中是可能的

    如果你想在活动之间刷新列表,你必须使用room或其他方式来完成

    编辑2

    此图像仅适用于您的案例,很快将被删除

    在其他情况下,数据通过ViewModel和存储库或不在View UI中的存储库进行管理(CRUD)

    example