I have used ViewPager inside fragment with 4 tabs. Each tab has a RecyclerView which shows an image and the title for the movie. When I switch back and forth to this fragment from another fragment, there is memory leaks at every switch. I could not figure out at which place exactly does this happen.
Fragment class which has the ViewPager:
public class FragmentMoviesTab extends Fragment {
String[] tabTitles = {"Tab 1", "Tab 2", "Tab 3", "Tab 4"};
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
View view;
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tab, container, false);
viewPager = (ViewPager) view.findViewById(R.id.viewPager);
viewPager.setPageTransformer(true, new AnimatePageTransformer());
FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getActivity().getSupportFragmentManager());
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) view.findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
return view;
}
class FragmentStatePagerAdapter extends android.support.v4.app.FragmentStatePagerAdapter {
public FragmentStatePagerAdapter(FragmentManager manager) { super(manager); }
#Override
public Fragment getItem(int position) { return new RecyclerMovies(); }
#Override
public int getCount() { return tabTitles.length; }
#Override
public CharSequence getPageTitle(int position) { return tabTitles[position]; }
#Override
public Parcelable saveState() { return null; }
}
}
RecyclerFragment for each tab:
public class RecyclerMovies extends android.support.v4.app.Fragment {
View view;
RecyclerView recyclerView;
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.recycler, container, false);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setNestedScrollingEnabled(true);
RecyclerMoviesAdapter adapter = new RecyclerMoviesAdapter();
recyclerView.setAdapter(adapter);
return view;
}
public class RecyclerMoviesAdapter extends RecyclerView.Adapter<RecyclerMoviesAdapter.MyViewHolder> {
int[] movieTrailers = {R.drawable.movie_1, R.drawable.movie_2, R.drawable.movie_3, R.drawable.movie_4};
String[] movieNames = {"Movie A", "Movie B", "Movie C", "Movie D"};
#Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
View itemLayoutView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.card_movie, viewGroup, false);
return new MyViewHolder(itemLayoutView);
}
#Override
public void onBindViewHolder(MyViewHolder viewHolder, int pos) {
final int position = viewHolder.getAdapterPosition();
viewHolder.movieName.setText(movieNames[position % 4]);
viewHolder.movieTrailer.setImageResource(movieTrailers[position % 4]);
}
#Override
public int getItemCount() {
return 10;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView movieName;
ImageView movieTrailer;
public MyViewHolder(View itemView) {
super(itemView);
movieName = (TextView) itemView.findViewById(R.id.movie_name);
movieTrailer = (ImageView) itemView.findViewById(R.id.movie_trailer);
}
}
}
}
Can someone point me to the correct direction where the memory leaks would be happening?
Memory leaks can be a pain to find, however there are tools out available that help you find and fix these leaks.
Take a look at LeakCanary, add this to your app and you'll get a notification whenever there is a memory leak. It also gives hints on what might be causing it.
Also, here's a link to a blog that shows some ways to avoid memory leaks in Android.
Related
I am building an Android Application which have Tab Layout in which there are Fragments and in Fragment I am displaying some value.
I have just only added hardcoded values to test the layout, but even these are not visible in the fragment.
Here is the code for ViewPagerAdapter:
public class FavouriteViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> favouriteFragmentList = new ArrayList<>(); // this line can cause crashes
private final List<String> favouriteFragmentListTitles = new ArrayList<>();
public FavouriteViewPagerAdapter(#NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
#NonNull
#Override
public Fragment getItem(int position) {
return favouriteFragmentList.get(position);
}
#Override
public int getCount() {
return favouriteFragmentListTitles.size();
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return favouriteFragmentListTitles.get(position);
}
public void AddFragment(Fragment fragment, String title) {
favouriteFragmentList.add(fragment); // this line can cause crashes
favouriteFragmentListTitles.add(title);
}
}
I have tried the answers available already none of them solves my problem.
I debugged the application and my RecyclerViewAdapter is not even called, very strange. I have done this many time but this never happened.
Here is my code for RecyclerViewAdapter :
public class ProductsRecyclerAdapter extends RecyclerView.Adapter<ProductsRecyclerAdapter.viewHolder> {
Context context;
private List<FavouriteProducts> favouriteProductsData;
public ProductsRecyclerAdapter(Context context, List<FavouriteProducts> favouriteProductsData) {
this.context = context;
this.favouriteProductsData = favouriteProductsData;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.single_favourite_product_item, parent, false);
viewHolder vHolder = new viewHolder(v);
return vHolder;
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
holder.product_name.setText(favouriteProductsData.get(position).getProduct_name());
holder.product_price.setText(favouriteProductsData.get(position).getProduct_price());
holder.product_image.setImageResource(favouriteProductsData.get(position).getProduct_image());
Toast.makeText(context,favouriteProductsData.get(position).getProduct_price() , Toast.LENGTH_SHORT).show();
/*holder.heart_button.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
showSuccessToast(context,"Liked");
}
#Override
public void unLiked(LikeButton likeButton) {
showSuccessToast(context,"Unliked");
}
});*/
}
#Override
public int getItemCount() {
return favouriteProductsData.size();
}
static class viewHolder extends RecyclerView.ViewHolder {
MaterialTextView product_name, product_price;
ImageView product_image;
LikeButton heart_button;
public viewHolder(#NonNull View itemView) {
super(itemView);
product_name = itemView.findViewById(R.id.product_name);
product_price = itemView.findViewById(R.id.product_price);
product_image = itemView.findViewById(R.id.product_image);
heart_button = itemView.findViewById(R.id.heart_button);
}
}
}
I am not getting any errors but after I check adapter is not even called. Some help will be really helpful.
Fragment Code:
public class FavouriteProductsFragment extends Fragment {
View v;
private List<FavouriteProducts> productList;
public FavouriteProductsFragment() {
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
productList = new ArrayList<>();
productList.add(new FavouriteProducts("All Weather", "200/Ltr", R.drawable.all_weather));
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.products_favourite_fragment, container, false);
RecyclerView productRecyclerView = v.findViewById(R.id.favourite_products_rv);
ProductsRecyclerAdapter recyclerAdapter = new ProductsRecyclerAdapter(getContext(), productList);
productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
productRecyclerView.hasFixedSize();
productRecyclerView.setAdapter(recyclerAdapter);
return v;
}
}
productList = new ArrayList<>();
productList.add(new FavouriteProducts("All Weather", "200/Ltr",R.drawable.all_weather));
recyclerAdapter.notifyDataSetChanged()
RecyclerView productRecyclerView = v.findViewById(R.id.favourite_products_rv);
ProductsRecyclerAdapter recyclerAdapter = new ProductsRecyclerAdapter(getContext(), productList);
productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
productRecyclerView.hasFixedSize();
productRecyclerView.setAdapter(recyclerAdapter);
You need to add
RecyclerView productRecyclerView = v.findViewById(R.id.favourite_products_rv);
ProductsRecyclerAdapter recyclerAdapter = new ProductsRecyclerAdapter(getContext(), productList);
productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
productRecyclerView.hasFixedSize();
productRecyclerView.setAdapter(recyclerAdapter);
productList = new ArrayList<>();
productList.add(new FavouriteProducts("All Weather", "200/Ltr",R.drawable.all_weather));recyclerAdapter.notifyDataSetChanged()
and Remove oncreate() method
try productRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); befor setting adapter in recyclerview.
Step1: First Create one or MoreFragment For Your ViewPager and in This Fragment Add your Recyclerview Code as per Your Requirement.
Like Below Code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_whatsapp_image, container, false);
context = getActivity();
((HomeActivity) getActivity()).toolbar.setVisibility(View.VISIBLE);
setupView(root);
return root;
}
private void setupView(ViewGroup root) {
recyclerView = (RecyclerView) root.findViewById(R.id.recyclerViewImage);
progressBar=root.findViewById(R.id.simpleProgressBar);
txtinfo=root.findViewById(R.id.txtinfo);
setUPList();
}
Step2: Then Create ViewPager Adapter for Your TabLayout
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
if(position == 0) return new AudioFragment();
if(position == 1) return new VideoFragment();
if(position == 2) return new ImageFragment();
throw new IllegalStateException("Unexpected position " + position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
if(position == 0) return "Audio";
if(position == 1) return "Video";
if(position == 2) return "Image";
throw new IllegalStateException("Unexpected position " + position);
}
}
Step3 : Then Call Your SetupViewpager Method in Your Oncreate method of your Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=findViewById(R.id.toolbar);
viewPager=findViewById(R.id.viewpager);
tabLayout=findViewById(R.id.tabs);
//add toolbar
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
setTabIcons();
}
NOTE: You Can Download ViewPager Code from Below Link.Click Here to View and Download
I am having trouble inflating a recycler view inside a viewPager.
The below code is of my MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.pager);
tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);//setting tab over viewpager
viewPager.setAdapter(new VeiwPagerAdapter());
}
And the following is my ViewPagerAdapter:
public class VeiwPagerAdapter extends PagerAdapter {
private RecyclerView recyclerView;
private List<Pojo> pojoList = new ArrayList<>();
#Override
public int getCount() {
return 2;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return false;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
if (position == 0) {
LayoutInflater inflater = LayoutInflater.from(container.getContext());
View view = inflater.inflate(R.layout.recycler_view_holder, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(container.getContext()));
pojoList.add(new Pojo("Random field 1", "Random field 1"));
recyclerView.setAdapter(new RecycAdapter(pojoList));
container.addView(view);
return view;
} else {
LayoutInflater inflater = LayoutInflater.from(container.getContext());
View view = inflater.inflate(R.layout.recycler_view_holder, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(container.getContext()));
pojoList.add(new Pojo("Random field 1", "Random field 1"));
recyclerView.setAdapter(new RecycAdapter(pojoList));
container.addView(view);
return view;
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return position == 0 ? "TAB 1" : "TAB 2";
}
RecycAdapter code:
public class RecycAdapter extends RecyclerView.Adapter<RecycViewHolder> {
private List<Pojo> pojoArrayList;
public RecycAdapter(List<Pojo> pojoArrayList) {
this.pojoArrayList = pojoArrayList;
}
#NonNull
#Override
public RecycViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.item_layout, parent, false);
return new RecycViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull RecycViewHolder holder, int position) {
Pojo pojo = pojoArrayList.get(position);
holder.textView1.setText(pojo.getText1());
holder.textView2.setText(pojo.getText2());
}
#Override
public int getItemCount() {
return pojoArrayList.size();
}
}
ViewHolder code added as well.Not sure if there is something wrong with the viewHolder implementation.
public class RecycViewHolder extends RecyclerView.ViewHolder {
public TextView textView1, textView2;
public RecycViewHolder(View itemView) {
super(itemView);
this.textView1 = itemView.findViewById(R.id.textvie1);
this.textView2 = itemView.findViewById(R.id.textvie2);
}
}
The output has nothing under each tab.
Can someone please help me as to where i went wrong
Why do you have the block of code on your MainActivity?
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
pojoList.add(new Pojo("Random field 1", "Random field 1"));
recyclerView.setAdapter(new RecycAdapter(pojoList));
}
I can see some conflicts with the same R.id.recyclerView.
If you want a ViewPager to display two different RecyclerViews on each tab, then your MainActivity should only really have the containers for your views. Can you please give some more context on what you need to achieve?
Have you tried to show a simple and different TextView/Layout on each tab? You might have some XML issues.
You need to inflate the RecyclerView into each page of the ViewPager, in other words put this code in the "instantiateItem" method:
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
pojoList.add(new Pojo("Random field 1", "Random field 1"));
recyclerView.setAdapter(new RecycAdapter(pojoList));
Finally,found a solution,the overriden method isViewFromObject was earlier returning false which was causing the issue upon changing to the code as below everything worked fine.
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
My app has a fragment that host a nested viewPager (One fragment added every time) all views are linked to the same layout.
Each fragment has a fixed button + recylerview that retrieve its data from firebase adapter.
When I click on the button, it show the correct viewPager position. But if I click on the listview item (viewHolder) it show the next pre-loaded position in the viewPager.
here's the viewpager and the pager adapter of the root fragment
Explore.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_explore, container, false);
array = controller.SELECTED_CATEGORIES;
viewPager = (ViewPager) root.findViewById(R.id.viewPager);
tabLayout = (TabLayout) root.findViewById(R.id.categories_tablayout);
tabLayout.setupWithViewPager(viewPager);
mAdapter = new MyAdapter(getFragmentManager());
viewPager.setAdapter(mAdapter);
return root;
}
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return controller.SELECTED_CATEGORIES.length;
}
#Override
public Fragment getItem(int position) {
return CategoriesFragment.newInstance(position);
}
#Override
public CharSequence getPageTitle(final int position) {
return controller.SELECTED_CATEGORIES[position];
}
}
CategoriesFragment.java
static CategoriesFragment newInstance(int num) {
CategoriesFragment f = new CategoriesFragment();
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_categories, container, false);
initialize();
listCategoriesFeed = (RecyclerView) rootView.findViewById(R.id.listCategoriesFeeds);
categoriesFeedAdapter = new CategoriesFeedAdapter(CategoriesFeedItem.class, R.layout.categoriesfeed_list_item, CategoriesFeedHolder.class, myref);
llm = new LinearLayoutManager(rootView.getContext());
llm.setOrientation(LinearLayoutManager.VERTICAL);
listCategoriesFeed.setLayoutManager(llm);
listCategoriesFeed.setAdapter(categoriesFeedAdapter);
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
//Holder itemClickListener
CategoriesFeedHolder.registerOnItemClickListener(this);
//TextView onclick listener
View tv = rootView.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("position",mNum + "");
}
});
return rootView;
}
#Override
public void onItemClick(View view, int position) {
super.onItemClick(view, position);
switch (view.getId()) {
case R.id.firstId:
Log.e("position",mNum+ "");
break;
case R.id.secondId:
secondAction....
.....
.....
.....
break;
}
}
private void initialize() {
controller.showProgressDialog();
list = controller.getIniCategoriesDetailsList();
list.clear();
controller.categoriesDetailsList.put(controller.SELECTED_CATEGORIES[mNum],list);
reference = FirebaseDatabase.getInstance().getReference("firebase-path/" + controller.SELECTED_CATEGORIES[mNum]);
myref = reference.orderByChild("order-by").limitToFirst(i);
myref.addChildEventListener(this);
}
CategoriesFeedHolder.java
private CategoriesFeedItem model;
private final ImageView mImage;
private static OnItemClickListener onItemClickListener;
public CategoriesFeedHolder(View itemView) {
super(itemView);
this.context = itemView.getContext();
mImage = (ImageView) itemView.findViewById(R.id.m_image);
mImage.setOnClickListener(this);
}
public static void registerOnItemClickListener(OnItemClickListener onItemClickListener) {
CategoriesFeedHolder.onItemClickListener = onItemClickListener;
}
public void setModel(CategoriesFeedItem model) {
this.model = model;
}
#Override
public void onClick(View view) {
onItemClickListener.onItemClick(view, getAdapterPosition());
}
Does anyone know why this happens?
The problem was with the viewholder class, there was no data binding inside it. So when i clicked on any item inside the viewholder, it performed the action on the current adapter's data (preloaded data).
the viewholder class should be something like this:
public ViewHolder(View itemView) {
super(itemView);
share = (ImageView) itemView.findViewById(R.id.share);
}
public void bindToPost(Post post, View.OnClickListener onClickListener) {
share.setOnClickListener(onClickListener);
}
I am new at android programming and I getting the error "No adapter attached; skipping layout". My app runs but when I click to open my fragment wich have an cardview inside, only displays the first content of my ArrayList.
I have been following this tutorial: https://code.tutsplus.com/tutorials/getting-started-with-recyclerview-and-cardview-on-android--cms-23465, but I am doing in a different way. I am using fragments instead of activity, but I think that is not a problem. So, here I have my Activity:
public class Av_ninja extends AppCompatActivity {
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_av_ninja);
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new CustomAdapter(getSupportFragmentManager(), getApplicationContext()));
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private class CustomAdapter extends FragmentPagerAdapter{
private String fragmentes [] = {"Info","Abilitities"};
public CustomAdapter(FragmentManager suppFragmentManager, Context applicaContext){
super(suppFragmentManager);
}
#Override
public Fragment getItem(int position){
switch (position){
case 0:
return new Fragment1();
case 1:
return new Fragment2();
default:
return null;
}
}
#Override
public int getCount(){
return fragmentes.length;
}
#Override
public CharSequence getPageTitle(int position) {
return fragmentes[position];
}
}
}
Fragment
public class Fragment1 extends Fragment {
ImageView Icons;
TextView Titulos;
TextView Textos;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
// return inflater.inflate(R.layout.frag1,container,false);
View rootView = inflater.inflate(R.layout.card_ninja_info,container,false);
Icons = (ImageView) rootView.findViewById(R.id.Icons);
Titulos = (TextView) rootView.findViewById(R.id.Titulos);
Textos = (TextView) rootView.findViewById(R.id.Textos);
Icons.setImageResource(R.drawable.offenseicon);
Titulos.setText("Role");
Textos.setText("Scout");
return rootView;
}
}
RecyclerView
public class RecyclerViewAv extends Fragment{
private List<Heroi> herois;
private RecyclerView rv;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
//return inflater.inflate(R.layout.frag2,container,false);
View rootView = inflater.inflate(R.layout.card_ninja_info,container,false);
rv = (RecyclerView)rootView.findViewById(R.id.rv_frag1);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
rv.setHasFixedSize(true);
initializeData();
initializeAdapter();
return rootView;
}
private void initializeData(){
herois = new ArrayList<>();
herois.add(new Heroi(R.drawable.offenseicon, "Role", "Scout"));
herois.add(new Heroi(R.drawable.identityicon, "Identity", "Genji Shimada"));
herois.add(new Heroi(R.drawable.workicon, "Work", "Adventurer"));
herois.add(new Heroi(R.drawable.localizationicon, "Base of Operation", "Nepal"));
herois.add(new Heroi(R.drawable.empresaicon, "Affiliation", "Shiamda Clan"));
herois.add(new Heroi(R.drawable.ageicon, "Age", "27"));
herois.add(new Heroi(R.drawable.healthicon, "Health", "100"));
}
private void initializeAdapter(){
RVAdapter adapter = new RVAdapter(herois);
rv.setAdapter(adapter);
}
}
Adapter
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.HeroiViewHolder>{
public static class HeroiViewHolder extends RecyclerView.ViewHolder{
CardView cv;
ImageView Icons;
TextView Titulos;
TextView Textos;
public HeroiViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
Icons = (ImageView)itemView.findViewById(R.id.Icons);
Titulos = (TextView)itemView.findViewById(R.id.Titulos);
Textos = (TextView)itemView.findViewById(R.id.Textos);
}
}
List<Heroi> herois;
RVAdapter(List<Heroi> herois){
this.herois=herois;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView){
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public RVAdapter.HeroiViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
HeroiViewHolder hvh = new HeroiViewHolder(v);
return hvh;
}
#Override
public void onBindViewHolder(HeroiViewHolder holder, int position) {
holder.Icons.setImageResource(herois.get(position).photoId);
holder.Titulos.setText(herois.get(position).tit);
holder.Textos.setText(herois.get(position).res);
}
#Override
public int getItemCount() {
return herois.size();
}
}
class Heroe
public class Heroi {
int photoId;
String tit;
String res;
public Heroi(int photoId, String tit, String res) {
this.photoId = photoId;
this.tit = tit;
this.res = res;
}
}
Thanks in advance!
Here you could do following changes to make it properly :
1) Update your onCreateView method
private RVAdapter rvAdapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
//return inflater.inflate(R.layout.frag2,container,false);
View rootView = inflater.inflate(R.layout.card_ninja_info,container,false);
rv = (RecyclerView)rootView.findViewById(R.id.rv_frag1);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
// Added here
llm.setOrientation(LinearLayoutManager.VERTICAL);
rv.setHasFixedSize(true); // Here we changed order you should call it first before setting LayoutManager
rv.setLayoutManager(llm);
//Set empty adapter and pass only context if you will needed inside it
rvAdapter = new RVAdapter(getActivity());
rv.setAdapter(rvAdapter);
initializeData();
initializeAdapter();
return rootView;
}
2) Create method in your adapter class to update your content list
public void updateList(List<Heroi> herois){
this.herois = herois;
notifyDataSetChanged();
}
3) Only update your contentList inside initializeAdapter method(No need to set adapter again)
private void initializeAdapter(){
rvAdapter.updateList(herois);
}
That's it!
Update your adapter as per below :
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.HeroiViewHolder>{
List<Heroi> herois;
public static class HeroiViewHolder extends RecyclerView.ViewHolder{
CardView cv;
ImageView Icons;
TextView Titulos;
TextView Textos;
Context context;
public HeroiViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
Icons = (ImageView)itemView.findViewById(R.id.Icons);
Titulos = (TextView)itemView.findViewById(R.id.Titulos);
Textos = (TextView)itemView.findViewById(R.id.Textos);
}
}
RVAdapter(Context context){
this.context = context;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView){
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public RVAdapter.HeroiViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
HeroiViewHolder hvh = new HeroiViewHolder(v);
return hvh;
}
#Override
public void onBindViewHolder(HeroiViewHolder holder, int position) {
holder.Icons.setImageResource(herois.get(position).photoId);
holder.Titulos.setText(herois.get(position).tit);
holder.Textos.setText(herois.get(position).res);
}
#Override
public int getItemCount() {
return herois.size();
}
public void updateList(List<Heroi> herois){
this.herois = herois;
notifyDataSetChanged();
}
}
Problem Solved I just deleted RecyclerView Class and putted it into Fragment1 class.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
// return inflater.inflate(R.layout.frag1,container,false);
View rootView = inflater.inflate(R.layout.frag1,container,false);
rv = (RecyclerView)rootView.findViewById(R.id.rv_frag1);
LinearLayoutManager llm = new LinearLayoutManager(getContext());
// llm.setOrientation(LinearLayoutManager.VERTICAL);
// rv.setHasFixedSize(true);
rv.setLayoutManager(llm);
initializeData();
rvAdapter = new RVAdapter(herois);
rv.setAdapter(rvAdapter);
return rootView;
}
Thanks Anyway
I am using FragmentStatePagerAdapter to load fragment with viewpager with tab layout. I am passing different id's to load same fragment with different data in getItem() but it is always returning fragment with same data on first time and when I swipe through next screens and came back to first screen then it will showing correct data.
Any solution or info is very helpful.
I am calling adapter like this in my onCreate() and it always return same data for position 0 and 1.
MyPagerAdapter adapter = new MyPagerAdapter (getSupportFragmentManager(),bundle);
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
My Adapter
static class MyPagerAdapter extends FragmentStatePagerAdapter {
private Bundle b;
public MyPagerAdapter (FragmentManager fm,Bundle b) {
super(fm);
this.b=b;
}
#Override
public Fragment getItem(int position) {
ContentListFragment fragment = new ContentListFragment();
b.putString("id", tabList.get(position).get("id"));
fragment.setArguments(b);
return fragment;
}
#Override
public int getCount() {
return tabList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return tabList.get(position).get("title");
}
}
Edit
ContentListFragment.java
public class ContentListFragment extends Fragment{
private static final String TAG="ContentListFragment";
private String id,type;
private TextView norecord;
private View rootView;
private List<AppReading> appReadingList;
private RecyclerView recyclerView;
private ContentRecyclerAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.d(TAG, "onCreateView");
rootView = inflater.inflate(R.layout.content_list, container,false);
initView();
initData();
return rootView;
}
private void initView() {
// TODO Auto-generated method stub
norecord=(TextView)rootView.findViewById(R.id.norecord);
recyclerView=(RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
private void initData() {
id=getArguments().getString("id");
getContentList(category);
}
// Get records by category
private void getContentList(String id){
Log.d(TAG, "getContentList: "+id);
Dao dao=new Dao(getActivity());
dao.open();
appReadingList=dao.getContentList(id);
dao.close();
//Set adapter if data available
if(appReadingList.size()>0){
adapter=new ContentRecyclerAdapter();
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(),R.drawable.divider));
recyclerView.setItemAnimator(new FadeInLeftAnimator());
recyclerView.setAdapter(new SlideInLeftAnimationAdapter(adapter));
}else{
norecord.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
}
}
private class ContentRecyclerAdapter extends RecyclerView.Adapter<ContentRecyclerAdapter.ViewHolder>{
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem, parent, false);
ViewHolder holder = new ViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(ViewHolder holder,final int position) {
holder.itemContent.setText(appReadingList.get(position).getTitle());
holder.itemDate.setText(appReadingList.get(position).getAddDate());
}
#Override
public int getItemCount() {
return appReadingList.size();
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView itemContent, itemDate ;
RelativeLayout listItem;
ViewHolder(View itemView){
super(itemView);
itemContent = (TextView) itemView.findViewById(R.id.itemcontent);
itemDate = (TextView) itemView.findViewById(R.id.itemdate);
listItem=(RelativeLayout) itemView.findViewById(R.id.rlListItem);
}
}
}