I recently created a recyclerview with an Api, using retrofit.
I made a paging using OnScrollListener, and it's working. But when I click on some file it does not find the position of it, how can I solve this error?
I looked here in the forum about it and did not find anything related to retrofit. I just want to select the file and send it to another activity, to send the right id.
public class AcervoFragment extends Fragment {
private Retrofit retrofit;
private RecyclerView recyclerView;
private AcervoAdaptador acervoAdaptador;
private ProgressBar progressBar2;
private List<Lancamentos> listaLancamentos = new ArrayList<>();
private int pagina;
private boolean aptoCarregar;
public AcervoFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_acervo, container, false);
recyclerView = view.findViewById(R.id.recyclerViewAcervo);
acervoAdaptador = new AcervoAdaptador(getActivity());
recyclerView.setAdapter(acervoAdaptador);
recyclerView.setHasFixedSize(true);
final GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
recyclerView.setLayoutManager(layoutManager);
retrofit = new Retrofit.Builder()
.baseUrl("api")
.addConverterFactory(GsonConverterFactory.create())
.build();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
int visibleItemCount = layoutManager.getChildCount();
int totalIntemCount = layoutManager.getItemCount();
int pastVisibleItems = layoutManager.findFirstVisibleItemPosition();
if (aptoCarregar) {
if ((visibleItemCount + pastVisibleItems) >= totalIntemCount) {
Log.i("TAG", "Carregando");
aptoCarregar = false;
pagina += 1;
obterDados(pagina);
}
}
}
}
});
aptoCarregar = true;
pagina = 1;
obterDados(pagina);
return view;
}
public void obterDados(int pagina) {
AcervoService service = retrofit.create(AcervoService.class);
Call<UltimosLancados> ultimosLancadosCall = service.obterAcervo(pagina);
ultimosLancadosCall.enqueue(new Callback<UltimosLancados>() {
#Override
public void onResponse(Call<UltimosLancados> call, Response<UltimosLancados> response) {
aptoCarregar = true;
if (response.isSuccessful()) {
UltimosLancados ultimosLancados = response.body();
final ArrayList<Lancamentos> listaAcervo = ultimosLancados.getDados();
//progressBar2.setVisibility(View.GONE);
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Lancamentos p = listaAcervo.get(position);
String aString = Integer.toString(p.getId());
int aInt = Integer.parseInt(aString);
Intent i = new Intent(getActivity().getApplicationContext(), PerfilActivity.class);
i.putExtra("ID", aInt);
startActivity(i);
}
#Override
public void onLongItemClick(View view, int position) {
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}));
acervoAdaptador.adicionarItem(listaAcervo);
} else {
Log.e("TAG", "onResponse" + response.errorBody());
}
}
#Override
public void onFailure(Call<UltimosLancados> call, Throwable t) {
aptoCarregar = true;
Log.e("TAG", "onFailure" + t.getMessage());
}
});
}
}
07-26 20:02:29.382 21112-21112/site.exemplo.project E/InputEventReceiver: Exception dispatching input event.
07-26 20:02:29.382 21112-21112/site.exemplo.project E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
07-26 20:02:29.392 21112-21112/site.exemplo.project E/MessageQueue-JNI: java.lang.IndexOutOfBoundsException: Invalid index 45, size is 40
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at site.exemplo.project.AcervoFragment$2$1.onItemClick(AcervoFragment.java:108)
at site.exemplo.project.RecyclerItemClickListener.onInterceptTouchEvent(RecyclerItemClickListener.java:26)
at android.support.v7.widget.RecyclerView.dispatchOnItemTouch(RecyclerView.java:2916)
at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:3044)
at android.view.View.dispatchTouchEvent(View.java:8808)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2569)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2239)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2581)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2607)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1779)
at android.app.Activity.dispatchTouchEvent(Activity.java:2846)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2568)
at android.view.View.dispatchPointerEvent(View.java:9003)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4209)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4072)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3627)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3646)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3763)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3654)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3820)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3627)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3646)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3654)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3627)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5910)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5884)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5855)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6000)
at android.view.InputEventReceiver.dispatchInputEven
Related
My RecyclerView's Adapter seems to be crashing, I have visited a few questions but I cannot seem to understand what is going on.
The questions I had visited mention that a list has been initialised again but I don't think I am initialising any list.
The link of the most relatable question:
Link 1
Logcat
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.android.predictious.ui.market.voucher.VoucherAdapter.onBindViewHolder(VoucherAdapter.java:61)
VoucherAdapter.java
public class VoucherAdapter extends RecyclerView.Adapter<VoucherAdapter.VoucherViewHolder> {
private final LayoutInflater mInflater;
private final String TAG = "VoucherAdapter";
private List<String> mTitle;
public VoucherAdapter(Context context, List<String> mTitle) {
this.mInflater = LayoutInflater.from(context);
this.mTitle = mTitle;
Log.d(TAG, "Constructor");
}
#NonNull
#Override
public VoucherAdapter.VoucherViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.voucher_card_view, parent, false);
VoucherViewHolder viewHolder = new VoucherViewHolder(view);
Log.d(TAG, "onCreateViewHolder");
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull VoucherAdapter.VoucherViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder");
String title = mTitle.get(position);
holder.voucherTitle.setText(title);
}
#Override
public int getItemCount() {
return mTitle.size();
}
public void setTitle(List<String> Title) {
this.mTitle = Title;
notifyDataSetChanged();
}
public class VoucherViewHolder extends RecyclerView.ViewHolder {
TextView voucherTitle;
public VoucherViewHolder(#NonNull View itemView) {
super(itemView);
Log.d(TAG, "ViewHolder Class");
voucherTitle = itemView.findViewById(R.id.voucherTitleText);
}
}
}
VoucherFragment.java
mViewModel.getmTitleLiveData().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
#Override
public void onChanged(List<String> titleList) {
mTitle.addAll(titleList);
adapter.setTitle(mTitle);
Log.d(TAG, "Data sent to Adapter");
}
});
ViewModel.java
public MutableLiveData<List<String>> getmTitleLiveData() {
repository
.getVoucherCol()
.whereEqualTo("category", categoryTitle)
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
if (e != null) {
mTitleLiveData = null;
Log.d(TAG, "Could not receive TITLE data \n " + e);
return;
}
List<String> titleList = new ArrayList<>();
for (QueryDocumentSnapshot doc: queryDocumentSnapshots) {
if (doc.get("title") != null) {
titleList.add((String) doc.get("title"));
}
}
mTitleLiveData.postValue(titleList);
Log.d(TAG, "Successfully retrieved TITLE data" + titleList);
}
});
return mTitleLiveData;
}
Here
#Override
public void onBindViewHolder(#NonNull VoucherAdapter.VoucherViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder");
String title = mTitle.get(position);
holder.voucherTitle.setText(title);
}
yout mTitle is empty when you create your adapter, so that is way you get the exeption. You need to change it to this one:
if (mTitle.size()>0){
String title = mTitle.get(position);
holder.voucherTitle.setText(title);
}
You suppose to add values to it not like you do here:
public void setTitle(List<String> Title) {
this.mTitle = Title;
notifyDataSetChanged();
}
I strongly recomend you to remove this setTitle method.
Pass this list via your adapter constructor. If you need to change this list - change it in your VoucherFragment. You can do it two ways - the way you did with little changes:
mViewModel.getmTitleLiveData().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
#Override
public void onChanged(List<String> titleList) {
mTitle.addAll(titleList);
adapter.notifyDataSetChanged;
Log.d(TAG, "Data sent to Adapter");
}
});
or another way:
mViewModel.getmTitleLiveData().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
#Override
public void onChanged(List<String> titleList) {
yourRecyclerView.setAdapter(new VoucherAdapter(getContext, titleList))
Log.d(TAG, "Data sent to Adapter");
}
Hope that helps
I want to show all items in RecyclerView in Fragment to RecyclerViewMore in Another Activity when I press "See All Items", but I getting null when I want to receive the data from RecyclerViewMore
//SectionAdapter.java
public class AdapterSectionHotTrendingNews extends RecyclerView.Adapter{
private Context mContext;
private ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews;
public AdapterSectionHotTrendingNews(Context mContext, ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews) {
this.mContext = mContext;
this.modelSectionHotTrendingNews = modelSectionHotTrendingNews;
}
#Override
public SectionHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_section_hottrendingnews, null);
return new SectionHotTrendingNewsViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SectionHotTrendingNewsViewHolder sectionHotTrendingNewsViewHolder = (SectionHotTrendingNewsViewHolder) holder;
ModelSectionHotTrendingNews modelSectionHotTrendingNewsX = modelSectionHotTrendingNews.get(position);
//Set
sectionHotTrendingNewsViewHolder.TVSectionTitle.setText(modelSectionHotTrendingNewsX.getHeaderTitle());
ArrayList singleSectionItems = modelSectionHotTrendingNewsX.getAllItemsInSection();
/*AdapterSingleHotLatestNews.RecyclerViewClickListener listenerLatestNews;
listenerLatestNews = new AdapterSingleHotLatestNews.RecyclerViewClickListener() {
#Override
public void onRowHotLatestNewsClick(View view, int position) {
}
#Override
public void onIconHotLatestNewsClick(View view, int position) {
}
};*/
AdapterSingleHotTrendingNews itemListDataAdapter = new AdapterSingleHotTrendingNews(mContext, singleSectionItems);
/*itemRowHolder.recycler_view_list.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
//Allow ScrollView to intercept touch events once again.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle RecyclerView touch events.
v.onTouchEvent(event);
return true;
}
});*/
sectionHotTrendingNewsViewHolder.BTNHotTrendingNewsMore.setOnClickListener(
new View.OnClickListener() { #Override public void onClick(View v) {
Intent intent = new Intent(mContext, TabMoreHotActivity.class);
new Intent().putExtra("MoreNews", modelSectionHotTrendingNews.get(position).getAllItemsInSection());
mContext.startActivity(intent); } });
/*Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
//SetRecyclerView
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setHasFixedSize(true);
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setAdapter(itemListDataAdapter);
sectionHotTrendingNewsViewHolder.RecyclerViewSectionHotTrendingNews.setNestedScrollingEnabled(false);
}
#Override
public int getItemCount() {
int itemCount = modelSectionHotTrendingNews.size();
return itemCount;
}
public class SectionHotTrendingNewsViewHolder extends RecyclerView.ViewHolder {
protected TextView TVSectionTitle;
protected ImageView BTNHotTrendingNewsMore;
protected RecyclerView RecyclerViewSectionHotTrendingNews;
protected RecyclerView RecyclerViewMoreSectionHotTrendingNews;
public SectionHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVSectionTitle = (TextView) itemView.findViewById(R.id.TV_SectionTitle);
BTNHotTrendingNewsMore= (ImageView) itemView.findViewById(R.id.BTN_HotTrendingNewsMore);
RecyclerViewSectionHotTrendingNews = (RecyclerView) itemView.findViewById(R.id.RecyclerView_Section_HotTrendingNews);
RecyclerViewMoreSectionHotTrendingNews = (RecyclerView) itemView.findViewById(R.id.RecyclerViewMore_Section_HotTrendingNews);
}
}
}
//SingleAdapter.java
public class AdapterSingleHotTrendingNews extends RecyclerView.Adapter{
private Context mContext;
private ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews;
public AdapterSingleHotTrendingNews(Context mContext, ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews) {
this.mContext = mContext;
this.modelSingleHotTrendingNews = modelSingleHotTrendingNews;
}
//Container
#Override
public SingleHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_single_hottrendingnews, null);
return new SingleHotTrendingNewsViewHolder(v);
}
//Fill Container with Model Setter Getter
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SingleHotTrendingNewsViewHolder singleHotTrendingNewsViewHolder = (SingleHotTrendingNewsViewHolder) holder;
final ModelSingleHotTrendingNews modelSingleHotTrendingNewsX = modelSingleHotTrendingNews.get(position);
//Set
singleHotTrendingNewsViewHolder.TVGameDate.setText(modelSingleHotTrendingNewsX.getGamedate());
singleHotTrendingNewsViewHolder.TVGameDescription.setText(modelSingleHotTrendingNewsX.getGamedescription());
singleHotTrendingNewsViewHolder.IMGGameImage.setImageResource(modelSingleHotTrendingNewsX.getGameimage());
singleHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Boolean booltrendingnewssaving = modelSingleHotTrendingNewsX.getTrendingnewssaving();
final int id = modelSingleHotTrendingNewsX.getId();
if (booltrendingnewssaving == true){
Toast.makeText(v.getContext(), "Turn Off Saved News " + id, Toast.LENGTH_SHORT).show();
singleHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_off);
modelSingleHotTrendingNewsX.setTrendingnewssaving(false);
/*updateSavedNewsSaving("update_newssaving", id, false);*/
} else if(booltrendingnewssaving == false) {
Toast.makeText(v.getContext(), "Turn On Saved News " + id, Toast.LENGTH_SHORT).show();
singleHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_on);
modelSingleHotTrendingNewsX.setTrendingnewssaving(true);
/*updateSavedNewsSaving("update_newssaving", id, true);*/
}
}
});
/* Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
singleHotTrendingNewsViewHolder.ROWHotTrendingNewsContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), modelSingleHotTrendingNews.get(position).getGamedescription(), Toast.LENGTH_SHORT).show();
//Passing Data to GameDescriptionActivity
Intent intent = new Intent(mContext, GameDetailActivity.class);
intent.putExtra("ImagePKG", modelSingleHotTrendingNews.get(position).getGameimage());
intent.putExtra("NamePKG", modelSingleHotTrendingNews.get(position).getGamedate());
intent.putExtra("UrlPKG", modelSingleHotTrendingNews.get(position).getId());
intent.putExtra("DescriptionPKG", modelSingleHotTrendingNews.get(position).getGamedescription());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
int itemCount = modelSingleHotTrendingNews.size();
return itemCount;
}
public class SingleHotTrendingNewsViewHolder extends RecyclerView.ViewHolder{
TextView TVGameDate;
TextView TVGameDescription;
ImageView IMGGameImage;
ImageView ICONHotTrendingNewsSaving;
private RelativeLayout ROWHotTrendingNewsContainer;
public SingleHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVGameDate = itemView.findViewById(R.id.TV_GameDate);
TVGameDescription = itemView.findViewById(R.id.TV_GameDescription);
IMGGameImage = itemView.findViewById(R.id.IMG_GameImage);
ICONHotTrendingNewsSaving = itemView.findViewById(R.id.ICON_HotTrendingNewsSaving);
ROWHotTrendingNewsContainer = itemView.findViewById(R.id.ROW_HotTrendingNewsContainer);
}
}
}
//ModelSection.java
public class ModelSectionHotTrendingNews implements Serializable {
private String headerTitle;
private ArrayList<ModelSingleHotTrendingNews> allItemsInSection;
public ModelSectionHotTrendingNews() {
}
public String getHeaderTitle() {
return headerTitle;
}
public void setHeaderTitle(String headerTitle) {
this.headerTitle = headerTitle;
}
public ArrayList<ModelSingleHotTrendingNews> getAllItemsInSection() {
return allItemsInSection;
}
public void setAllItemsInSection(ArrayList<ModelSingleHotTrendingNews> allItemsInSection) {
this.allItemsInSection = allItemsInSection;
}
}
//ModelSingle.java
public class ModelSingleHotTrendingNews implements Serializable {
private int id;
private String gamedate;
private String gamedescription;
private int gameimage;
private Boolean trendingnewssaving;
private String value;
private String message;
public ModelSingleHotTrendingNews(int id, String gamedate, String gamedescription, int gameimage, Boolean trendingnewssaving, String value, String message) {
this.id = id;
this.gamedate = gamedate;
this.gamedescription = gamedescription;
this.gameimage = gameimage;
this.trendingnewssaving = trendingnewssaving;
this.value = value;
this.message = message;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getGamedate() {
return gamedate;
}
public void setGamedate(String gamedate) {
this.gamedate = gamedate;
}
public String getGamedescription() {
return gamedescription;
}
public void setGamedescription(String gamedescription) {
this.gamedescription = gamedescription;
}
public int getGameimage() {
return gameimage;
}
public void setGameimage(int gameimage) {
this.gameimage = gameimage;
}
public Boolean getTrendingnewssaving() {
return trendingnewssaving;
}
public void setTrendingnewssaving(Boolean trendingnewssaving) {
this.trendingnewssaving = trendingnewssaving;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
//This function SectionAdapter.java is to send data from RecyclerView in Fragment to RecyclerViewMore Activity
sectionHotTrendingNewsViewHolder.BTNHotTrendingNewsMore.setOnClickListener(
new View.OnClickListener() { #Override public void onClick(View v) {
Intent intent = new Intent(mContext, TabMoreHotActivity.class);
new Intent().putExtra("MoreNews", modelSectionHotTrendingNews.get(position).getAllItemsInSection());
mContext.startActivity(intent); } });
//I use same Model in those RecyclerViews but different Adapter
//I use RecyclerView in Fragment AdapterSection.java,AdapterSingle.java,ModelSection.java,ModelSingle.java
//I user RecyclerViewMore in Activity
AdapterMoreSection.java,AdapterMoreSingle.java,ModelSection.java,ModelSingle.java
//RecyclerViewMoreActivity.java
public class TabMoreHotActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragmentmore_tabhot);
AdapterMoreSectionHotTrendingNews adapterMoreSectionHotTrendingNews;
ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews = null;
Bundle bundle = getIntent().getExtras();
if(bundle!=null)
{
modelSectionHotTrendingNews = (ArrayList<ModelSectionHotTrendingNews>) bundle.getSerializable("MoreNews");
}
//1
RecyclerView RecyclerViewMoreSingleHotTrendingNews = findViewById(R.id.RecyclerViewMore_Single_HotTrendingNews);
RecyclerViewMoreSingleHotTrendingNews.setHasFixedSize(true);
adapterMoreSectionHotTrendingNews = new AdapterMoreSectionHotTrendingNews(this, modelSectionHotTrendingNews);
RecyclerViewMoreSingleHotTrendingNews.setAdapter(adapterMoreSectionHotTrendingNews);
RecyclerViewMoreSingleHotTrendingNews.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
//Optimized
RecyclerViewMoreSingleHotTrendingNews.setHasFixedSize(true);
RecyclerViewMoreSingleHotTrendingNews.setItemViewCacheSize(20);
}
}
//I got this error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.indofun.android.indojoy, PID: 32309
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at com.indofun.android.indojoy.Adapters.AdapterMore_HotTrendingNews.AdapterMoreSectionHotTrendingNews.getItemCount(AdapterMoreSectionHotTrendingNews.java:109)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4042)
at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3532)
at android.view.View.measure(View.java:23279)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:23279)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:23279)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:23279)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:23279)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:23279)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:23279)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6928)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:898)
at android.view.View.measure(View.java:23279)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2873)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1910)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2165)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1779)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7810)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
//Provide the code it will help me a lot
//UPDATED
//AdapterMoreSingle
public class AdapterMoreSingleHotTrendingNews extends RecyclerView.Adapter{
private Context mContext;
private ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews;
public AdapterMoreSingleHotTrendingNews(Context mContext, ArrayList<ModelSingleHotTrendingNews> modelSingleHotTrendingNews) {
this.mContext = mContext;
this.modelSingleHotTrendingNews = modelSingleHotTrendingNews;
}
//Container
#Override
public SingleMoreHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.itemmore_single_hottrendingnews, null);
return new SingleMoreHotTrendingNewsViewHolder(v);
}
//Fill Container with Model Setter Getter
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SingleMoreHotTrendingNewsViewHolder singleMoreHotTrendingNewsViewHolder = (SingleMoreHotTrendingNewsViewHolder) holder;
final ModelSingleHotTrendingNews modelSingleHotTrendingNewsX = modelSingleHotTrendingNews.get(position);
//Set
singleMoreHotTrendingNewsViewHolder.TVGameDate.setText(modelSingleHotTrendingNewsX.getGamedate());
singleMoreHotTrendingNewsViewHolder.TVGameDescription.setText(modelSingleHotTrendingNewsX.getGamedescription());
singleMoreHotTrendingNewsViewHolder.IMGGameImage.setImageResource(modelSingleHotTrendingNewsX.getGameimage());
singleMoreHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Boolean booltrendingnewssaving = modelSingleHotTrendingNewsX.getTrendingnewssaving();
final int id = modelSingleHotTrendingNewsX.getId();
if (booltrendingnewssaving == true){
Toast.makeText(v.getContext(), "Turn Off Saved News " + id, Toast.LENGTH_SHORT).show();
singleMoreHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_off);
modelSingleHotTrendingNewsX.setTrendingnewssaving(false);
/*updateSavedNewsSaving("update_newssaving", id, false);*/
} else if(booltrendingnewssaving == false) {
Toast.makeText(v.getContext(), "Turn On Saved News " + id, Toast.LENGTH_SHORT).show();
singleMoreHotTrendingNewsViewHolder.ICONHotTrendingNewsSaving.setImageResource(R.drawable.saved_on);
modelSingleHotTrendingNewsX.setTrendingnewssaving(true);
/*updateSavedNewsSaving("update_newssaving", id, true);*/
}
}
});
/* Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
singleMoreHotTrendingNewsViewHolder.ROWHotTrendingNewsContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), modelSingleHotTrendingNews.get(position).getGamedescription(), Toast.LENGTH_SHORT).show();
//Passing Data to GameDescriptionActivity
Intent intent = new Intent(mContext, GameDetailActivity.class);
intent.putExtra("ImagePKG", modelSingleHotTrendingNews.get(position).getGameimage());
intent.putExtra("NamePKG", modelSingleHotTrendingNews.get(position).getGamedate());
intent.putExtra("UrlPKG", modelSingleHotTrendingNews.get(position).getId());
intent.putExtra("DescriptionPKG", modelSingleHotTrendingNews.get(position).getGamedescription());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
int itemCount = modelSingleHotTrendingNews.size();
return itemCount;
}
public class SingleMoreHotTrendingNewsViewHolder extends RecyclerView.ViewHolder{
TextView TVGameDate;
TextView TVGameDescription;
ImageView IMGGameImage;
ImageView ICONHotTrendingNewsSaving;
private RelativeLayout ROWHotTrendingNewsContainer;
public SingleMoreHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVGameDate = itemView.findViewById(R.id.TV_GameDate);
TVGameDescription = itemView.findViewById(R.id.TV_GameDescription);
IMGGameImage = itemView.findViewById(R.id.IMG_GameImage);
ICONHotTrendingNewsSaving = itemView.findViewById(R.id.ICON_HotTrendingNewsSaving);
ROWHotTrendingNewsContainer = itemView.findViewById(R.id.ROW_HotTrendingNewsContainer);
}
}
}
//UPDATED2 AdapterSectionMore.java
public class AdapterMoreSectionHotTrendingNews extends RecyclerView.Adapter {
private Context mContext;
private ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews;
public AdapterMoreSectionHotTrendingNews(Context mContext, ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews) {
this.mContext = mContext;
this.modelSectionHotTrendingNews = modelSectionHotTrendingNews;
}
#Override
public SectionMoreHotTrendingNewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemmore_section_hottrendingnews, null);
return new SectionMoreHotTrendingNewsViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SectionMoreHotTrendingNewsViewHolder sectionMoreHotTrendingNewsViewHolder = (SectionMoreHotTrendingNewsViewHolder) holder;
ModelSectionHotTrendingNews modelSectionHotTrendingNewsX = modelSectionHotTrendingNews.get(position);
//Set
sectionMoreHotTrendingNewsViewHolder.TVSectionTitle.setText(modelSectionHotTrendingNewsX.getHeaderTitle());
// here you have to change your ArrayList to ArrayList<ModelSingleHotTrendingNews>
ArrayList<ModelSingleHotTrendingNews> singleSectionItems = modelSectionHotTrendingNewsX.getAllItemsInSection();
/*AdapterSingleHotLatestNews.RecyclerViewClickListener listenerLatestNews;
listenerLatestNews = new AdapterSingleHotLatestNews.RecyclerViewClickListener() {
#Override
public void onRowHotLatestNewsClick(View view, int position) {
}
#Override
public void onIconHotLatestNewsClick(View view, int position) {
}
};*/
AdapterMoreSingleHotTrendingNews itemListDataAdapter = new AdapterMoreSingleHotTrendingNews(mContext, singleSectionItems);
/*itemRowHolder.recycler_view_list.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
//Allow ScrollView to intercept touch events once again.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle RecyclerView touch events.
v.onTouchEvent(event);
return true;
}
});*/
final String sectionTitle = modelSectionHotTrendingNewsX.getHeaderTitle();
sectionMoreHotTrendingNewsViewHolder.BTNHotTrendingNewsMore.setOnClickListener(
new View.OnClickListener() {
#Override public void onClick(View v) {
//More IN RecyclerViewMore
}
});
/*Glide.with(mContext)
.load(feedItem.getImageURL())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.error(R.drawable.bg)
.into(feedListRowHolder.thumbView);*/
//SetRecyclerView
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setHasFixedSize(true);
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setAdapter(itemListDataAdapter);
sectionMoreHotTrendingNewsViewHolder.RecyclerViewMoreSectionHotTrendingNews.setNestedScrollingEnabled(false);
}
#Override
public int getItemCount() {
int itemCount = modelSectionHotTrendingNews.size();
return itemCount;
}
public class SectionMoreHotTrendingNewsViewHolder extends RecyclerView.ViewHolder {
protected TextView TVSectionTitle;
protected ImageView BTNHotTrendingNewsMore;
protected RecyclerView RecyclerViewMoreSectionHotTrendingNews;
public SectionMoreHotTrendingNewsViewHolder(View itemView) {
super(itemView);
TVSectionTitle = (TextView) itemView.findViewById(R.id.TV_SectionTitle);
BTNHotTrendingNewsMore= (ImageView) itemView.findViewById(R.id.BTN_HotTrendingNewsMore);
RecyclerViewMoreSectionHotTrendingNews = (RecyclerView) itemView.findViewById(R.id.RecyclerViewMore_Section_HotTrendingNews);
}
}
}
Because you are passing null modelSectionHotTrendingNews to your adapter.
You just need to initialize your ArrayList in your TabMoreHotActivity
And one more thing you have to set layout manger to your recycler view before set adapter.
public class TabMoreHotActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragmentmore_tabhot);
AdapterMoreSectionHotTrendingNews adapterMoreSectionHotTrendingNews;
// here you have to initialize it
ArrayList<ModelSectionHotTrendingNews> modelSectionHotTrendingNews = new ArrayList<>();
Bundle bundle = getIntent().getExtras();
if(bundle!=null)
{
modelSectionHotTrendingNews = (ArrayList<ModelSectionHotTrendingNews>) bundle.getSerializable("MoreNews");
}
//1
RecyclerView RecyclerViewMoreSingleHotTrendingNews = findViewById(R.id.RecyclerViewMore_Single_HotTrendingNews);
RecyclerViewMoreSingleHotTrendingNews.setHasFixedSize(true);
adapterMoreSectionHotTrendingNews = new AdapterMoreSectionHotTrendingNews(this, modelSectionHotTrendingNews);
// here have to set layout manager before set adapter
RecyclerViewMoreSingleHotTrendingNews.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
// and then you have to set adapter to recyclerview
RecyclerViewMoreSingleHotTrendingNews.setAdapter(adapterMoreSectionHotTrendingNews);
//Optimized
RecyclerViewMoreSingleHotTrendingNews.setHasFixedSize(true);
RecyclerViewMoreSingleHotTrendingNews.setItemViewCacheSize(20);
}
}
UPDATE
Change ArrayList to ArrayList<ModelSingleHotTrendingNews> inside onBindViewHolder in AdapterMoreSectionHotTrendingNews.
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final SectionMoreHotTrendingNewsViewHolder sectionMoreHotTrendingNewsViewHolder = (SectionMoreHotTrendingNewsViewHolder) holder;
ModelSectionHotTrendingNews modelSectionHotTrendingNewsX = modelSectionHotTrendingNews.get(position);
//Set
sectionMoreHotTrendingNewsViewHolder.TVSectionTitle.setText(modelSectionHotTrendingNewsX.getHeaderTitle());
// here you have to change your ArrayList to ArrayList<ModelSingleHotTrendingNews>
ArrayList<ModelSingleHotTrendingNews> singleSectionItems = modelSectionHotTrendingNewsX.getAllItemsInSection();
// reset of your codes here.
For this error
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
By #Jakir answer, you can initialize ArrayList for extra point initialize with specific size (i.e new ArrayList<>(0);) to reduce the memory usage because of array list default a lot memory of 10 objects in memory.
or
check this condition in getItem
#Override
public int getItemCount() {
return modelSectionHotTrendingNews != null && modelSectionHotTrendingNews.size();
}
It will resolve this error.
For serializable parsing in your code
Intent intent = new Intent(mContext, TabMoreHotActivity.class);
// here you create put extra in new intent not the intent that you created
new Intent().putExtra("MoreNews", modelSectionHotTrendingNews.get(position).getAllItemsInSection());
mContext.startActivity(intent);
Change this to
Intent intent = new Intent(mContext, TabMoreHotActivity.class);
// here you create put extra in new intent not the intent that you created
intent.putExtra("MoreNews", modelSectionHotTrendingNews.get(position).getAllItemsInSection());
mContext.startActivity(intent);
Happy coding.... ;)
I've got an activity which show up some data retrieved from a firebase. I have a method which do that programmatically scroll the recycler view to the today's event but if I need this method to work, I need to intent my activity two times... How can I fix it please?
Planning.java :
public void setUpRecyclerView(){
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
private void loadDataFromFirebase(){
db = FirebaseFirestore.getInstance();
if(eventsArrayList.size()>0){
eventsArrayList.clear();}
db.collection("Planning").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
for(DocumentSnapshot querySnapshot: task.getResult()){
Events Nom = new Events(querySnapshot.getString("Nom"),querySnapshot.getString("Lieu"),querySnapshot.getString("Heure"),querySnapshot.getString("Minute"),querySnapshot.getString("Day"));
eventsArrayList.add(Nom);
}
tvLoad.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
adapter = new MyRecyclerViewAdapter(Planning.this, eventsArrayList);
recyclerView.setAdapter(adapter);
pos = MyRecyclerViewAdapter.getPos();
recyclerView.scrollToPosition(pos);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Planning.this, "Erreur(s) :", Toast.LENGTH_SHORT).show();
Log.v("---]---", e.getMessage());
}
});
}
#Override
protected void onStart(){
super.onStart();
pos = MyRecyclerViewAdapter.getPos();
recyclerView.scrollToPosition(pos);
}
MyRecyclerViewAdapter :
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewHolder> {
Planning planning;
ArrayList<Events> eventsArrayList;
static int pos;
public MyRecyclerViewAdapter(Planning planning, ArrayList<Events> eventsArrayList) {
this.planning = planning;
this.eventsArrayList = eventsArrayList;
}
#NonNull
#Override
public MyRecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater layoutInflater = LayoutInflater.from(planning.getBaseContext());
View view = layoutInflater.inflate(R.layout.list_item, viewGroup, false);
return new MyRecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyRecyclerViewHolder holder, int position) {
Calendar cal = Calendar.getInstance();
holder.tvLieu.setVisibility(View.VISIBLE);
holder.tvDate.setVisibility(View.VISIBLE);
holder.cardView.setCardBackgroundColor(Color.WHITE);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.tvNom.getLayoutParams();
params.gravity = Gravity.START;
holder.tvNom.setLayoutParams(params);
holder.tvNom.setText(eventsArrayList.get(position).getNom());
holder.tvLieu.setText(eventsArrayList.get(position).getLieu());
holder.tvDate.setText(eventsArrayList.get(position).getHeure() + "h" + eventsArrayList.get(position).getMinute());
if(TextUtils.isEmpty(eventsArrayList.get(position).getHeure())){
holder.tvDate.setVisibility(View.GONE);
holder.tvLieu.setVisibility(View.GONE);
params.gravity = Gravity.CENTER;
holder.tvNom.setLayoutParams(params);
holder.cardView.setCardBackgroundColor(Color.parseColor("#227c97"));
}
if(TextUtils.equals(eventsArrayList.get(position).getDay(), String.valueOf(cal.get(Calendar.DAY_OF_MONTH)))){
pos = position;
}
}
public static int getPos(){
return pos;
}
#Override
public int getItemCount() {
return eventsArrayList.size();
}
}
I know the title seems weird, but basically what I want is to apply pagination to my list and control it using the url api endpoint as a parameter.!
so the endpoint looks like this for example > www.someapi.com/josn/list?pageIndex=1
and it will give a response with array of 10 items, and if I want more I have to change the index of the parameter to 2 and so on.!
response
{
"Succeeded": true,
"AvailableChallenge": true,
"DebugError": "",
"NextPage": 2,
"AllPages": 2,
"Challenges": [
{
"ID": 114,
"Title": "Amet sit id ratione dolorem numquam"
},
{
"ID": 114,
"Title": "Amet sit id ratione dolorem numquam"
}
...
..
.
]
}
I tied everything, but couldn't get it done correctly, I have tried most of the solutions in here and no luck.
I've also tried to use these two library Paginate & recyclerview-paginated and even this SuperRecyclerView. but it didn't work.!
Any help with the best logic for controlling this will help a lot.
Code for SuperRecyclerView
public class ChallengesListFragment extends BaseFragment {
private int pageNumber = 1;
private SuperRecyclerView recyclerview;
private ArrayList<ChallengeActive> data;
private ChallengesAdapter adapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_challenges_list, container, false);
initView(rootView);
initRecycler();
getData(1);
return rootView;
}
private void initRecycler() {
data = new ArrayList<>();
final RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerview.setLayoutManager(mLayoutManager);
adapter = new ChallengesAdapter(data, getActivity(), this);
recyclerview.setAdapter(adapter);
recyclerview.setupMoreListener(new OnMoreListener() {
#Override
public void onMoreAsked(int overallItemsCount, int itemsBeforeMore, int maxLastVisiblePosition) {
pageNumber++;
getData(maxLastVisiblePosition);
}
}, 10);
recyclerview.setRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
pageNumber = 1;
getData(pageNumber);
}
});
}
private void getData(final int pageNumber) {
WebRequests.GetActiveChallenges(pageNumber, new onResult() {
#Override
public void onSuccess(Object object) {
ArrayList<ChallengeActive> list = (ArrayList<ChallengeActive>) object;
data.clear();
data.addAll(list);
adapter.notifyDataSetChanged();
}
#Override
public void onFail(Object object) {
Toast.makeText(getActivity(), "Something went wrong, try again later",
Toast.LENGTH_SHORT).show();
}
});
}
}
Here is how I did it in a project... In this case I add more elements when bottom of the list is reached
rv_flohtainer_events.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!rv_flohtainer_events.canScrollVertically(1)){
if (!(eventsResponse.getCurrent_page() == eventsResponse.getLast_page())) {
pageEventsRequest++;
makeVendorEventsRequest();
}
}
}
});
The request I do is with retrofit, and it looks like this
#GET(RestClient.API_EVENTS_URL)
Call<EventsResponse> getEvents(#Query("page") int page)
After some time, I did it using Paginate Library
The Code
public class ChallengesListFragment extends BaseFragment implements OnRefreshListener, Paginate.Callbacks {
// other variables..
private int currentPage = 1;
private boolean hasMore;
private boolean loadingInProgress;
#RequiresApi(api = VERSION_CODES.LOLLIPOP)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_challenges_list, container, false);
initView(rootView);
initToolbar();
initRecycler();
getData();
return rootView;
}
private void initRecycler() {
data = new ArrayList<>();
mLayoutManager = new LinearLayoutManager(getActivity());
recyclerview.setLayoutManager(mLayoutManager);
adapter = new ChallengesAdapter(data, getActivity(), this);
recyclerview.setAdapter(adapter);
Paginate.with(recyclerview, this)
.setLoadingTriggerThreshold(3)
.addLoadingListItem(false)
.build();
}
private void getData() {
swipeRefresh.setRefreshing(true);
WebRequests.GetActiveChallenges(currentPage, new onResult() {
#Override
public void onSuccess(Object object) {
ArrayList<Challenge> list = (ArrayList<Challenge>) object;
data.addAll(list);
adapter.notifyDataSetChanged();
if (list.size() == 10) {
currentPage++;
hasMore = true;
} else {
hasMore = false;
}
loadingInProgress = false;
swipeRefresh.setRefreshing(false);
}
#Override
public void onFail(Object object) {
Toast.makeText(getActivity(), "Something went wrong, try again later",
Toast.LENGTH_SHORT).show();
swipeRefresh.setRefreshing(false);
}
});
}
public ChallengesListFragment() {
}
#Override
public void onRefresh() {
currentPage = 1;
loadingInProgress = true;
getData();
}
#Override
public void onLoadMore() {
loadingInProgress = true;
Handler mHandler = new Handler();
final Runnable hintRunnable = new Runnable() {
#Override
public void run() {
getData();
}
};
mHandler.postDelayed(hintRunnable, 1500);
}
#Override
public boolean isLoading() {
return loadingInProgress;
}
#Override
public boolean hasLoadedAllItems() {
return !hasMore;
}
}
I am trying to open a url link when I click on a list item in a recyclerview but I keep getting a NullPointerException. I am using a ViewPager, I don't know if this is the cause of the exception, maybe I'm doing something wrong. Please check out my code and logcat below.
This is my adapter:
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsHolder> {
private ArrayList<News> mNews = new ArrayList<>();
private static ClickListener clickListener;
public NewsAdapter(ArrayList<News> news) {
mNews = news;
}
private static String timeConverter(String inputTime) {
long startTime = 0;
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
simpleDate.setTimeZone(TimeZone.getTimeZone("GMT"));
try {
Date date = simpleDate.parse(inputTime);
startTime = date.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
long currentTime = System.currentTimeMillis();
long end = currentTime - startTime;
long seconds = TimeUnit.MILLISECONDS.toSeconds(end);
long minutes = TimeUnit.SECONDS.toMinutes(seconds);
long hours = TimeUnit.MINUTES.toHours(minutes);
if (minutes > 59) {
return hours + "h";
}else if (seconds > 59) {
return minutes + "m";
}else {
return seconds + "s";
}
}
#Override
public NewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_view, parent, false);
return new NewsHolder(view);
}
#Override
public void onBindViewHolder(NewsHolder holder, int position) {
String imagePath = mNews.get(position).getImageUrl();
Picasso.with(holder.mImageView.getContext()).load(imagePath).into(holder.mImageView);
holder.mNewsTextView.setText(mNews.get(position).getNews());
holder.mTimeStampTextView.setText(timeConverter(mNews.get(position).getTime()));
}
#Override
public int getItemCount() {
return mNews.size();
}
// NewsHolder class that extends the ViewHolder
public static class NewsHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView mImageView;
private TextView mNewsTextView;
private TextView mTimeStampTextView;
// Setting the views
public NewsHolder(View itemView) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.simple_imageView);
mNewsTextView = (TextView) itemView.findViewById(R.id.news_tv);
mTimeStampTextView = (TextView) itemView.findViewById(R.id.time_tv);
}
#Override
public void onClick(View view) {
clickListener.onItemClick(getAdapterPosition(), view);
}
}
public void setOnItemClickListener(ClickListener listener) {
NewsAdapter.clickListener = listener;
}
public interface ClickListener {
void onItemClick(int position, View v);
}
}
This is one of my ViewPager fragments:
public class TechFragment extends Fragment {
private SwipeRefreshLayout mSwipeRefreshLayout;
private TextView mErrorMessage;
private NewsAdapter mNewsAdapter;
ArrayList<News> news;
NetworkInfo info;
// The Loader takes in a bundle
Bundle sourceBundle = new Bundle();
private final String LOG_TAG = MainActivity.class.getSimpleName();
private static final String TECH_NEWS_QUERY_URL = "query";
private static final String TECH_NEWS_SOURCE = "techcrunch";
private static final String TECH_SOURCE_CATEGORY = "latest";
private static final int TECH_NEWS_LOADER = 22;
private RecyclerView mRecyclerView;
public TechFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_news, container, false);
mErrorMessage = (TextView) view.findViewById(R.id.tv_error_message);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_main);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefresh);
getActivity().getSupportLoaderManager().initLoader(TECH_NEWS_LOADER, sourceBundle, new NewsDataLoader());
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Log.v(LOG_TAG, "Refreshing");
restartLoader();
mSwipeRefreshLayout.setColorSchemeResources(
R.color.colorPrimary,
R.color.colorPrimaryDark);
}
});
return view;
}
private boolean isConnected() {
ConnectivityManager cm = (ConnectivityManager) getActivity()
.getSystemService(CONNECTIVITY_SERVICE);
info = cm.getActiveNetworkInfo();
return info != null && info.isConnectedOrConnecting();
}
private int anyRandomInt(Random random) {
return random.nextInt();
}
private void restartLoader() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
URL techNewsUrl = NetworkUtils.buildUrl(TECH_NEWS_SOURCE, TECH_SOURCE_CATEGORY);
sourceBundle.putString(TECH_NEWS_QUERY_URL, techNewsUrl.toString());
Random random = new Random();
int uniqueId = anyRandomInt(random); //Generates a new ID for each loader call;
LoaderManager loaderManager = getActivity().getSupportLoaderManager();
if (loaderManager.getLoader(TECH_NEWS_LOADER) == null) {
loaderManager.initLoader(uniqueId, sourceBundle, new NewsDataLoader());
} else {
loaderManager.restartLoader(TECH_NEWS_LOADER, sourceBundle, new
NewsDataLoader());
}
}
}, 5000);
mSwipeRefreshLayout.setRefreshing(false);
Log.v(LOG_TAG, "Finished refreshing");
}
private void showErrorScreen() {
mErrorMessage.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.INVISIBLE);
mErrorMessage.setText(getString(R.string.internet_error));
}
public class NewsDataLoader implements LoaderManager.LoaderCallbacks<ArrayList<News>> {
#Override
public Loader<ArrayList<News>> onCreateLoader(int id, final Bundle args) {
if (isConnected()) {
mErrorMessage.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
return new AsyncTaskLoader<ArrayList<News>>(getActivity()) {
ArrayList<News> mNewsData;
#Override
protected void onStartLoading() {
super.onStartLoading();
if (mNewsData != null) {
deliverResult(mNewsData);
} else {
forceLoad();
mSwipeRefreshLayout.setRefreshing(true);
}
}
#Override
public ArrayList<News> loadInBackground() {
try {
ArrayList<News> news = NetworkUtils.parseJSON(TECH_NEWS_SOURCE, TECH_SOURCE_CATEGORY);
return news;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public void deliverResult(ArrayList<News> data) {
mNewsData = data;
super.deliverResult(data);
}
};
} else {
showErrorScreen();
return null;
}
}
#Override
public void onLoadFinished(Loader<ArrayList<News>> loader, final ArrayList<News> data) {
mSwipeRefreshLayout.setRefreshing(false);
if (null == data) {
showErrorScreen();
} else {
mErrorMessage.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
if (news != null) {
news.clear();
news.addAll(data);
mNewsAdapter = new NewsAdapter(news);
mRecyclerView.setAdapter(mNewsAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
mNewsAdapter.notifyDataSetChanged();
} else {
news = data;
}
}
mNewsAdapter.setOnItemClickListener(new NewsAdapter.ClickListener() {
#Override
public void onItemClick(int position, View v) {
News currentNews = news.get(position);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(currentNews.getUrl()));
if (intent.resolveActivity(getActivity().getPackageManager()) != null){
startActivity(intent);
}
}
});
}
#Override
public void onLoaderReset(Loader<ArrayList<News>> loader) {
}
}
}
And this is my error:
06-13 12:11:38.667 3890-3890/com.ire.blogbot E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ire.blogbot, PID: 3890
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.ire.blogbot.adapter.NewsAdapter.setOnItemClickListener(com.ire.blogbot.adapter.NewsAdapter$ClickListener)' on a null object reference
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader.onLoadFinished(TechFragment.java:192)
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader.onLoadFinished(TechFragment.java:131)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:476)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:444)
at android.support.v4.content.Loader.deliverResult(Loader.java:126)
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader$1.deliverResult(TechFragment.java:164)
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader$1.deliverResult(TechFragment.java:137)
at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:252)
at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:80)
at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:485)
at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:502)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Try this code, it is working
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
#Override public void onItemClick(View view, int position) {
// on click
}
})
);
RecyclerItemClickListener Class
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}}
Move
mNewsAdapter.setOnItemClickListener(new NewsAdapter.ClickListener() {
#Override
public void onItemClick(int position, View v) {
News currentNews = news.get(position);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(currentNews.getUrl()));
if (intent.resolveActivity(getActivity().getPackageManager()) != null){
startActivity(intent);
}
}
});
after
mNewsAdapter = new NewsAdapter(news);