paging library not showing anything in recyclerview - android-recyclerview

i'm trying to load bunch of list from room database, with paging library, but somehow that i don't really understand, the list never shown up
i add a repository class between dao and viewmodel, not sure if its the problem but, i configure Paged.list and pagedlistbuilder in there
i've also try to put some breakpoint in pagedListAdapter, but it never called
DAO
#Query("SELECT * FROM DictIndonesia")
public abstract DataSource.Factory<Integer, DictIndonesia> getAllPaged();
REPOSITORY
public class DictRepository {
PagedList.Config pagedListConfid;
.....
public DictRepository(Application application) {
db = DictIndoDatabase.getINSTANCE(application);
indDao = db.dictIdDao();
.....
pagedListConfid = (new PagedList.Config.Builder()
.setEnablePlaceholders(true)
.setPrefetchDistance(10)
.setPageSize(20).build());
}
......
public LiveData<PagedList<DictIndonesia>> getAllWordPaged() {
return new LivePagedListBuilder<>(
indDao.getAllPaged(), pagedListConfid).build();
}
viewmodel
public LiveData<PagedList<DictIndonesia>> getAllWordPaged() {
return dictRepository.getAllWordPaged();
}
ADAPTER
public class WordIndAdapterPaged extends PagedListAdapter<DictIndonesia,WordIndAdapterPaged.WordHolder> {
public WordIndAdapterPaged() {
super(diffcallBack);
}
#NonNull
#Override
public WordHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler, parent, false);
return new WordHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull WordHolder holder, int position) {
holder.bindTo(getItem(position));
}
private static final DiffUtil.ItemCallback<DictIndonesia> diffcallBack = new DiffUtil.ItemCallback<DictIndonesia>() {
#Override
public boolean areItemsTheSame(#NonNull DictIndonesia oldItem, #NonNull DictIndonesia newItem) {
return oldItem.getIdIndo() == newItem.getIdIndo();
}
#Override
public boolean areContentsTheSame(DictIndonesia oldItem, #NonNull DictIndonesia newItem) {
return oldItem == newItem;
}
};
public class WordHolder extends RecyclerView.ViewHolder {
...............
WordHolder(View view) {
super(view);
...............
}
void bindTo(DictIndonesia dictIndonesia) {
word.setText(Html.fromHtml(dictIndonesia.getWord()));
meaning.setText(Html.fromHtml(dictIndonesia.getMeaning()));
}
}
Fragment
public class Fdashboard extends Fragment {
#BindView(R.id.rv_global)
RecyclerView rvGlobal;
private Unbinder unbinder;
WordIndAdapterPaged wordIndAdapterPaged;
private WordViewModel wordViewModel;
public Fdashboard() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_fdashboard, container, false);
unbinder = ButterKnife.bind(this, v);
wordViewModel = ViewModelProviders.of(getActivity()).get(WordViewModel.class);
wordIndAdapterPaged = new WordIndAdapterPaged();
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
rvGlobal.setLayoutManager(layoutManager);
rvGlobal.setAdapter(wordIndAdapterPaged);
wordViewModel.getAllWordPaged().observe(this, dictIndonesias -> {
wordIndAdapterPaged.submitList(dictIndonesias); //i think the problem maybe around here
});
return v;
}

Related

Recycler view lost after fragment replacement

