片段中的RecyclerView - 没有连接适配器,跳过布局 [英] RecyclerView in Fragment - No Adapter Attached, Skipping Layout

查看:258
本文介绍了片段中的RecyclerView - 没有连接适配器,跳过布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的情况,我有一个活动托管 TabLayout / Viewpager 根据变化填充数据到Firebase数据库。不幸的是, RecyclerView 没有被填充,我在logcat中收到以下错误。我相信即使片段不在屏幕上也会加载片段,这会导致 RecyclerView 的填充错误。当我旋转屏幕时, RecyclerView 会填充,这也很奇怪:

I have an odd situation, I have an Activity hosting a TabLayout/Viewpager that populates data based on changes to a Firebase Database. Unfortunately, the RecyclerView is not being populated, and I am receiving the error below in my logcat. I believe the fragment is being loaded even when it is not on screen, which is causing an error in the population of the RecyclerView. It is also weird as the RecyclerView does populate when I rotate the screen:

12-13 21:31:40.013 12490-12490/com.troychuinard.fanpolls E/RecyclerView: No adapter attached; skipping layout

这是 ViewPager 适配器I在我的主机活动

Here is the ViewPager Adapter I have in my host Activity:

public class SectionPagerAdapter extends FragmentPagerAdapter {

    public SectionPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new TrendingFragment();
            case 1:
                return new FollowingFragment();
            case 2:
                return new LiveFragment();
            default:
                return new TrendingFragment();
        }
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return getResources().getString(R.string.trending_text);
            case 1:
                return getResources().getString(R.string.following_text);
            case 2:
                return getResources().getString(R.string.new_text);
            default:
                return getResources().getString(R.string.trending_text);
        }
    }
}

这是完整的片段,其中我在 LiveFragment onCreateView()函数中初始化 RecyclerView >,这是 TabLayout 中的标签3:

Here is the complete fragment where I initialize the RecyclerView inside onCreateView() function in my LiveFragment, which is tab 3 in the TabLayout:

public class LiveFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

private RecyclerView mRecyclerview;
private DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
private LinearLayoutManager mLayoutManager;

private FirebaseRecyclerAdapter <Poll, PollHolder> mFireAdapter;


// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private OnFragmentInteractionListener mListener;

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

/**
 * Use this factory method to create a new instance of
 * this fragment using the provided parameters.
 *
 * @param param1 Parameter 1.
 * @param param2 Parameter 2.
 * @return A new instance of fragment LiveFragment.
 */
// TODO: Rename and change types and number of parameters
public static LiveFragment newInstance(String param1, String param2) {
    LiveFragment fragment = new LiveFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mBaseRef = FirebaseDatabase.getInstance().getReference();
    mPollsRef = mBaseRef.child("Polls");

    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);

    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    final View v = inflater.inflate(R.layout.fragment_new, container, false);
    Log.v("TAG", "ON CREATE CALLED FROM NEW");

    mLayoutManager = new LinearLayoutManager(getActivity());
    mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

    mRecyclerview = (RecyclerView)v.findViewById(R.id.new_RecyclerView);

    if (mRecyclerview != null){
        mRecyclerview.setHasFixedSize(true);
    }

    if (mRecyclerview == null){
       Log.v("TAG", "RECYCLERVIEW NULL");
    } else if (mLayoutManager == null){
        Log.v("TAG", "LAYOUTMANAGER NULL");
    } else if (mFireAdapter == null) {
        Log.v("TAG", "mFIREADAPTER NULL");
    }
    return v;
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

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


}

@Override
public void onStop() {
    super.onStop();
    if (mFireAdapter != null){
        mFireAdapter.cleanup();
    }
}

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


    mRecyclerview.setLayoutManager(mLayoutManager);
    mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(Poll.class, R.layout.latest_item, PollHolder.class, mPollsRef) {
        @Override
        protected void populateViewHolder(PollHolder viewHolder, Poll model, int position) {
            viewHolder.mPollQuestion.setText(model.getQuestion());
            Picasso.with(getActivity().getApplicationContext())
                    .load(model.getImage_URL())
                    .fit()
                    .into(viewHolder.mPollImage);
            Log.v("QUESTION", model.getQuestion());
            Log.v("IMAGE", model.getImage_URL());
        }
    };
    mRecyclerview.setAdapter(mFireAdapter);

    mPollsRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot x : dataSnapshot.getChildren()){
                mFireAdapter.notifyItemInserted(0);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });





}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}


public static class PollHolder extends RecyclerView.ViewHolder {

    TextView mPollQuestion;
    ImageView mPollImage;


    public PollHolder(View itemView) {
        super(itemView);

        mPollQuestion = (TextView) itemView.findViewById(R.id.latest_item_question);
        mPollImage = (ImageView) itemView.findViewById(R.id.pollThumbNailImage);

    }
}

/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
     }
   }


推荐答案

移动从firebase读取数据后,从onCreateView到onActivityCreated方法的适配器。

Move your Adapter from onCreateView to onActivityCreated method after you have read data from firebase.

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

//read Poll data from firebase mPollsRef for example
//.... database reference to firebase
//Query mPollsRef = databaseReference.child("pools").limitToFirst(200);


    mRecyclerview.setLayoutManager(mLayoutManager);
    mFireAdapter = new FirebaseRecyclerAdapter<Poll, PollHolder>(Poll.class, R.layout.latest_item, PollHolder.class, mPollsRef) {
    @Override
    protected void populateViewHolder(PollHolder viewHolder, Poll model, int position) {
        viewHolder.mPollQuestion.setText(model.getQuestion());
        Picasso.with(getActivity().getApplicationContext())
                .load(model.getImage_URL())
                .fit()
                .into(viewHolder.mPollImage);
        Log.v("QUESTION", model.getQuestion());
        Log.v("IMAGE", model.getImage_URL());
        }
    };
    mRecyclerview.setAdapter(mFireAdapter);

}

我在HostActivity.java初始化寻呼机的代码

My code for initialize Pager at HostActivity.java

private FragmentPagerAdapter mPagerAdapter;
private ViewPager mViewPager;

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


    // Create the adapter that will return a fragment for each section
    mPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
        private final Fragment[] mFragments = new Fragment[] {
                new MyAbsenceFragment(),
                new MyAttendanceFragment(),
                new AbsTypesFragment(),
                new LiveFragment(),
        };
        private final String[] mFragmentNames = new String[] {
                "Absences",
                "Attendances",
                "AbsTypes",
                "Live"
        };
        @Override
        public Fragment getItem(int position) {
            return mFragments[position];
        }
        @Override
        public int getCount() {
            return mFragments.length;
        }
        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentNames[position];
        }
    };
    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mPagerAdapter);

这篇关于片段中的RecyclerView - 没有连接适配器,跳过布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