【问题标题】:How to update recyclerview in the second tab in viewpager from first tab?如何从第一个选项卡更新 viewpager 的第二个选项卡中的 recyclerview?
【发布时间】:2016-03-19 11:53:11
【问题描述】:

我目前面临的一个问题是,如果用户在他们的时间表中添加了一些内容,则应该在第二个标签Current Timetable 中的recyclerview 中刷新它。但是,它永远不会更新,用户必须返回主菜单,返回Timetables 活动,然后选择Current Timetable。我相信这与我的ViewPager 及其适配器有关。我只是看不出哪里出错了,我确信这是我想念的简单事情。请您修改我的代码以使其正常工作

这是我的代码: 浏览器类

public class Timetables extends AppCompatActivity{
    TabLayout tabLayout;
    ViewPager viewPager;
    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.timetables);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        TimetablesAdapter timetablesAdapter = new TimetablesAdapter(getSupportFragmentManager(), Timetables.this);
        viewPager.setAdapter(timetablesAdapter);
        viewPager.setOffscreenPageLimit(2);
        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                //viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                //viewPager.setCurrentItem(tab.getPosition());
            }
        });
    }
}

fragmentpageradapter 类:

public class TimestableAdapter extends FragmentPagerAdapter{

    String tabNames[] = new String[] {"All timetables", "Current Timetable", "Expired"};
    Context context;

    public TimestableAdapter(FragmentManager fragmentManager, Context context){
        super(fragmentManager);
        this.context = context;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position){
            case 0:
                return new AllTimetables();
            case 1:
                return new CurrentTimetables();
            case 2:
                return new ExpiredTimetables();
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return tabNames.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabNames[position];
    }
}

这是CurrentTimetable 类:

public class CurrentTimetables extends Fragment {
    RecyclerView recyclerView;
    static MusicRecyclerAdapter adapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<Timetables> list;

    public CurrentTimetables(){

    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.currenttimetable, container, false);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.timetablerecyclerView);
        recyclerView.setHasFixedSize(true);
        list = new ArrayList<Timetables>();
        adapter = new MusicRecyclerAdapter(list, CurrentTimetables.this);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(adapter);
        tabBackground = new TabBackground(CurrentTimetables.this, list, spinnerItems, adapter, spinnerAdapter);
        tabBackground.populateConditionsList();
        inputs = new ArrayList<>();
        populate();
        return rootView;
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {

    }

    @Override
    public void onStart() {
        super.onStart();
    }

    public void populate(){
        String dbURL = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        RequestQueue requestQueue = Volley.newRequestQueue(fragment.getActivity());
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
                (dbURL, new Response.Listener<JSONArray>(){

                    @Override
                    public void onResponse(JSONArray jsonArray) {
                        if(!list.isEmpty()){
                            list.clear();
                        }
                        try {
                            for (int i = 0; i < jsonArray.length(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);

                                int timetableID = Integer.parseInt(jsonObject.getString("timetableID"));
                                String timetableName = jsonObject.getString("timetableName");
                                String subjectName = jsonObject.getString("subjectName");

                                Timetables timetables = new Timetables(timetableID, timetableName, subjectName);
                                list.add(timetables);
                                adapter.notifyDataSetChanged();
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }, new Response.ErrorListener(){

                    @Override
                    public void onErrorResponse(VolleyError volleyError) {

                    }
                }
                );
        requestQueue.add(jsonArrayRequest);
    }
 }

真的意味着很多人可以帮助我

谢谢

【问题讨论】:

  • 请发布您的 CurrentTimetables 片段类的代码
  • 如果你有timetable的数据库,尝试在currentTimetable片段的onResume方法中刷新recyclerview。
  • 哦,好吧,你的意思是在 onResume 中调用 populate 方法(这会用 db 中的值填充 recyclerview)?
  • 它不起作用,我把它放在onResume() - 仍然没有运气
  • 在选项卡中,所有片段都将被调用一次,因此它的 oncreateview 和 onviewcreated 方法将在您切换片段时调用,其 onResume 方法将被调用。您应该检查它的生命周期以了解它。

标签: android android-fragments android-viewpager fragmentpageradapter


【解决方案1】:

您的代码需要进行一些更改。如果您查看 Fragment 的 LifeCycle,您将了解它如何与表格视图一起使用。

查看我根据上述代码制作的代码。

public class CurrentTimetables extends Fragment {
    RecyclerView recyclerView;
    static MusicRecyclerAdapter adapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<Timetables> list;
    Context context;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context = context;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.currenttimetable, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        recyclerView = (RecyclerView) view.findViewById(R.id.timetablerecyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        tabBackground = new TabBackground(CurrentTimetables.this, list, spinnerItems, adapter, spinnerAdapter);
        tabBackground.populateConditionsList();
        // If you have another Component add here using finViewById() and also you can do
        // other process here. I just used setUserVisibleHint because it will execute when
        // fragment will be visible to user and it will stop over calling to web service.
        /**
         * Populate Recyclerview data if setUserVisibleHint do not work.
         */
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            populate();
        }
    }

    public void populate() {
        String dbURL = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(dbURL, new Response.Listener<JSONArray>() {

            @Override
            public void onResponse(JSONArray jsonArray) {
                if (!list.isEmpty()) {
                    list.clear();
                }
                try {
                    list = new ArrayList<Timetables>();
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);

                        int timetableID = Integer.parseInt(jsonObject.getString("timetableID"));
                        String timetableName = jsonObject.getString("timetableName");
                        String subjectName = jsonObject.getString("subjectName");

                        Timetables timetables = new Timetables(timetableID, timetableName, subjectName);
                        list.add(timetables);
                        adapter = new MusicRecyclerAdapter(list, context);
                        recyclerView.setAdapter(adapter);
                        adapter.notifyDataSetChanged();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError volleyError) {

            }
        });
        jsonArrayRequest.setRetryPolicy(new DefaultRetryPolicy(5 * 1000, 1, 1.0F));
        jsonArrayRequest.setShouldCache(false);
        requestQueue.add(jsonArrayRequest);
    }

    @Override
    public void onResume() {
        super.onResume();
        populate();
    }
}

我可能忘记了您的代码中的某些内容,您可能需要添加它。

【讨论】:

  • 你知道什么伙伴。我不知道该怎么感谢你。有用!!!下一个选项卡会更新,但延迟了 2 秒,但嘿,这是由于服务器的原因 - 我想我可以解决这个问题
  • 只是出于兴趣jsonArrayRequest.setRetryPolicy(new DefaultRetryPolicy(5 * 1000, 1, 1.0F));jsonArrayRequest.setShouldCache(false); 是什么意思?我从来没有过,但这是什么意思?
  • RetryPolicy 用于多次调用web service,第一个参数是minTime 继续调用webservice,第二个参数是失败重试的次数,第三个参数是backoff multiplier。跨度>
  • 非常有帮助的答案..拯救了我的一天..+1
  • 我现在不会使用这种方法,因为setUserVisibleHint 似乎已被弃用。
【解决方案2】:

你必须在 mainActivity 中创建一个接口。在您的片段中引用它。它是从一个片段到另一个片段进行通信的最佳方式。请参考以下链接。

http://developer.android.com/training/basics/fragments/communicating.html

看看,如果有任何疑问,我们会为您提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多