在viewPager的片段中,recyclerView适配器notifyDataSetChanged第一次不起作用

时间:2016-04-21 10:43:19

标签: android android-fragments android-viewpager android-recyclerview android-adapter

我在活动中有片段视图寻呼机,它之前会创建一些输入数字的页面。在每个片段中,我都有回收站视图,每次用户移动到相关页面时都需要更新。在每个片段的resume()上,我从主要活动获取数据。

我遇到的是当我第一次进入下一页时它没有更新,但是如果在一些页面移动之后我会回到它,它会被更新,使用相同的resume()代码。

我在更新数据后尝试了一些延迟,但没有帮助。

因此,如果在更新数据之前,我会检查它按照我的计划工作的每个页面,但如果之前没有创建页面(由于寻呼机适配器)但我仍然使用相同的代码进行更新,则它不起作用。 / p>

我会很高兴得到一些帮助,已经在它上面堆了2天了。

主要活动:

package com.slavafleer.tipcalculator02;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.slavafleer.tipcalculator02.recycler.PageHeaderAdapter;

import java.util.ArrayList;

public class ManualModeActivity extends AppCompatActivity implements
        PageHeaderAdapter.Callbacks, DinerFragment.Callbacks {

    private int mDinersAmount;
    private ViewPager mViewPagerDiners;
    private PageHeaderAdapter mHeaderAdapter;
    private DinersPagerAdapter mDinersPagerAdapter;
    private ArrayList<Order> mOrders;

    public ArrayList<Order> getOrders() {
        return mOrders;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_manual_mode);

        mOrders = new ArrayList<>();

        // Get diners amount from previous activity
        Intent intent = getIntent();
        mDinersAmount = intent.getIntExtra(Constants.KEY_DINNERS_AMOUNT, 1);

        // Initialise PageHeader Recycler
        mHeaderAdapter = new PageHeaderAdapter(this, mDinersAmount, this);
        final RecyclerView recyclerPageHeader = (RecyclerView) findViewById(R.id.recyclerViewPagerHeader);
        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        recyclerPageHeader.setLayoutManager(linearLayoutManager);
        recyclerPageHeader.setAdapter(mHeaderAdapter);

        // Initialise ViewPager
        mViewPagerDiners = (ViewPager) findViewById(R.id.viewPagerDiners);
        FragmentManager fragmentManager = getSupportFragmentManager();
        mDinersPagerAdapter = new DinersPagerAdapter(fragmentManager, mDinersAmount);
        mViewPagerDiners.setAdapter(mDinersPagerAdapter);

        // ViewPager Listener - synchronise with headers recycler
        mViewPagerDiners.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            // Gets position for selected page
            @Override
            public void onPageSelected(int position) {

                mHeaderAdapter.selectItem(position);
                linearLayoutManager.smoothScrollToPosition(recyclerPageHeader, null,position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    // HeaderPage Adapter Callbacks
    // Scroll ViewPager by clicked Header
    @Override
    public void onItemClick(int position) {
        mViewPagerDiners.setCurrentItem(position, true);
    }

    // DinerFragment.OrderDialog.Callbacks
    // Send data to PagerAdapter that would sent to each fragment
    @Override
    public void onDialogAddClick(Order order) {

        Log.d("test", "onDialogAddClick");

        mOrders.add(order);
        mDinersPagerAdapter.updateOrders();
    }
}

PagerAdapter

package com.slavafleer.tipcalculator02;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.ArrayList;

/**
 * PagerAdapter for ManualModeActivity ViewPager
 */
public class DinersPagerAdapter extends FragmentPagerAdapter {

    private int mDinersAmount;
    private ArrayList<DinerFragment> mDinerFragments;

    public DinersPagerAdapter(FragmentManager fm, int dinersAmount) {
        super(fm);

        mDinersAmount = dinersAmount;
        mDinerFragments = new ArrayList<>();
    }

    @Override
    public Fragment getItem(int position) {

        // Insert diners amount to fragment
        Bundle bundle = new Bundle();
        bundle.putInt(Constants.KEY_DINNERS_AMOUNT, mDinersAmount);
        bundle.putInt(Constants.KEY_CURRENT_PAGE, position);
        DinerFragment dinerFragment = new DinerFragment();
        dinerFragment.setArguments(bundle);
        mDinerFragments.add(dinerFragment); // save fragments references

        return dinerFragment;
    }

    // Diners amount + All
    @Override
    public int getCount() {
        return mDinersAmount + 1;
    }

    // Update order list in each fragment of view pager
    public void updateOrders() {

        for(DinerFragment dinerFragment : mDinerFragments) {
            dinerFragment.onResume();
        }
    }
}

片段

package com.slavafleer.tipcalculator02;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.slavafleer.tipcalculator02.recycler.OrdersAdapter;

import java.util.ArrayList;


/**
 * Diner Fragment Class
 */
public class DinerFragment extends Fragment implements OrderDialog.Callbacks {

    private ArrayList<Order> mOrders = new ArrayList<>();
    private RecyclerView mRecyclerViewOrders;
    private ImageView mImageViewAddOrderButton;
    private int mDinersAmount;
    private OrdersAdapter mOrdersAdapter;
    private int mDinerId;
    private Callbacks mCallbacks;

    public DinerFragment() {
        // Required empty public constructor
    }

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

        Log.d("test", "onCreateView");

        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_diner, container, false);

        mCallbacks = (Callbacks) inflater.getContext();

        // Get Diners Amount
        final Bundle bundle = getArguments();
        if(bundle != null) {
            mDinersAmount = bundle.getInt(Constants.KEY_DINNERS_AMOUNT);
            mDinerId = bundle.getInt(Constants.KEY_CURRENT_PAGE);

            Log.d("test", "onCreateView " + mDinerId);
        }

        mRecyclerViewOrders = (RecyclerView) view.findViewById(R.id.recyclerViewOrders);

        mOrdersAdapter = new OrdersAdapter(getActivity(), mOrders);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        mRecyclerViewOrders.setLayoutManager(linearLayoutManager);
        mRecyclerViewOrders.setAdapter(mOrdersAdapter);

        // Due to the bug, we could use just listener and not OnClick in Fragment
        mImageViewAddOrderButton = (ImageView) view.findViewById(R.id.imageViewAddButton);
        mImageViewAddOrderButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ArrayList<Integer> currentPage = new ArrayList<>();
                currentPage.add(mDinerId);
                OrderDialog orderDialog = new OrderDialog(getActivity(),
                        mDinersAmount, currentPage, DinerFragment.this);
                orderDialog.show();
            }
        });

        return view;
    }

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

        Log.d("test", "onResume " + mDinerId);

        ManualModeActivity activity = (ManualModeActivity) getActivity();
        mOrders = activity.getOrders();

        for(Order order : mOrders) {
            Log.d("test", order.getPrice() + "");
        }

        int size = mOrders.size();
        mOrdersAdapter.notifyDataSetChanged();
        mRecyclerViewOrders.smoothScrollToPosition(size);
    }

    // Blank OrderDialog.Callbacks
    // used due to Implements for creation OrderDialog
    @Override
    public void onDialogAddClick(Order order) {

        mCallbacks.onDialogAddClick(order);
    }

    public interface Callbacks {

        void onDialogAddClick(Order order);
    }
}

