Android ViewPager2 RecyclerView notificationDataSetChanged() 不工作

发布于 2025-01-09 08:04:49 字数 9236 浏览 1 评论 0原文

我正在使用 ViewPager2 和 RecyclerView 开发搜索活动。
我想要的是使用在 EditText 中输入的文本作为请求参数,响应数据反映在 RecyclerView 中。
我检查了数据正常响应,但是没有反映到视图中。
看了那么多问题和帖子,还是没能解决视图不刷新的问题。
经检查,数据已添加到RecyclerView的列表中,RecyclerViewAdapter的方法根本没有执行。

SearchActivity

public class SearchActivity extends AppCompatActivity {
    private ActivitySearchBinding binding;
    private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2};
    private final String key;
    private BusStopInterface busStopInterface;
    private PlaceholderFragment fragment;
    private SectionsPagerAdapter sectionsPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySearchBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        sectionsPagerAdapter = new SectionsPagerAdapter(SearchActivity.this);
        ViewPager2 pager = binding.viewPager;
        pager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = binding.tabs;
        EditText searchBox = binding.searchBox;
        fragment = new PlaceholderFragment();
        new TabLayoutMediator(tabs, pager, (tab, position) -> tab.setText(TAB_TITLES[position])).attach();

        RetrofitClient retrofitClient = RetrofitClient.getInstance();
        busStopInterface = RetrofitClient.getRetrofitInterface();

        searchBox.addTextChangedListener(textWatcher);
        pager.registerOnPageChangeCallback(pageChangeCallback);
    }

    ViewPager2.OnPageChangeCallback pageChangeCallback = new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);
            if (position == 0) {
                Log.d("position", "Bus stop");;
            } else if (position == 1) {
                Log.d("position", "Bus");;
            }
        }
    };

    TextWatcher textWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
        busStopInterface.getBusStop(key, 25, "json", 25, s.toString()).enqueue(new Callback<Example>() {
            @Override
            public void onResponse(Call<Example> call, Response<Example> response) {
                if (response.isSuccessful()) {
                    Example example = response.body();
                    Items items = example.getResult().getBody().getItems();  //I checked the data response.
                    fragment.resetRecyclerView(items.getItem());
                    sectionsPagerAdapter.notifyDataSetChanged();
                    Log.d("retrofit", "Data fetch success");
                } else {
                    Log.d("retrofit", "Data fetch fail");
                }
            }

            @Override
            public void onFailure(Call<Example> call, Throwable t) {
                Log.d("retrofit", t.getMessage());
            }
        });
        }
    };
}

PlaceholderFragment

public class PlaceholderFragment extends Fragment {

    private static final String ARG_SECTION_NUMBER = "section_number";

    private PageViewModel pageViewModel;
    private FragmentSearchBinding binding;

    public List<BusStopItem> items = new ArrayList<>();
    public SearchRecyclerViewAdapter adapter = new SearchRecyclerViewAdapter(items);

    public static PlaceholderFragment newInstance(int index) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle bundle = new Bundle();
        bundle.putInt(ARG_SECTION_NUMBER, index);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pageViewModel = new ViewModelProvider(this).get(PageViewModel.class);
        int index = 1;
        if (getArguments() != null) {
            index = getArguments().getInt(ARG_SECTION_NUMBER);
        }
        pageViewModel.setIndex(index);
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        binding = FragmentSearchBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        pageViewModel.getIndex().observe(getViewLifecycleOwner(), new Observer<Integer>() {
            @Override
            public void onChanged(Integer index) {
                if (index == 1) {
                    adapter.setItemViewType(SearchRecyclerViewAdapter.VIEWTYPE_BUS_STOP);
                } else if (index == 2) {
                    adapter.setItemViewType(SearchRecyclerViewAdapter.VIEWTYPE_BUS);
                }
            }
        });
        return root;
    }

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

        RecyclerView recyclerView = binding.searchRecyclerView;
        recyclerView.setAdapter(adapter);
        recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), 1));
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    public void resetRecyclerView(List<BusStopItem> newItems) {
        items.clear();
        items.addAll(newItems);
        adapter.notifyDataSetChanged();
    }
}

SearchRecyclerViewAdapter

public class SearchRecyclerViewAdapter extends RecyclerView.Adapter<SearchRecyclerViewAdapter.ViewHolder> {

    public static final int VIEWTYPE_BUS_STOP = 0;
    public static final int VIEWTYPE_BUS = 1;
    int mItemViewType;