I have a single activity which replaces a fragment containing a recycler view with a fragment containing details of the selected viewholder item. When the back button is pressed the fragment containing the recycler view is restored but the recycler view items are no longer displayed. However, views are restored upon device rotation. All model data is stored in a SQLite database and the adapter list is updated on resume of its fragment .
CrimeListFragment.Java
public class CrimeListFragment extends Fragment {
private Callbacks callbacks;
public interface Callbacks {
public void onItemSelected(UUID id);
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
callbacks = (Callbacks) context;
}
#Override
public void onDetach() {
super.onDetach();
callbacks = null;
}
private RecyclerView crimeListRecycler;
private CrimeListAdapter adapter;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime_list, container, false);
crimeListRecycler = view.findViewById(R.id.crime_list);
crimeListRecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_crime_list, menu);
MenuItem showSubtitle = menu.findItem(R.id.show_subtitle);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.new_crime:
Crime crime = new Crime();
CrimeLab.get(getActivity()).addCrime(crime);
/*Intent intent = CrimeActivity.createIntent(getActivity(), crime.getId());
startActivity(intent);*/
callbacks.onItemSelected(crime.getId());
return true;
default:
return onOptionsItemSelected(item);
}
}
private void updateUI() {
List<Crime> crimes = CrimeLab.get(getActivity()).getCrimes();
if (adapter == null) {
adapter = new CrimeListAdapter(crimes);
crimeListRecycler.setAdapter(adapter);
} else {
adapter.setCrimesList(crimes);
adapter.notifyDataSetChanged();
}
}
public class CrimeListAdapter extends RecyclerView.Adapter<CrimeListAdapter.CrimeHolder> {
private List<Crime> crimeList;
public CrimeListAdapter(List<Crime> crimes) {
crimeList = crimes;
}
#NonNull
#Override
public CrimeHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_crime, parent, false);
return new CrimeHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CrimeHolder holder, int position) {
Crime crime = crimeList.get(position);
holder.bind(crime);
}
#Override
public int getItemCount() {
return crimeList.size();
}
public void setCrimesList(List<Crime> crimes) {
crimeList = crimes;
}
public class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Crime crime;
private TextView crimeTitleTextView;
private TextView crimeDateTextView;
public CrimeHolder(#NonNull View itemView) {
super(itemView);
crimeTitleTextView = itemView.findViewById(R.id.crime_title);
crimeDateTextView = itemView.findViewById(R.id.crime_date);
itemView.setOnClickListener(this);
}
public void bind(Crime crime) {
this.crime = crime;
crimeTitleTextView.setText(crime.getTitle());
crimeDateTextView.setText(crime.getDate().toString());
}
#Override
public void onClick(View v) {
callbacks.onItemSelected(crime.getId());
/*Intent intent = CrimeActivity.createIntent(getActivity(), crime.getId());
startActivity(intent);*/
}
}
}
}
MasterActivity
public class MasterActivity extends AppCompatActivity implements CrimeListFragment.Callbacks {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = new CrimeListFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
#Override
public void onItemSelected(UUID id) {
Fragment fragment = CrimeFragment.newInstance(id);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
}
Please share your code. Something to check when you replace/add your fragment on top of recyclerview fragment.

how fix NullPointerException? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
im new in android programing and i want to add JSON to my recyclerview i was getting the adapter not attetched skiping layout but my CustomAdapter is giving me NullPointerException too.
my CustomAdapter
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private List<RetroProduct> dataList;
private Context context;
CustomAdapter(Context context, List< RetroProduct > dataList){
this.context = context;
this.dataList = dataList;
}
class CustomViewHolder extends RecyclerView.ViewHolder {
final View mView;
TextView goodsId,categoryTitle,number,title1,title2;
CustomViewHolder(View itemView) {
super(itemView);
mView = itemView;
goodsId = mView.findViewById(R.id.tv_goodsId);
categoryTitle = mView.findViewById(R.id.tv_categoryTitle);
number = mView.findViewById(R.id.tv_number);
title1 = mView.findViewById(R.id.tv_title1);
title2 = mView.findViewById(R.id.tv_title2);
}
}
#NonNull
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.item_row, parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
holder.goodsId.setText(dataList.get(position).getGoodsId());
holder.categoryTitle.setText(dataList.get(position).getCategoryTitle());
holder.title1.setText(dataList.get(position).getTitle1());
holder.title2.setText(dataList.get(position).getTitle2());
holder.number.setText(dataList.get(position).getNumber());
}
#Override
public int getItemCount() {
return dataList.size();
}
}
and im getting NullPointerException on
return dataList.size();
what should i do now? give it value or i dont know.
MainActivity
public class MainActivity extends AppCompatActivity {
private CustomAdapter adapter;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GetDataService service =
RetrofitClientInstance.getRetrofitInstance()
.create(GetDataService.class);
Call< List<RetroProduct> > call = service.getAllProducts();
call.enqueue(new Callback<List<RetroProduct>>() {
#Override
public void onResponse(Call<List<RetroProduct>> call,
Response<List<RetroProduct>> response) {
generateDataList(response.body());
LinearLayoutManager manager = new
LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<RetroProduct>> call, Throwable t)
{
Toast.makeText(MainActivity.this, "null",
Toast.LENGTH_SHORT).show();
}
});
}
private void generateDataList(List<RetroProduct> productList) {
recyclerView = findViewById(R.id.recycler_view);
adapter = new CustomAdapter(this,productList);
}
}
#Override
public int getItemCount() {
if(dataList!=null)
return dataList.size();
else
return 0;
}
Add a null check before calling size() method of a Arraylist as above

