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?
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;
}
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 !!
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!
I have an Android activity with a RecycleView and I have implemented a ClickEvent on this RecycleView.
If I try to click on one items, I want to display a Dialog with another RecycleView.
So this is my activity code:
public class ResultActivity extends AppCompatActivity {
private List<Result> lista= new ArrayList<Result>();
private RecyclerView recyclerView;
private RecyclerView recyclerViewResult;
private ResultsAdapter pAdapter;
private ResultXResultAdapter prAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
try{
super.onCreate(savedInstanceState);
setContentView(R.layout.results_activity);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
ResultDAO manager = new ResultDAO(this);
lista=manager.getResults();
pAdapter = new ResultsAdapter(lista, new ResultsAdapter.OnItemClickListener() {
#Override
public void onItemClick(Result item) {
try{
final Dialog dialog = new Dialog(ResultActivity.this);
dialog.setContentView(R.layout.result_modal);
recyclerViewResult = (RecyclerView) findViewById(R.id.recycler_result_view);
dialog.setTitle("Parametri");
prAdapter = new ResultXResultAdapter(item.getListaParametri());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerViewResult.setLayoutManager(mLayoutManager);
recyclerViewResult.setItemAnimator(new DefaultItemAnimator());
recyclerViewResult.setAdapter(prAdapter);
dialog.show();
}catch(Exception e){
Log.e("","");
}
}
});
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(pAdapter);
// prepareMovieData();
}catch(Exception e){
}
}
}
If I run my application and I try to click on one items, I have null exception. The problem is in this line code:
recyclerViewResult = (RecyclerView) findViewById(R.id.recycler_result_view);
after this code, the recyclerViewResult is null, but should not be null.
The reason your RecyclerView is returning null is because you're calling findViewById without the correct view prefix. Because you're using a custom layout in your Dialog you should use a LayoutInflater to inflate the layout then use the inflated view object to find the RecyclerView that belongs in the dialog like so:
View dialogView = inflater.inflate(R.layout.result_modal, null);
recyclerViewResult = (RecyclerView) dialogView.findViewById(R.id.recycler_result_view)
dialog.setContentView(dialogView)
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());