    List<BusStopItem> busStopItems;

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView busStopName, busStopId, busStopLocation, busName, busArea, busRoute;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            busStopName = itemView.findViewById(R.id.busStopName);
            busStopId = itemView.findViewById(R.id.busStopId);
            busStopLocation = itemView.findViewById(R.id.busStopLocation);
            busName = itemView.findViewById(R.id.busName);
            busArea = itemView.findViewById(R.id.busArea);
            busRoute = itemView.findViewById(R.id.busRoute);
        }

        public void setBusStopItem(BusStopItem item) {
            busStopName.setText(item.getNodenm());
            if(item.getNodeno() != null) {
                busStopId.setText(item.getNodeno().toString());
            }
        }

    }

    public SearchRecyclerViewAdapter(List<BusStopItem> busStopItems) {
        this.busStopItems = busStopItems;
    }

    public void setItemViewType(int viewType) {
        mItemViewType = viewType;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = null;

        if (viewType == VIEWTYPE_BUS_STOP) {
            view = inflater.inflate(R.layout.search_bus_stop_item, parent, false);
        } else if (viewType == VIEWTYPE_BUS) {
            view = inflater.inflate(R.layout.search_bus_item, parent, false);
        }

        SearchRecyclerViewAdapter.ViewHolder vh = new SearchRecyclerViewAdapter.ViewHolder(view);

        return vh;
    }

    @Override
    public int getItemViewType(int position) {
        return mItemViewType;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        if (mItemViewType == VIEWTYPE_BUS_STOP) {
            holder.setBusStopItem(busStopItems.get(position));
        } else if (mItemViewType == VIEWTYPE_BUS) {
        }
    }

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

}

SectionsPagerAdapter

public class SectionsPagerAdapter extends FragmentStateAdapter {

    public SectionsPagerAdapter(FragmentActivity fa) {
        super(fa);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return PlaceholderFragment.newInstance(position + 1);
    }

    @Override
    public int getItemCount() {
        return 2;
    }
}

我尝试过

public void resetRecyclerView(List<BusStopItem> newItems) {
    items.clear();
    items.addAll(newItems);
    adapter.notifyDataSetChanged();
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.detach(this).attach(this).commit();
}

java.lang.NullPointerException:尝试调用虚拟方法 'androidx.fragment.app.FragmentTransaction空对象引用上的 androidx.fragment.app.FragmentManager.beginTransaction()'

I'm using ViewPager2 and RecyclerView develop to Search activity.
What I want is use text entered in EditText as request parameter and response data is reflected in the RecyclerView.
I checked that the data was responded normally, but it was not reflected in the view.
I read so many questions and posts, but I couldn't solve the problem that the view was not refreshed.
Upon checking, data was added to the list of RecyclerView, the methods of the RecyclerView Adapter were not executed at all.

SearchActivity

public class SearchActivity extends AppCompatActivity {
    private ActivitySearchBinding binding;
    private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2};
    private final String key;
    private BusStopInterface busStopInterface;
    private PlaceholderFragment fragment;
    private SectionsPagerAdapter sectionsPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySearchBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        sectionsPagerAdapter = new SectionsPagerAdapter(SearchActivity.this);
        ViewPager2 pager = binding.viewPager;
        pager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = binding.tabs;
        EditText searchBox = binding.searchBox;
        fragment = new PlaceholderFragment();
        new TabLayoutMediator(tabs, pager, (tab, position) -> tab.setText(TAB_TITLES[position])).attach();

        RetrofitClient retrofitClient = RetrofitClient.getInstance();
        busStopInterface = RetrofitClient.getRetrofitInterface();

        searchBox.addTextChangedListener(textWatcher);
        pager.registerOnPageChangeCallback(pageChangeCallback);
    }

    ViewPager2.OnPageChangeCallback pageChangeCallback = new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);
            if (position == 0) {
                Log.d("position", "Bus stop");;
            } else if (position == 1) {
                Log.d("position", "Bus");;
            }
        }
    };

    TextWatcher textWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
        busStopInterface.getBusStop(key, 25, "json", 25, s.toString()).enqueue(new Callback<Example>() {
            @Override
            public void onResponse(Call<Example> call, Response<Example> response) {
                if (response.isSuccessful()) {
                    Example example = response.body();
                    Items items = example.getResult().getBody().getItems();  //I checked the data response.
                    fragment.resetRecyclerView(items.getItem());
                    sectionsPagerAdapter.notifyDataSetChanged();
                    Log.d("retrofit", "Data fetch success");
                } else {
                    Log.d("retrofit", "Data fetch fail");
                }
            }

            @Override
            public void onFailure(Call<Example> call, Throwable t) {
                Log.d("retrofit", t.getMessage());
            }
        });
        }
    };
}

