Recyclerview in my Fragment is giving me this error but I couldn't figure it out. There are lots of questions about this issue but none of them solved my problem so far.
Here is a piece of code from my fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
initCollapsingToolbar();
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
prepareSectors();
try {
Glide.with(this).load(R.drawable.cover).into((ImageView) view.findViewById(R.id.backdrop));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
You did not create an instance of your adapter before setting it to RecyclerView.
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
// Your adapter initialization here
adapter = new YourAdapter(getActivity(), ....);
recyclerView.setAdapter(adapter);
UPDATE:
Get LayoutInflater from passed context. Update your SectorAdapter code portion as below:
public Context mContext;
public List<Sector> sectorList;
LayoutInflater layoutInflater;
public SectorAdapter(Context mContext, List<Sector> sectorList) {
this.mContext = mContext;
this.sectorList = sectorList;
layoutInflater = LayoutInflater.from(mContext);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = layoutInflater.inflate(R.layout.sector_card, parent, false);
return new MyViewHolder(itemView);
}
Try moving your RecyclerView codes to onViewCreated()
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sectorList = new ArrayList<>();
prepareSectors();
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new SectorAdapter(getActivity(), sectorList);
recyclerView.setAdapter(adapter);
}
Hope this will help~
There is no any code for your adapter. Thus you need to implement the adapter and pass the instance to the recyclerView.
RecyclerView.LayoutManager mLayoutManager ....
....
// Your adapter initialization here
adapter = new someAdapter(....);
recyclerView.setAdapter(adapter);
This will help you!
Related
I am trying to update items onRefresh in the recylerview but it is not producing the reuquired list. When I close the app and open it back then it gives the updated items list but it does not update items list through onRefresh method. So basically in order to update the list you have to close and open the app and you can not update it in other way.
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
myAdapter = new MyAdapter(getContext(), items);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(),
RecyclerView.VERTICAL, false));
//myAdapter.notifyDataSetChanged();
recyclerView.invalidate();
swipeRefreshLayout.setRefreshing(false);
I have tried both notifyDataSetChanged() and invalidate() but none of them are working. There is also no error in logcat. How do I change the method to update it onRefresh?
I have the same adapter setting in the onCreateView method
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myAdapter = new MyAdapter(getContext(), videoFiles);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
}
This is whole activity with recylerview
public class FilesFragment extends Fragment {
RecyclerView recyclerView;
View view;
MyAdapter myAdapter;
// public static List<Files> items; from adapter class
public FilesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_files, container, false);
recyclerView = view.findViewById(R.id.filesRV);
myAdapter = new MyAdapter(getContext(), items);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
// recyclerView.invalidate();
swipeRefreshLayout = view.findViewById(R.id.swipeToRefresh);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// recyclerView.invalidate();
myAdapter.notifyDataSetChanged();
// updateData(items);
swipeRefreshLayout.setRefreshing(false);
}
public void updateData(List<Files> items) {
// items.clear();
myAdapter = new MyAdapter(getContext(), items);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
items.addAll(items);
myAdapter.notifyDataSetChanged();
}
});
if (items!= null && items.size() > 0) {
myAdapter = new MyAdapter(getContext(), items);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
}
return view;
}
No need to set new adapter every time. Just call notify dataset changed like below:
recyclerView.getAdapter().notifyDataSetChanged();
And before that please make sure that your items are updated. My wild guess is you are not inserting or updating the items. If its a arraylist please insert or update an item before calling the notifyDataSetChanged()
myAdapter.notifyDataSetChanged();
add this line to notifiy adapter that the data source has changed
put this in onResume() to make it seamless
also you can try to do following
recyclerView.setAdapter(null);
recyclerView.setLayoutManager(null);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(myLayoutManager);
myAdapter.notifyDataSetChanged();
what this will do is invalidate the recycler view with new updated data
although there is invalidate method present it tend to not work in certain conditions
public class FilesFragment extends Fragment {
RecyclerView recyclerView;
View view;
MyAdapter myAdapter;
// public static List<Files> items; from adapter class
public FilesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_files, container, false);
recyclerView = view.findViewById(R.id.filesRV);
myAdapter = new MyAdapter(getContext(), items);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
// recyclerView.invalidate();
swipeRefreshLayout = view.findViewById(R.id.swipeToRefresh);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// recyclerView.invalidate();
// myAdapter.notifyDataSetChanged();
updateData(items);
swipeRefreshLayout.setRefreshing(false);
}
});
public void updateData(List<Files> items) {
// items.clear();
myAdapter = new MyAdapter(getContext(), items);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
items.addAll(items);
myAdapter.notifyDataSetChanged();
recyclerview.getAdapter.notifydatasetchanged();
}
return view;
}
im trying to achieve a recycler view in my fragment but these error are not letting me to do this kindly see and tell me
here is my fragment java class
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
MyListData[] myListData = new MyListData[] {
new MyListData("Email", android.R.drawable.ic_dialog_email),
new MyListData("Info", android.R.drawable.ic_dialog_info),
new MyListData("Delete", android.R.drawable.ic_delete),
new MyListData("Dialer", android.R.drawable.ic_dialog_dialer),
new MyListData("Alert", android.R.drawable.ic_dialog_alert),
new MyListData("Map", android.R.drawable.ic_dialog_map),
new MyListData("Email", android.R.drawable.ic_dialog_email),
new MyListData("Info", android.R.drawable.ic_dialog_info),
new MyListData("Delete", android.R.drawable.ic_delete),
new MyListData("Dialer", android.R.drawable.ic_dialog_dialer),
new MyListData("Alert", android.R.drawable.ic_dialog_alert),
new MyListData("Map", android.R.drawable.ic_dialog_map),
};
RecyclerView recyclerView = root.findViewById(R.id.recyclerView);
MyListAdapter adapter = new MyListAdapter(myListData);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
return root;
}
}
i am error on these lines
RecyclerView recyclerView = root.findViewById(R.id.recyclerView)
and
recyclerView.setLayoutManager(new LinearLayoutManager(this));
here is my fragment view model class
public class HomeViewModel extends ViewModel {
private MutableLiveData<String> mText;
public HomeViewModel() {
mText = new MutableLiveData<>();
//mText.setValue();
}
public LiveData<String> getText() {
return mText;
}
}
here is my xml
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/t1"
android:scrollbars="vertical"
android:id="#+id/recyclerView"
/>
You have to use
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
instead of
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Try this,
RecyclerView recyclerView = root.findViewById(R.id.recyclerView);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
Rcv_Results.setLayoutManager(mLayoutManager);
Previous Question:
May I know why this error will occur when I try to start RecyclerView activity doing a search from fragment.
After added adapter:
error: OwnerDAO.getOwner()' on a null object reference
Fragment code:
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
SearchAdapter adapter;
OwnerDAO mOwnerDao;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.activity_search, container, false);
recyclerView = (RecyclerView)v.findViewById(R.id.recycler_search);
layoutManager = new LinearLayoutManager(this.getActivity());
mOwnerDao = new OwnerDAO(getContext())
adapter = new SearchAdapter(getContext(),mOwnerDao.getOwner());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter( adapter );
return v;
}
Search Adapter:
public SearchAdapter(Context context, List<Owner> owners) {
this.context = context;
this.owners = owners;
}
Set the layoutManager after setAdapter like this :-
recyclerView.setAdapter( adapter );
recyclerView.setLayoutManager(layoutManager);
The error will be removed !!
I have never seen like this before. There is no error or exception the code just skipps some line.
I have a class which is doing something and when it's done returns with an Adapter and it's working fine the adapter contains the correct number and returns with it correctly. After that in my Fragment I'm trying to use this Adapter with a RecyclerView and create a list. Here is my fragment:
public class ServicesFragment extends Fragment {
ArrayList<Item> list;
public RecyclerView mRecyclerView;
public RecyclerView.LayoutManager mLayoutManager;
public ItemAdapter itemAdapter;
DownloadDataThread downloadDataThread;
public static boolean dataisready;
ProgressDialog dialog;
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_service, parent, false);
mRecyclerView = (RecyclerView)v.findViewById(R.id.services_recycler_view);
list = new ArrayList<Item>();
list.add(0,new Item());
itemAdapter = new ItemAdapter(list);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(itemAdapter);
downloadDataThread = ((MainActivity)getActivity()).downloadDataThread;
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable helloRunnable = new Runnable() {
public void run() {
dataisready = downloadDataThread.ready;
if(dataisready){
itemAdapter = downloadDataThread.getItemAdapter();
Log.d("THREAD","adapter " + itemAdapter);
readAndLoadList(itemAdapter);
executor.shutdown();
}
Log.d("THREAD","nézem "+dataisready);
}
};
executor.scheduleAtFixedRate(helloRunnable, 0, 200, TimeUnit.MILLISECONDS);
return v;
}
private void readAndLoadList(ItemAdapter itemAdapter1){
itemAdapter = itemAdapter1;
itemAdapter.notifyDataSetChanged();
Log.d("THREAD"," adaptert22 "+itemAdapter.getItemCount());
mRecyclerView.setHasFixedSize(true);
Log.d("THREAD","muszáfá0 "+ mRecyclerView);
mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
Log.d("THREAD","muszáfá1 "+ mLayoutManager);
mRecyclerView.setLayoutManager(mLayoutManager);
// And after that the other logs never shows up
Log.d("THREAD","muszáfá2 "+ mLayoutManager);
mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
Log.d("THREAD","muszáfá3 "+ mLayoutManager);
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL));
Log.d("THREAD","muszáfá4 ");
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
Log.d("THREAD","muszáfá5 ");
mRecyclerView.setAdapter(itemAdapter);
mRecyclerView.invalidate();
mRecyclerView.getAdapter().getItemCount();
Log.d("THREAD","lássuk az adaptert33 "+mRecyclerView.getAdapter().getItemCount());
}
}
So as you can see I'm checking in every 200 millisecond that the adapter is ready or not and when it's ready I'm returning with it's adapter and trying to load the RecyclerView but after that line : mRecyclerView.setLayoutManager(mLayoutManager);˛ the other logs never shows up.
Before you ask me I'm created a complete RecyclerView and load in the beginning of the onCreateView because I always got an error for RecyclerView but before I have added that it was also bad.
Have you any idea whats going on here?
I am getting an error saying "No adapter attached; skipping layout", however my images are loading into my LayoutManager just fine. However, when i try to scroll down and load additional data, the application crashes with a NullPointerException. Here is my related code.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
service.getPodcasts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(podcasts -> mRecyclerView.setAdapter(new PodcastsAdapter(getActivity(), podcasts)));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_podcasts, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.podcasts_recycler_view);
mLayoutManager = new GridLayoutManager(getActivity(), 3);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//mRecyclerView.setAdapter(mAdapter);
return rootView;
}
Any ideas on how to fix this?
You didn't attach the adapter because you create it after you try to attach it:
In my case:
mRecyclerView.setAdapter(mAdapter); // Here, mAdapter is null
mAdapter = new CountryAdapter(CountryManager.getInstance().getCountries(), R.layout.card_layout, getActivity());