Restore scroll position

I have a simple fragment which retrieve data from Firebase database.
I use firebase recycler view to display retrieving data. And after scrolling or screen rotation I can't force recycler view (or linear layout manager) restore scroll position.
I found here some answers but they don't work.
My code is:
public class NewsListFragment extends ParentNewsFragment {
static int color_naval, color_black;
private boolean mProcessLikes = false;
private DatabaseReference mDatabaseLikes;
private DatabaseReference mDatabaseViews;
private FirebaseAuth mAuth;
private int position = 0;
public static NewsListFragment getInstance() {
return new NewsListFragment();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDatabaseReference = FirebaseDatabase.getInstance().getReference()
.child("App_news");
mDatabaseLikes = FirebaseDatabase.getInstance().getReference().child("news_likes");
mDatabaseViews = FirebaseDatabase.getInstance().getReference().child("news_views");
mAuth = FirebaseAuth.getInstance();
mQuery = mDatabaseReference.orderByChild("pos").startAt("100");
color_naval = getResources().getColor(R.color.colorPrimary);
color_black = getResources().getColor(R.color.colorBlack);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.rv_choose, container, false);
rv = (RecyclerView) rootView.findViewById(R.id.rv_choose);
lm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(lm);
rv.setHasFixedSize(true);
return rootView;
}
#Override
public void onPause() {
super.onPause();
position = lm.findFirstVisibleItemPosition();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("position", position);
}
#Override
public void onViewStateRestored(#Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if(savedInstanceState != null) {
position = savedInstanceState.getInt("position");
}
}
#Override
public void onResume() {
super.onResume();
if (position != 0) {
lm.scrollToPosition(position);
showToast(position+"");
}
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerAdapter<NewsList, NewsListViewHolder> adapter =
new FirebaseRecyclerAdapter<NewsList, NewsListViewHolder>(
NewsList.class,
R.layout.frag_newslist_card_view,
NewsListViewHolder.class,
mQuery
) {
#Override
protected void populateViewHolder(NewsListViewHolder viewHolder, final NewsList model, int position) {
final String post_key = getRef(position).getKey();
viewHolder.setDate(model.getDate()+",");
viewHolder.setTime(model.getTime());
viewHolder.setTitle(model.getTitle());
viewHolder.setImage(getContext(), model.getImage());
viewHolder.setEye(model.getCode());
viewHolder.setThumb(post_key);
viewHolder.thumb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mProcessLikes = true;
mDatabaseLikes.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (mProcessLikes){
if (dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())){
mDatabaseLikes.child(post_key).child(mAuth.getCurrentUser().getUid())
.removeValue();
mProcessLikes = false;
}
else {
mDatabaseLikes.child(post_key).child(mAuth.getCurrentUser().getUid())
.setValue("like");
mProcessLikes = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDatabaseViews.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (!dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())) {
mDatabaseViews.child(post_key).child(mAuth.getCurrentUser().getUid())
.setValue("view");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mChooserListener.chooseNews(model.getCode());
}
});
}
};
rv.setAdapter(adapter);
}
public static class NewsListViewHolder extends RecyclerView.ViewHolder {
//some text here
}
}
method showToast in the end shows real number of position but recyclerview starts from the beginning.
any ideas?
Make sure you are not reloading data from the server or wherever you are retrieving data.
Add is not null check in your fragment's onCreateView or activity's onCreate like:
if(savedInstanceState != null){
...
}else{
loadData();
}
Replace your linear layout manager with something similar to the following. I have used this implementation many times when using RecyclerView in fragments. Let me know how it goes
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
yourItem.setLayoutManager(mLayoutManager);