PlaceholderFragment

public class PlaceholderFragment extends Fragment {

    private static final String ARG_SECTION_NUMBER = "section_number";

    private PageViewModel pageViewModel;
    private FragmentSearchBinding binding;

    public List<BusStopItem> items = new ArrayList<>();
    public SearchRecyclerViewAdapter adapter = new SearchRecyclerViewAdapter(items);

    public static PlaceholderFragment newInstance(int index) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle bundle = new Bundle();
        bundle.putInt(ARG_SECTION_NUMBER, index);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pageViewModel = new ViewModelProvider(this).get(PageViewModel.class);
        int index = 1;
        if (getArguments() != null) {
            index = getArguments().getInt(ARG_SECTION_NUMBER);
        }
        pageViewModel.setIndex(index);
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        binding = FragmentSearchBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        pageViewModel.getIndex().observe(getViewLifecycleOwner(), new Observer<Integer>() {
            @Override
            public void onChanged(Integer index) {
                if (index == 1) {
                    adapter.setItemViewType(SearchRecyclerViewAdapter.VIEWTYPE_BUS_STOP);
                } else if (index == 2) {
                    adapter.setItemViewType(SearchRecyclerViewAdapter.VIEWTYPE_BUS);
                }
            }
        });
        return root;
    }

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

        RecyclerView recyclerView = binding.searchRecyclerView;
        recyclerView.setAdapter(adapter);
        recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), 1));
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    public void resetRecyclerView(List<BusStopItem> newItems) {
        items.clear();
        items.addAll(newItems);
        adapter.notifyDataSetChanged();
    }
}

SearchRecyclerViewAdapter

public class SearchRecyclerViewAdapter extends RecyclerView.Adapter<SearchRecyclerViewAdapter.ViewHolder> {

    public static final int VIEWTYPE_BUS_STOP = 0;
    public static final int VIEWTYPE_BUS = 1;
    int mItemViewType;

    List<BusStopItem> busStopItems;

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView busStopName, busStopId, busStopLocation, busName, busArea, busRoute;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            busStopName = itemView.findViewById(R.id.busStopName);
            busStopId = itemView.findViewById(R.id.busStopId);
            busStopLocation = itemView.findViewById(R.id.busStopLocation);
            busName = itemView.findViewById(R.id.busName);
            busArea = itemView.findViewById(R.id.busArea);
            busRoute = itemView.findViewById(R.id.busRoute);
        }

        public void setBusStopItem(BusStopItem item) {
            busStopName.setText(item.getNodenm());
            if(item.getNodeno() != null) {
                busStopId.setText(item.getNodeno().toString());
            }
        }

    }

    public SearchRecyclerViewAdapter(List<BusStopItem> busStopItems) {
        this.busStopItems = busStopItems;
    }

    public void setItemViewType(int viewType) {
        mItemViewType = viewType;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = null;

        if (viewType == VIEWTYPE_BUS_STOP) {
            view = inflater.inflate(R.layout.search_bus_stop_item, parent, false);
        } else if (viewType == VIEWTYPE_BUS) {
            view = inflater.inflate(R.layout.search_bus_item, parent, false);
        }

        SearchRecyclerViewAdapter.ViewHolder vh = new SearchRecyclerViewAdapter.ViewHolder(view);

        return vh;
    }

    @Override
    public int getItemViewType(int position) {
        return mItemViewType;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        if (mItemViewType == VIEWTYPE_BUS_STOP) {
            holder.setBusStopItem(busStopItems.get(position));
        } else if (mItemViewType == VIEWTYPE_BUS) {
        }
    }

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

}

SectionsPagerAdapter

public class SectionsPagerAdapter extends FragmentStateAdapter {

    public SectionsPagerAdapter(FragmentActivity fa) {
        super(fa);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return PlaceholderFragment.newInstance(position + 1);
    }

    @Override
    public int getItemCount() {
        return 2;
    }
}

What I tried

public void resetRecyclerView(List<BusStopItem> newItems) {
    items.clear();
    items.addAll(newItems);
    adapter.notifyDataSetChanged();
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.detach(this).attach(this).commit();
}

java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.fragment.app.FragmentTransaction androidx.fragment.app.FragmentManager.beginTransaction()' on a null object reference

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往日 2025-01-16 08:04:49

您创建 PlaceholderFragment 但未将其添加到 FragmmentManger

fragment = new PlaceholderFragment();

When `busStopInterface.getBusStop()` get return, you set data to