3 个答案:

答案 0 :(得分:1)

使用onPageSelected方法而不是使用onResume,并使用传递的上下文片段来调用片段中的更新方法。

答案 1 :(得分:0)

最后我做的是在重新创建适配器时替换mOrdersAdapter.notifyDataSetChanged()。我知道这不是一个非常聪明的解决方案,但在视觉上它确实可以工作。

我不会将其标记为答案因为我仍然想知道为什么它像我之前写的那样。

再次感谢。

//        mOrdersAdapter.notifyDataSetChanged();
        mOrdersAdapter = new OrdersAdapter(getActivity(), mOrders);
        mRecyclerViewOrders.setAdapter(mOrdersAdapter);

答案 2 :(得分:0)

ViewPager适配器同时创建2个片段。例如,当您在第0页时,它还会创建第1页(第1页的生命周期:OnCreate-&gt; OnCreateView-&gt; OnResume-&gt; OnPause-&gt; OnResume)。当您向第1页滑动时,只有方法是被调用的是SetMenuVisibility。因此,为了更新第1页的数据,可以在Fragment中调用setMenuVisibilty:

@Override
public void setMenuVisibility(boolean menuVisible) {
    super.setMenuVisibility(menuVisible);
    if(menuVisible && isResumed()){
            settingAdapter();
    }
}

所以在这里setAdapter我重新加载了数据。 到目前为止,这是我在viewpager中使用recyclerviews对片段做出的最佳技巧。但是使用新数据填充片段仍有几毫秒的延迟))) 我希望这会对你有所帮助