android only show first viewpager inside recyclerview

i have a viewpager with FragmentStatePagerAdapter inside recyclerview
and its show only the first row in recyclerview
please help me
viewpager adapter:
public class CustomPagerAdapter extends FragmentStatePagerAdapter {
private static int NUM_ITEMS = 3;
public CustomPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
Log.e("fragmentManager",fragmentManager.toString());
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
Fragment currentFragment;
switch (position) {
case 0:
currentFragment=new FirstFragment();
break;
case 1:
currentFragment=new SecondFragment();
break;
case 2:
currentFragment=new ThirdFragment();
break;
default:
currentFragment=new FirstFragment();
break;
}
return currentFragment;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
recyclerview adapter:
public class JobAdapter extends RecyclerView.Adapter<JobAdapter.JobHolder> {
private Context context;
private List<String> mJobList = new ArrayList<>();
public JobAdapter(List<String> mJobList,Context context) {
this.mJobList = mJobList;
this.context=context;
}
#Override
public JobHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.find_job_line_content, parent, false);
return new JobHolder(view);
}
#Override
public void onBindViewHolder(final JobHolder holder, int position) {
configurePagerHolder(holder, position);
}
private void configurePagerHolder(JobHolder holder, int position) {
//Job job= mJobList.get(position);
CustomPagerAdapter adapter = new CustomPagerAdapter(((MainActivity)context).getSupportFragmentManager());
holder.viewPager.setAdapter(adapter);
adapter.notifyDataSetChanged();
holder.viewPager.setCurrentItem(1);
Log.e("configurePagerHolder",position+"");
}
public int getItemCount() {``
return mJobList.size();
}
public class JobHolder extends RecyclerView.ViewHolder{
ViewPager viewPager;
public JobHolder(View itemView) {
super(itemView);
viewPager=(ViewPager)itemView.findViewById(R.id.slidesPager);
}
}
main:
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
JobAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView)findViewById(R.id.find_jobs_recyclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this,
LinearLayoutManager.VERTICAL,false));
mRecyclerView.setHasFixedSize(true);
List<String> list=new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
adapter = new JobAdapter(list,this);
mRecyclerView.setAdapter(adapter);
}
}
Very late answer but it might help some people...
Try using ViewPager2 ( an improved version of ViewPager) : https://developer.android.com/training/animation/screen-slide-2
In my case it solved the problem.

Android recycleView displaying an emply list

Please i need help on this one. Have been working on it for days but cant figure it out.
I have a recycleView to display a list of names but its displaying empty list, but i can print the list in console.
here,s the code fetching the list
public List<BackendlessUser> userList = new ArrayList<BackendlessUser>();
BackendlessDataQuery query = new BackendlessDataQuery();
Backendless.Data.of( BackendlessUser.class ).find( query, new AsyncCallback<BackendlessCollection<BackendlessUser>>()
{
#Override
public void handleResponse( BackendlessCollection<BackendlessUser> response )
{
userList = response.getCurrentPage();
for( BackendlessUser user : userList ){
Log.d( "USERS : ", user.getEmail() );
}
Log.d("USER LIST", String.valueOf( userList.size() ));
}
#Override
public void handleFault(BackendlessFault backendlessFault) {
}
});
and the recyclerView adapter that is supposed to adapt the list to the view ..
private void setupRecyclerView(#NonNull RecyclerView recyclerView) {
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(userList));
}
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final List<BackendlessUser> mValues;
public SimpleItemRecyclerViewAdapter(List<BackendlessUser> items) {
mValues = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_content, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).getProperty("idno").toString());
holder.mContentView.setText(mValues.get(position).getProperty("fname").toString());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getProperty("idno").toString());
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
Context context = v.getContext();
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getProperty("idno").toString());
context.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public BackendlessUser mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}