首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android: SQLite填充的底部导航栏片段中的回收视图不会更新

Android: SQLite填充的底部导航栏片段中的回收视图不会更新
EN

Stack Overflow用户
提问于 2020-12-17 05:51:27
回答 1查看 928关注 0票数 2

我有一个有3个片段的BottomNavigationBar。在第一个片段中,我尝试将SQLite数据放入回收视图中。它的工作很好,除了我需要切换之间的导航栏项目,以看到刷新回收between。然而,当我在postDelayed中使用一个处理程序时,如果我设置了大约1秒的延迟时间,它就会显示刷新的回收视图。0.2秒已经不能工作了。

尽管这仍然是非常通用的:有什么最佳实践吗?在我看来,我需要使用AsyncTask,但是它已经被废弃了。

谢谢!

西蒙

HomeFragment

代码语言:javascript
复制
public class HomeFragment extends Fragment {


    private HomeViewModel homeViewModel;
    private Context context;
    private CardView cardview;
    private LinearLayout.LayoutParams layoutparams;
    private TextView textview;
    private RelativeLayout relativeLayout;
    private myDbAdapter helper;
    RecyclerView myView;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        homeViewModel =
                new ViewModelProvider(this).get(HomeViewModel.class);
        View root = inflater.inflate(R.layout.fragment_home, container, false);
        
        helper  = new myDbAdapter(getContext());
        myView = (RecyclerView) root.findViewById(R.id.recyclerview_home);
        RecyclerViewAdapter3 adapter = new RecyclerViewAdapter3(new ArrayList<String>(Arrays.asList(helper.classes())));
        myView.setHasFixedSize(true);
        myView.setAdapter(adapter);
        LinearLayoutManager llm = new LinearLayoutManager(getContext());
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        myView.setLayoutManager(llm);
    

        homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });
        return root;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);



    }

    public void refresh(View v){
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            public void run() {
                myView = (RecyclerView) v.findViewById(R.id.recyclerview_home);
                helper  = new myDbAdapter(v.getContext());
                ArrayList<String> classes = new ArrayList(Arrays.asList(helper.classes()));
                ArrayList<String> subClasses = new ArrayList(Arrays.asList(helper.subClasses()));
                RecyclerViewAdapter3 adapter = new RecyclerViewAdapter3(classes);
                myView.setHasFixedSize(true);
                myView.setAdapter(adapter);
                LinearLayoutManager llm = new LinearLayoutManager(v.getContext());
                llm.setOrientation(LinearLayoutManager.VERTICAL);
                myView.setLayoutManager(llm);
            }
        }, 1000); //time in millis
    }
}

RecyclerViewAdapter3

代码语言:javascript
复制
public class RecyclerViewAdapter3 extends RecyclerView.Adapter<RecyclerViewAdapter3.MyViewHolder> {
    public ArrayList<String> classArrayList;
    public ArrayList<String> subClassArrayList;
    myDbAdapter helper;


    public RecyclerViewAdapter3(ArrayList<String> classArrayList){
        this.classArrayList = classArrayList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View listItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
        return new MyViewHolder(listItem);

    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.class.setText(classArrayList.get(position));

        holder.delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                helper = new myDbAdapter(v.getContext());
                helper.delete(classArrayList.get(position));
                HomeFragment homeFragment = new HomeFragment();
                homeFragment.refresh(v.getRootView());
            }
        });
        holder.selectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


        }});}

    @Override
    public int getItemCount() {

        return classArrayList.size();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView class;
        private Button selectButton;
        private ImageView delete;
        public MyViewHolder(View itemView) {
            super(itemView);
            class = (TextView)itemView.findViewById(R.id.name);
            selectButton = (Button) itemView.findViewById(R.id.selectButton);
            delete = (ImageView) itemView.findViewById(R.id.delete);
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-12-19 16:06:53

谢谢您发布您的代码:)

在您的代码中有一些事情可能会出错,就像现在一样,而且我无法确定是什么导致它在使用postDelay时工作。我要列举几个,你可以看看:

从你的onClick()到你的ViewHolder

HomeFragment homeFragment = new HomeFragment(); homeFragment.refresh(v.getRootView());

你不应该像这样实例化你的片段。相反,可以将回调从片段传递给适配器(例如:View.OnClickListener)。

您一直在不必要地重新实例化适配器和助手。您应该只创建一次适配器,将其设置为回收器视图适配器,并将其保存在成员变量中。

拟议解决方案

我看到您已经在使用ViewModel了,所以您可以选择一个不太容易出错的屏幕,所以我建议您将db查询逻辑移到视图模型中。如果您使用的是原始SQLite (而不是空间),您可以扩展AndroidViewModel,这样您就可以立即访问上下文。在处理homeViewModel.getText()时,您应该将classes数组公开为实时数据,观察它,并将新列表提交给适配器。

为了向适配器提交列表,我建议使用ListAdapter,这将为您提供一个submitList方法,用于提交片段中的列表,而在适配器中,您将有一个getItem(int position)方法,您可以在onBindViewHolder方法中查询该方法。

在您的片段中,它看起来如下所示:

代码语言:javascript
复制
ClassAdapter adapter = null;

View onCreateView(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState)
    View root = inflater.inflate(R.layout.fragment_home, container, false);
    
    adapter = new ClassAdapter(
        new ClassDeleteCallback() {
            @Override
            void onClassDeleted(Class class) {
                // inside view model we can modify db state, than refresh live data
                viewModel.deleteClass(class);
            }
        },
        new ClassSelectedCallback() {
            // follows same pattern of above
        }
    );
    RecyclerView rv = root.findViewById(R.id.my_rv);
    rv.setAdapter(adapter);
    rv.setLayoutManager(new LinearLayoutManager(getContext());
    
        
    homeViewModel.getClasses().observe(getViewLifecycleOwner(), new Observer<List<Class>>() {
        @Override
        public void onChanged(@Nullable List<Class> classes) {
            adapter.submitList(classes);
         }
     });

    homeViewModel.refreshClasses();
    return root;
}

我可以强烈推荐你研究这个项目,因为它涵盖了很多基础知识,这些基础知识可以导致一个更稳定的应用程序:向日葵样例应用

我认为您应该多读一些关于体系结构组件的内容,然后再看一些代码-实验室之类的东西,然后从第一步开始使用这个屏幕,因为它将比修复当前状态更容易:)

我希望这是有帮助的,不要太令人沮丧!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65335339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档