私有PlaceholderFragment片段

和片段不附加到任何 Activity,因此 UI 不会刷新。
您应该从 SectionsPagerAdapter 获取 PlaceholderFragment 实例或为 SectionsPagerAdapter 创建 PlaceholderFragment 实例,然后您可以设置数据到真正的 PlaceholderFragment

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySearchBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        fragments = new ArrayList<>();
        fragments.add(PlaceholderFragment.newInstance(1));
        fragments.add(PlaceholderFragment.newInstance(2));
        sectionsPagerAdapter = new SectionsPagerAdapter(SearchActivity.this, fragments);
        ViewPager2 pager = binding.viewPager;
        pager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = binding.tabs;
        EditText searchBox = binding.searchBox;
        
        new TabLayoutMediator(tabs, pager, (tab, position) -> tab.setText(TAB_TITLES[position])).attach();

        RetrofitClient retrofitClient = RetrofitClient.getInstance();
        busStopInterface = RetrofitClient.getRetrofitInterface();

        searchBox.addTextChangedListener(textWatcher);
        pager.registerOnPageChangeCallback(pageChangeCallback);
    }
public class SectionsPagerAdapter extends FragmentStateAdapter {

    private final List<PlaceholderFragment> fragments;

    public SectionsPagerAdapter(FragmentActivity fa, List<PlaceholderFragment> fragments) {
        super(fa);
        this.fragments = fragments;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragments.get(position);
    }

    @Override
    public int getItemCount() {
        return 2;
    }
}
busStopInterface.getBusStop(key, 25, "json", 25, s.toString()).enqueue(new Callback<Example>() {
                @Override
                public void onResponse(Call<Example> call, Response<Example> response) {
                    if (response.isSuccessful()) {
                        Example example = response.body();
                        Items items = example.getResult().getBody().getItems();  //I checked the data response.
                        fragments.get(1).resetRecyclerView(items.getItem());
                        Log.d("retrofit", "Data fetch success");
                    } else {
                        Log.d("retrofit", "Data fetch fail");
                    }
                }

                @Override
                public void onFailure(Call<Example> call, Throwable t) {
                    Log.d("retrofit", t.getMessage());
                }
            });

PS。消除

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(this).attach(this).commit();

You create PlaceholderFragment but not add it to FragmmentManger.

fragment = new PlaceholderFragment();

When `busStopInterface.getBusStop()` get return, you set data to

private PlaceholderFragment fragment

and fragment is not attach to any Activity,so UI dosen't refresh.
You should get PlaceholderFragment instance from SectionsPagerAdapter or create PlaceholderFragment instance for SectionsPagerAdapter, and you can set data to real PlaceholderFragment

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySearchBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        fragments = new ArrayList<>();
        fragments.add(PlaceholderFragment.newInstance(1));
        fragments.add(PlaceholderFragment.newInstance(2));
        sectionsPagerAdapter = new SectionsPagerAdapter(SearchActivity.this, fragments);
        ViewPager2 pager = binding.viewPager;
        pager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = binding.tabs;
        EditText searchBox = binding.searchBox;
        
        new TabLayoutMediator(tabs, pager, (tab, position) -> tab.setText(TAB_TITLES[position])).attach();

        RetrofitClient retrofitClient = RetrofitClient.getInstance();
        busStopInterface = RetrofitClient.getRetrofitInterface();

        searchBox.addTextChangedListener(textWatcher);
        pager.registerOnPageChangeCallback(pageChangeCallback);
    }
public class SectionsPagerAdapter extends FragmentStateAdapter {

    private final List<PlaceholderFragment> fragments;

    public SectionsPagerAdapter(FragmentActivity fa, List<PlaceholderFragment> fragments) {
        super(fa);
        this.fragments = fragments;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragments.get(position);
    }

    @Override
    public int getItemCount() {
        return 2;
    }
}
busStopInterface.getBusStop(key, 25, "json", 25, s.toString()).enqueue(new Callback<Example>() {
                @Override
                public void onResponse(Call<Example> call, Response<Example> response) {
                    if (response.isSuccessful()) {
                        Example example = response.body();
                        Items items = example.getResult().getBody().getItems();  //I checked the data response.
                        fragments.get(1).resetRecyclerView(items.getItem());
                        Log.d("retrofit", "Data fetch success");
                    } else {
                        Log.d("retrofit", "Data fetch fail");
                    }
                }

                @Override
                public void onFailure(Call<Example> call, Throwable t) {
                    Log.d("retrofit", t.getMessage());
                }
            });

PS. remove

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(this).attach(this).commit();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文