I'm using ViewPager2 in my app to show some images it worked well when I used images from drawable but when i try to load images from links it shows error. I'm new to this so please help me how to load them from url.
It throws error at the adapter class as items.size(); refers to null.
Item Class
public class ImageSlider1_Item {
private String imageURL;
public ImageSlider1_Item(String imageURL){
this.imageURL = imageURL;
}
public String getImageURL (){
return imageURL;
}
}
Adapter Class
public class ImageSlider1_Adapter extends RecyclerView.Adapter<ImageSlider1_Adapter.ImageSlider1_ViewHolder>{
private List<ImageSlider1_Item> items;
private ViewPager2 viewPager2;
public ImageSlider1_Adapter(List<ImageSlider1_Item> items, ViewPager2 viewPager2) {
this.items = items;
this.viewPager2 = viewPager2;
}
#NonNull
#Override
public ImageSlider1_ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ImageSlider1_ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.image_slider_layout, parent, false));
}
#Override
public void onBindViewHolder(#NonNull ImageSlider1_ViewHolder holder, int position) {
holder.setImageView(items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
class ImageSlider1_ViewHolder extends RecyclerView.ViewHolder{
private RoundedImageView imageView;
ImageSlider1_ViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageSlide);
}
void setImageView(ImageSlider1_Item slider1Item){
Glide.with(itemView.getContext())
.load(slider1Item.getImageURL())
.into(imageView);
}
}
}
Main Activity
FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
firebaseFirestore.collection("Image Sliders").document("Whats New").get()
.addOnSuccessListener(documentSnapshot -> {
slider1_items = new ArrayList<>();
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image1")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image2")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image3")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image4")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image5")));
});
ViewPager2 viewPager2 = view.findViewById(R.id.imageSlider_1);
viewPager2.setAdapter(new ImageSlider1_Adapter(slider1_items, viewPager2));
viewPager2.setClipToPadding(false);
viewPager2.setClipChildren(false);
viewPager2.setOffscreenPageLimit(3);
viewPager2.getChildAt(0).setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);
CompositePageTransformer compositePageTransformer = new CompositePageTransformer();
compositePageTransformer.addTransformer(new MarginPageTransformer(40));
viewPager2.setPageTransformer(compositePageTransformer);
1st change your adapter like this :
public class ImageSlider1_Adapter extends RecyclerView.Adapter<ImageSlider1_Adapter.ImageSlider1_ViewHolder>{
private List<ImageSlider1_Item> items;
private Context context;
public ImageSlider1_Adapter(List<ImageSlider1_Item> items) {
this.items = items;
}
public void setItems(List<ImageSlider1_Item> items) {
this.items = items;
}
#NonNull
#Override
public ImageSlider1_ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
return new ImageSlider1_ViewHolder(LayoutInflater.from(context).inflate(R.layout.image_slider_layout, parent, false));
}
#Override
public void onBindViewHolder(#NonNull ImageSlider1_ViewHolder holder, int position) {
holder.setImageView(items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
class ImageSlider1_ViewHolder extends RecyclerView.ViewHolder{
private RoundedImageView imageView;
ImageSlider1_ViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageSlide);
}
void setImageView(ImageSlider1_Item slider1Item){
//custom settings for fast loading image
RequestOptions options = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.centerCrop()
.priority(Priority.HIGH)
.format(DecodeFormat.PREFER_RGB_565);
Glide.with(context)
.applyDefaultRequestOptions(options)
.load(slider1Item.getImageURL())
.thumbnail(0.4f)
.into(imageView);
}
}
}
next in your activity
//1st initialize list & adapter
private List<ImageSlider1_Item> slider1_items = new ArrayList<>();
private ImageSlider1_Adapter adapter;
//2sd initialize views
ViewPager2 viewPager2 = view.findViewById(R.id.imageSlider_1);
viewPager2.setClipToPadding(false);
viewPager2.setClipChildren(false);
viewPager2.setOffscreenPageLimit(3);
viewPager2.getChildAt(0).setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);
CompositePageTransformer compositePageTransformer = new CompositePageTransformer();
compositePageTransformer.addTransformer(new MarginPageTransformer(40));
viewPager2.setPageTransformer(compositePageTransformer);
//3d remove ViewPager2 from adapter constructor - no need for that
//and initialize new adapter without viewPager2
adapter = new ImageSlider1_Adapter(slider1_items);
//next set adapter to ViewPager2
viewPager2.setAdapter(adapter);
FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
firebaseFirestore.collection("Image Sliders").document("Whats New").get()
.addOnSuccessListener(documentSnapshot -> {
slider1_items.clear();
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image1")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image2")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image3")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image4")));
slider1_items.add(new ImageSlider1_Item(documentSnapshot.getString("Image5")));
//next setList to adapter
adapter.setItems(slider1_items);
adapter.notifyDataSetChanged();
});
Related
I try to implement expandable RecyclerView as shown in this example :
https://github.com/CodingSTUFF070/Nested-RecyclerView-Inside-Expandable-RecyclerView
But I have bug :
When I implement the same for my app. Steps to reproduce - Click 1st item (Instant Food and Noodles) and scroll to last and click last item (Personal Care) without closing 1st opened item. Now, if you scroll-up and see the child items of 1st parent, you'll see child items of lastly opened parent (Personal Care).
Please tell me how to fix this?
MainActivity:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<DataModel> mList;
private ItemAdapter adapter;
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.main_recyclervie);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mList = new ArrayList<>();
//list1
List<String> nestedList1 = new ArrayList<>();
nestedList1.add("Jams and Honey");
nestedList1.add("Pickles and Chutneys");
nestedList1.add("Readymade Meals");
nestedList1.add("Chyawanprash and Health Foods");
nestedList1.add("Pasta and Soups");
nestedList1.add("Sauces and Ketchup");
nestedList1.add("Namkeen and Snacks");
nestedList1.add("Honey and Spreads");
List<String> nestedList2 = new ArrayList<>();
nestedList2.add("Book");
nestedList2.add("Pen");
nestedList2.add("Office Chair");
nestedList2.add("Pencil");
nestedList2.add("Eraser");
nestedList2.add("NoteBook");
nestedList2.add("Map");
nestedList2.add("Office Table");
List<String> nestedList3 = new ArrayList<>();
nestedList3.add("Decorates");
nestedList3.add("Tea Table");
nestedList3.add("Wall Paint");
nestedList3.add("Furniture");
nestedList3.add("Bedsits");
nestedList3.add("Certain");
nestedList3.add("Namkeen and Snacks");
nestedList3.add("Honey and Spreads");
List<String> nestedList4 = new ArrayList<>();
nestedList4.add("Pasta");
nestedList4.add("Spices");
nestedList4.add("Salt");
nestedList4.add("Chyawanprash");
nestedList4.add("Maggie");
nestedList4.add("Sauces and Ketchup");
nestedList4.add("Snacks");
nestedList4.add("Kurkure");
List<String> nestedList5 = new ArrayList<>();
nestedList5.add("Jams and Honey");
nestedList5.add("Pickles and Chutneys");
nestedList5.add("Readymade Meals");
nestedList5.add("Chyawanprash and Health Foods");
nestedList5.add("Pasta and Soups");
nestedList5.add("Sauces and Ketchup");
nestedList5.add("Namkeen and Snacks");
nestedList5.add("Honey and Spreads");
List<String> nestedList6 = new ArrayList<>();
nestedList6.add("Pasta");
nestedList6.add("Spices");
nestedList6.add("Salt");
nestedList6.add("Chyawanprash");
nestedList6.add("Maggie");
nestedList6.add("Sauces and Ketchup");
nestedList6.add("Snacks");
nestedList6.add("Kurkure");
List<String> nestedList7 = new ArrayList<>();
nestedList7.add("Decorates");
nestedList7.add("Tea Table");
nestedList7.add("Wall Paint");
nestedList7.add("Furniture");
nestedList7.add("Bedsits");
nestedList7.add("Certain");
nestedList7.add("Namkeen and Snacks");
nestedList7.add("Honey and Spreads");
mList.add(new DataModel(nestedList1 , "Instant Food and Noodles"));
mList.add(new DataModel( nestedList2,"Stationary"));
mList.add(new DataModel( nestedList3,"Home Care"));
mList.add(new DataModel(nestedList4 ,"Grocery & Staples"));
mList.add(new DataModel(nestedList5,"Pet Care"));
mList.add(new DataModel(nestedList6,"Baby Care"));
mList.add(new DataModel(nestedList7 ,"Personal Care"));
adapter = new ItemAdapter(mList);
recyclerView.setAdapter(adapter);
}
}
DataModel:
public class DataModel {
private List<String> nestedList;
private String itemText;
private boolean isExpandable;
public DataModel(List<String> itemList, String itemText) {
this.nestedList = itemList;
this.itemText = itemText;
isExpandable = false;
}
public void setExpandable(boolean expandable) {
isExpandable = expandable;
}
public List<String> getNestedList() {
return nestedList;
}
public String getItemText() {
return itemText;
}
public boolean isExpandable() {
return isExpandable;
}
}
ItemAdapter:
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ItemViewHolder> {
private List<DataModel> mList;
private List<String> list = new ArrayList<>();
public ItemAdapter(List<DataModel> mList){
this.mList = mList;
}
#NonNull
#Override
public ItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.each_item , parent , false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ItemViewHolder holder, int position) {
DataModel model = mList.get(position);
holder.mTextView.setText(model.getItemText());
boolean isExpandable = model.isExpandable();
holder.expandableLayout.setVisibility(isExpandable ? View.VISIBLE : View.GONE);
if (isExpandable){
holder.mArrowImage.setImageResource(R.drawable.arrow_up);
}else{
holder.mArrowImage.setImageResource(R.drawable.arrow_down);
}
NestedAdapter adapter = new NestedAdapter(list);
holder.nestedRecyclerView.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext()));
holder.nestedRecyclerView.setHasFixedSize(true);
holder.nestedRecyclerView.setAdapter(adapter);
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
model.setExpandable(!model.isExpandable());
list = model.getNestedList();
notifyItemChanged(holder.getAdapterPosition());
}
});
}
#Override
public int getItemCount() {
return mList.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder{
private LinearLayout linearLayout;
private RelativeLayout expandableLayout;
private TextView mTextView;
private ImageView mArrowImage;
private RecyclerView nestedRecyclerView;
public ItemViewHolder(#NonNull View itemView) {
super(itemView);
linearLayout = itemView.findViewById(R.id.linear_layout);
expandableLayout = itemView.findViewById(R.id.expandable_layout);
mTextView = itemView.findViewById(R.id.itemTv);
mArrowImage = itemView.findViewById(R.id.arro_imageview);
nestedRecyclerView = itemView.findViewById(R.id.child_rv);
}
}
}
NestedAdapter:
public class NestedAdapter extends RecyclerView.Adapter<NestedAdapter.NestedViewHolder> {
private List<String> mList;
public NestedAdapter(List<String> mList){
this.mList = mList;
}
#NonNull
#Override
public NestedViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.nested_item , parent , false);
return new NestedViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull NestedViewHolder holder, int position) {
holder.mTv.setText(mList.get(position));
}
#Override
public int getItemCount() {
return mList.size();
}
public class NestedViewHolder extends RecyclerView.ViewHolder{
private TextView mTv;
public NestedViewHolder(#NonNull View itemView) {
super(itemView);
mTv = itemView.findViewById(R.id.nestedItemTv);
}
}
}
As I fetched and show the dates (see image) as the title of the main recyclerview. I want to show the available slots data instead of the 0 1 2 etc elements. The code is attached below
Url for json data
https://run.mocky.io/v3/c9bd7858-0e41-422f-b1d2-cd490c08583b
AppointmentTimeActivity.java
public class AppointmentTimeActivity extends AppCompatActivity {
SharedPrefManager sharedPrefManager;
Button appointmentTimeButton;
private TextView doctorFullName;
ConstraintLayout constraintLayout;
public static List<List<String>> availableSlots;
RecyclerView rvGroup;
public static ArrayList<String> arrayListGroup;
LinearLayoutManager layoutManagerGroup;
GroupAdapter groupAdapter;
private DoctorScheduleResponse timings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_appointment_time);
getSupportActionBar().setTitle("Appointment time");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
sharedPrefManager = new SharedPrefManager(this);
constraintLayout = findViewById(R.id.constraintLayout);
appointmentTimeButton = findViewById(R.id.book_video_call_appointment_btn);
doctorFullName = findViewById(R.id.doctor_full_name);
rvGroup = findViewById(R.id.rv_group);
String docName = getIntent().getStringExtra("doctorFullName");
doctorFullName.setText(docName);
arrayListGroup = new ArrayList<>();
fetchAndShowAppointmentsTime();
}
private void fetchAndShowAppointmentsTime() {
String id = String.valueOf(SpecialityActivity.doctorID);
Call<DoctorScheduleResponse> call = RetrofitClient.getInstance().getMyInterface().getAppointmentTime("Bearer " + sharedPrefManager.getAccessToken(), id);
call.enqueue(new Callback<DoctorScheduleResponse>() {
#Override
public void onResponse(#NotNull Call<DoctorScheduleResponse> call, #NotNull Response<DoctorScheduleResponse> response) {
arrayListGroup = new ArrayList<>();
if (response.isSuccessful()) {
assert response.body() != null;
for (List<Slot> slots : response.body().getSlot()) {
for (Slot slot : slots) {
arrayListGroup.add(slot.getScheduleDate());
}
}
groupAdapter = new GroupAdapter(AppointmentTimeActivity.this, response.body().getSlot());
layoutManagerGroup = new LinearLayoutManager(getApplicationContext());
rvGroup.setLayoutManager(layoutManagerGroup);
rvGroup.setAdapter(groupAdapter);
}
}
#Override
public void onFailure(#NotNull Call<DoctorScheduleResponse> call, #NotNull Throwable t) {
Toast.makeText(getBaseContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
DoctorScheduleResponse.java
public class DoctorScheduleResponse {
#SerializedName("slot")
#Expose
private List<List<Slot>> slot = null;
public List<List<Slot>> getSlot() {
return slot;
}
public void setSlot(List<List<Slot>> slot) {
this.slot = slot;
}
}
GroupAdater.java
public class GroupAdapter extends RecyclerView.Adapter<GroupAdapter.ViewHolder> {
private Activity activity;
ArrayList<String> arrayListGroup, arrayListMember;
LinearLayoutManager linearLayoutManager;
SharedPrefManager sharedPrefManager;
List<List<Slot>> slotsList;
public GroupAdapter(Activity activity, ArrayList<String> arrayListGroup) {
this.activity = activity;
this.arrayListGroup = arrayListGroup;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_slot_layout, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.dummyTV.setText(arrayListGroup.get(position));
arrayListMember = new ArrayList<>();
sharedPrefManager = new SharedPrefManager(activity);
for (int i = 0; i < 5; i++) {
arrayListMember.add(String.valueOf(i));
}
CustomAdapter customAdapter = new CustomAdapter(arrayListMember);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(activity);
holder.rvMember.setLayoutManager(linearLayoutManager);
holder.rvMember.setAdapter(customAdapter);
}
#Override
public int getItemCount() {
return arrayListGroup.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView dummyTV;
RecyclerView rvMember;
public ViewHolder(#NonNull View itemView) {
super(itemView);
dummyTV = itemView.findViewById(R.id.dummyTextView);
rvMember = itemView.findViewById(R.id.rv_member);
}
}
}
CustomAdapter.java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.SlotsViewHolder> {
ArrayList<String> slots;
public CustomAdapter(ArrayList<String> slots) {
this.slots = slots;
}
#NonNull
#Override
public SlotsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.available_slots_list, parent, false);
return new CustomAdapter.SlotsViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SlotsViewHolder holder, int position) {
holder.tvSlots.setText(slots.get(position));
}
#Override
public int getItemCount() {
return slots.size();
}
public class SlotsViewHolder extends RecyclerView.ViewHolder {
TextView tvSlots;
public SlotsViewHolder(#NonNull View itemView) {
super(itemView);
tvSlots = itemView.findViewById(R.id.tv_slots);
}
}
}
Nested recycler view will be more complex in terms of memory. So you can achieve same UI with different approach.
You should try with single recycler view with dynamic layout binding.
Example: For single item of recycler view, there will be a header(for date) and a viewgroup(may be linear layout) then bind any no. of child views inside that linear layout.
The problem is in GroupAdater.java. Inside onBindViewHolder method you are adding the value of loop variable to your list that you pass to your nested recycler view adaptor.
for (int i = 0; i < 5; i++) {
arrayListMember.add(String.valueOf(i));
}
You have to add the correct date from arrayListGroup object.
I'm developping an app in which my main activity hosts different fragments via a SectionsPageAdapter. My question is about one of those fragments that roughtly looks like the image bellow:
My innerRecyclers lists differents items that I want to be able to remove by swiping and make the user validate the deletion via a DialogFragment. I was able to implement the swipe action but what I'm struggly to do is to implement a listener in the OuterRecycler for OnItemTouch so I can use an interface and send the action back to my fragment which will dispay my DialoFragment afterwards.
The code of my OuterRecycler currently looks like that:
public class OuterRecyclerAdapter extends RecyclerView.Adapter<OuterRecyclerAdapter.InsideRecyclerHolder> {
private final Context mContext;
private final String mText;
private final ArrayList<MainViewArrayListMasterList> mDataArrayList;
OuterRecyclerAdapter(Context context, ArrayList<MainViewArrayListMasterList> DataArrayList, String text) {
mContext = context;
mDataArrayList = RecyclerArrayListType;
mText = text;
}
#NonNull
#Override
public OuterRecyclerAdapter.InsideRecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater myInflater = LayoutInflater.from(mContext);
View myOwnView = myInflater.inflate(R.layout.outer_recycler, parent, false);
return new OuterRecyclerAdapter.InsideRecyclerHolder(myOwnView);
}
#Override
public void onBindViewHolder(#NonNull OuterRecyclerAdapter.InsideRecyclerHolder holder, int position) {
MainViewArrayListMasterList currentItem = mDataArrayList.get(position);
holder.CardTitle.setText(String.valueOf(currentItem.getmYear()));
LinearLayoutManager mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
holder.CardRecycler.setLayoutManager(mLayoutManager);
InnerRecyclerAdapter historyInnerView_Adapter = new InnerRecyclerAdapter(mContext, currentItem.getmArrayListStored(), mText);
new ItemTouchHelper(ListHistoryViewSwiped).attachToRecyclerView(holder.CardRecycler);
holder.CardRecycler.setAdapter(historyInnerView_Adapter);
}
#Override
public int getItemCount() {
return mDataArrayList.size();
}
static class InsideRecyclerHolder extends RecyclerView.ViewHolder {
final TextView CardTitle;
final RecyclerView CardRecycler;
InsideRecyclerHolder(#NonNull View itemView) {
super(itemView);
CardTitle = itemView.findViewById(R.id.TitleText);
CardRecycler = itemView.findViewById(R.id.Inside_Recycler);
}
}
ItemTouchHelper.SimpleCallback ListHistoryViewSwiped = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
};
}
Is OnItemTouchListener the good way to acheive this ? Or do I have to create a new callback method ?
I actually circumvented this issue by calling the DialogFragment from my OuterRecycler:
public class OuterRecyclerAdapter extends RecyclerView.Adapter<OuterRecyclerAdapter.InsideRecyclerHolder> {
private final Context mContext;
private final String mText;
private final ArrayList<MainViewArrayListMasterList> mDataArrayList;
private FragmentManager mFragmentManager;
OuterRecyclerAdapter(Context context, FragmentManager FragmentManager, ArrayList<MainViewArrayListMasterList> DataArrayList, String text) {
mContext = context;
mFragmentManager = FragmentManager;
mDataArrayList = RecyclerArrayListType;
mText = text;
}
#NonNull
#Override
public OuterRecyclerAdapter.InsideRecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater myInflater = LayoutInflater.from(mContext);
View myOwnView = myInflater.inflate(R.layout.outer_recycler, parent, false);
return new OuterRecyclerAdapter.InsideRecyclerHolder(myOwnView);
}
#Override
public void onBindViewHolder(#NonNull OuterRecyclerAdapter.InsideRecyclerHolder holder, int position) {
MainViewArrayListMasterList currentItem = mDataArrayList.get(position);
holder.CardTitle.setText(String.valueOf(currentItem.getmYear()));
LinearLayoutManager mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
holder.CardRecycler.setLayoutManager(mLayoutManager);
InnerRecyclerAdapter historyInnerView_Adapter = new InnerRecyclerAdapter(mContext, currentItem.getmArrayListStored(), mText);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
openMyDialog(currentItem.getmArrayListStored().get(viewHolder.getAdapterPosition()));
}
}).attachToRecyclerView(holder.CardRecycler);
holder.CardRecycler.setAdapter(historyInnerView_Adapter);
}
#Override
public int getItemCount() {
return mDataArrayList.size();
}
static class InsideRecyclerHolder extends RecyclerView.ViewHolder {
final TextView CardTitle;
final RecyclerView CardRecycler;
InsideRecyclerHolder(#NonNull View itemView) {
super(itemView);
CardTitle = itemView.findViewById(R.id.TitleText);
CardRecycler = itemView.findViewById(R.id.Inside_Recycler);
}
}
private void openMyDialog(MainViewArrayListRecycler itemToDelete) {
MyDialog myDialog = MyDialog.newInstance(itemToDelete);
myDialog.show(mFragmentManager, "MyDialogDialog");
}
}
I'm using Retrofit, picasso and recyclerview.But the below error is coming.
Process: com.example.user.recyclerview, PID: 4871
java.lang.StackOverflowError
MainActivity.class
public class MainActivity extends AppCompatActivity
{
private RecyclerView recyclerView;
private DataAdapter dataAdapter;
private List<ModelData> modelDataList;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.card_recycle_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
getPopularMovies();
}
private void getPopularMovies()
{
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://pratikbutani.x10.mx")
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitInterface service = retrofit.create(RetrofitInterface.class);
Call<ModelDataList> call =service.getJSON();
call.enqueue(new Callback<ModelDataList>()
{
#Override
public void onResponse(Call<ModelDataList> call, Response<ModelDataList> response)
{
ModelDataList modelDataList = response.body();
dataAdapter = new DataAdapter(modelDataList.getResults());
recyclerView.setAdapter(dataAdapter);
}
#Override
public void onFailure(Call<ModelDataList> call, Throwable t)
{
Log.d("Main","failure");
}
});
}
}
ModelDataList.java
public class ModelDataList
{
private List<ModelData> results;
public List<ModelData> getResults()
{
return results;
}
}
DataAdapter.java
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder>
{
private List<ModelData> modelDataList;
private LayoutInflater layoutInflater;
private Context context;
public DataAdapter(List<ModelData> modelDataList)
{
this.context = new AppCompatActivity();
this.modelDataList = modelDataList;
this.layoutInflater = LayoutInflater.from(context);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = layoutInflater.inflate(R.layout.card_view, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position)
{
ModelData modelData = modelDataList.get(position);
holder.textView.setText(modelData.getName());
Picasso.with(context).load(String.valueOf(modelData.getDisplay_pic())).placeholder(R.color.colorAccent).into(holder.imgview);
}
#Override
public int getItemCount()
{
return modelDataList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder
{
private ImageView imgview;
private TextView textView;
public ViewHolder(View itemView)
{
super(itemView);
imgview = (ImageView) itemView.findViewById(R.id.tv_image);
textView = (TextView) itemView.findViewById(R.id.tv_name);
}
}
}
Not sure about your StackOverflowError issue. One issue is how you get...context. You can get context from view instead of "this.context = new AppCompatActivity();"
ex:
LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view, parent, false);
Picasso.with(holder.imgview.getContext()).load(String.valueOf(modelData.getDisplay_pic())).placeholder(R.color.colorAccent).into(holder.imgview);
I have this strage error. I'm downloading data from API and I want to print it in RecyclerView nested in Fragment called ListFragment. This fragment is one of three which I use in ViewPager. ViewPager works fine. For now, I want to display only two textViews. Layout for them has name single_data_layout. List<Feature> features is my DataResponse. Project builds normaly without issues and I receive in Log that "Data is successfully downloaded". When I run app in DebugMode I get message that my RecyclerView isn't attached to adapter. Any ideas?
ApiClient:
public interface ApiClient {
#GET("/query?format=geojson&starttime&minsig=700")
Call<DataResponse> getData();
}
ApiClientFactory:
public class ApiClientFactory {
public static final String baseURL = "https://earthquake.usgs.gov/fdsnws/event/1/";
public ApiClient createApiClient(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(ApiClient.class);
}
}
DataAdapter:
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.DataViewHolder> {
private List<Feature> features;
private ListFragment listFragment;
private Context context;
private LayoutInflater inflater;
public DataAdapter(List<Feature> features) {
this.features = features;
}
#Override
public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
inflater = LayoutInflater.from(context);
View contractView = inflater.inflate(R.layout.single_data_layout, parent, false);
return new DataViewHolder(contractView);
}
#Override
public void onBindViewHolder(DataViewHolder holder, int position) {
holder.place.setText(features.get(position).getProperties().getPlace());
holder.alert.setText(features.get(position).getProperties().getAlert());
}
#Override
public int getItemCount() {
return features.size();
}
public static class DataViewHolder extends RecyclerView.ViewHolder {
private final TextView place;
private final TextView alert;
public DataViewHolder(View view) {
super(view);
place = (TextView) view.findViewById(R.id.place_text_view);
alert = (TextView) view.findViewById(R.id.alert_text_view);
}
}
}
ListFragment:
public class ListFragment extends Fragment {
private RecyclerView recyclerView;
private static final String TAG = ListFragment.class.getSimpleName();
private ApiClient apiClient;
private List<Feature> features;
private RecyclerView.LayoutManager layoutManager;
private DataAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
getData();
return view;
}
private void getData() {
apiClient = new ApiClientFactory().createApiClient();
apiClient.getData().enqueue(new Callback<DataResponse>() {
#Override
public void onResponse(Call<DataResponse> call, Response<DataResponse> response) {
if (response.isSuccessful()) {
features = response.body().getFeatures();
adapter = new DataAdapter(features);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(layoutManager);
}
Log.d(TAG, "Data successfully downloaded");
}
#Override
public void onFailure(Call<DataResponse> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
}
}
You should change the way you inflate the layout. This should do the trick.
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.DataViewHolder> {
private List<Feature> features;
public DataAdapter(List<Feature> features) {
this.features = features;
}
#Override
public DataAdapter.DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_data_layout, parent, false);
return new DataViewHolder(view);
}
#Override
public void onBindViewHolder(DataViewHolder holder, int position) {
holder.place.setText(features.get(position).getProperties().getPlace());
holder.alert.setText(features.get(position).getProperties().getAlert());
}
#Override
public int getItemCount() {
return features.size();
}
public static class DataViewHolder extends RecyclerView.ViewHolder {
private final TextView place;
private final TextView alert;
public DataViewHolder(View view) {
super(view);
place = (TextView) view.findViewById(R.id.place_text_view);
alert = (TextView) view.findViewById(R.id.alert_text_view);
}
}
}
I see that the adapter class don't have a context , I guess if you add to the adapter constructor Context c as a second parameter your problem will be solved
try to replase
public DataAdapter(List<Feature> features) {
this.features = features;
}
by this
public DataAdapter(List<Feature> features, Context c) {
this.features = features;
this.context = c;
}
and replace this line in the fragment class
adapter = new DataAdapter(features);
by this
adapter = new DataAdapter(features,getActivity());
hope this will help you :)