Recyclerview in fragment inside a viewpager - java

I wanted to use recyclerview inside a fragment of my 3 fragment viewpager. I wrote the code and it ran perfectly but I don't know why it is too slow.When I swap from one fragment to another it almost takes half minute.Don't know what mistakes I did here.
Main Activity
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar)findViewById(R.id.toolBar);
tabLayout = (TabLayout)findViewById(R.id.tabs);
viewPager = (ViewPager)findViewById(R.id.viewPager);
setSupportActionBar(toolbar);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addFragment(new OneFragment(), "One");
viewPagerAdapter.addFragment(new TwoFragment(), "Two");
viewPagerAdapter.addFragment(new ThreeFragment(), "Three");
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
}
Here it is one of my fragment where I tried to implement recyclerview.
Fragment
public class TwoFragment extends Fragment {
public TwoFragment() {
// 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_two, container, false);
OurData ourData = new OurData();
ourData.pic.add(R.drawable.b);
ourData.title.add("Hello");
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.listRecyclerView);
ListAdapter listAdapter = new ListAdapter();
recyclerView.setAdapter((listAdapter));
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
return view;
}
}
public class ListAdapter extends RecyclerView.Adapter {
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ListViewHolder) holder).bindView(position);
}
#Override
public int getItemCount() {
return OurData.title.size();
}
private class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView text;
private ImageView image;
public ListViewHolder(View itemview) {
super(itemview);
text = (TextView) itemview.findViewById(R.id.textF);
image = (ImageView) itemview.findViewById(R.id.imageF);
itemview.setOnClickListener(this);
}
public void bindView(int position) {
text.setText(OurData.title.get(position));
image.setImageResource(OurData.pic.get(position));
}
public void onClick(View view) {
}
}
}
public class OurData {
public static ArrayList<String> title = new ArrayList<String>();
public static ArrayList<Integer> pic = new ArrayList<Integer>();
}
It tooks my whole day thinking what I did wrong. Please help me out!

set your adapter recyclerView.setAdapter((listAdapter));
insise onViewCreated instead of onCreateView

I think the problem is because of one of your Methods.
maybe 'OurData'
and also are you sure of this:
#Override
public int getItemCount() {
return OurData.title.size();
}
also try using Log in each code and see the part that takes time especially 'OurData'

Related

TabLayoutMediator with ViewPager2 is synchronizing wrong on tab selection -Android java

ViewPager2 is scrolling to the wrong page when I am selecting a tab from a far position. Swiping and selecting tab of loaded pages working fine. The error is only happening when the page is not loaded and scrolling animation is active. I have created a large viewpager2 with 100 pages containing Recyclerview.
My Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabLayout tabLayout = findViewById(R.id.tabLayout);
ViewPager2 viewPager = findViewById(R.id.viewPager2);
viewPager.setAdapter(new viewPagerAdapter(this));
new TabLayoutMediator(tabLayout, viewPager, true, true,
((tab, position) -> tab.setText("Page: " + position))).attach();
}
private class viewPagerAdapter extends FragmentStateAdapter {
public viewPagerAdapter(FragmentActivity fa) {
super(fa);
}
#Override
public Fragment createFragment(int position) {
Fragment fragment = new itemFragment();
Bundle args = new Bundle();
args.putInt(itemFragment.ARG_PARAM1, position);
fragment.setArguments(args);
return fragment;
}
#Override
public int getItemCount() {
return 100;
}
}
}
My Fragment
public class itemFragment extends Fragment {
public static final String ARG_PARAM1 = "parram1";
int pagePosition;
public itemFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pagePosition = getArguments().getInt(ARG_PARAM1);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frgment_item, container, false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView textView = view.findViewById(R.id.textView);
textView.setText("Page - " + pagePosition);
RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setAdapter(new myAdapter());
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 16));
}
private class myAdapter extends RecyclerView.Adapter<Myvh> {
#Override
public Myvh onCreateViewHolder(ViewGroup parent, int viewType) {
return new Myvh(new TextView(getContext()));
}
#Override
public void onBindViewHolder(Myvh holder, int position) {
int codepoint=pagePosition*700 + position;
char[] ch=Character.toChars(codepoint);
holder.textView.setText(String.valueOf(ch));
}
#Override
public int getItemCount() { return 700; }
}
private class Myvh extends RecyclerView.ViewHolder {
TextView textView;
public Myvh(View itemView) {
super(itemView);
textView = (TextView) itemView;
}
}
}
I have also tried Recyclerview adapter instead of FragmentStateAdapter and getting same problem.
I have found some solution but not sufficient.
Those are:
Using old ViewPager(deprecated)
Using viewPager.setOffscreenPageLimit(100); (taking huge time to load activity)
Disabling smoothscroll ( looks awful when swiping)

It doesn't load from Firebase on the Fragment Activity ('FragmentOne' is clear and it shouldn't be)

I made a Recycler View on a Fragment , wired it with the Firebase, but it won't show anything on the activity , doesn't load from Firebase.. I verified the code and the procedure a thousand times , I really don't know what to do , maybe its a problem in my code or connections..
Fragment class :
public class FragmentUnu extends Fragment {
View v;
FirebaseDatabase mDatabase;
DatabaseReference mRef;
RecyclerView mRecycler;
RecyclerView.LayoutManager layoutManager;
FirebaseRecyclerAdapter < FragmentUnuModel, FragmentUnuViewHolder > adapter;
public FragmentUnu() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
v = inflater.inflate(R.layout.unu_fragment, container, false);
mRecycler = (RecyclerView) v.findViewById(R.id.fragment_unu_recycler);
mRecycler.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
mRecycler.setLayoutManager(layoutManager);
mDatabase = FirebaseDatabase.getInstance();
mRef = mDatabase.getReference("FragmentId");
FirebaseRecyclerOptions < FragmentUnuModel > options = new FirebaseRecyclerOptions.Builder < FragmentUnuModel > ()
.setQuery(mRef, FragmentUnuModel.class)
.build();
adapter = new FirebaseRecyclerAdapter < FragmentUnuModel, FragmentUnuViewHolder > (options) {
#NonNull
#Override
public FragmentUnuViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.unu_fragment_item, parent, false);
return new FragmentUnuViewHolder(itemView);
}
#Override
protected void onBindViewHolder(#NonNull FragmentUnuViewHolder fragmentUnuViewHolder, int i, #NonNull FragmentUnuModel fragmentUnuModel) {
fragmentUnuViewHolder.denumire.setText(fragmentUnuModel.getDenumire());
fragmentUnuViewHolder.descriere.setText(fragmentUnuModel.getDescriere());
fragmentUnuViewHolder.pret.setText(fragmentUnuModel.getPret());
Picasso.with(getActivity().getBaseContext()).load(fragmentUnuModel.getImagine()).into(fragmentUnuViewHolder.img);
}
};
return v;
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
mRecycler.setAdapter(adapter);
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
This is my MainActivity class with the fragments :
public class Food extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private ViewPagerAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.food_activity);
tabLayout = (TabLayout) findViewById(R.id.tabs);
viewPager = (ViewPager) findViewById(R.id.viewpager);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.AddFragment(new FragmentUnu(), "Unu");
adapter.AddFragment(new FragmentDoi(), "Doi");
adapter.AddFragment(new FragmentTrei(), "Trei");
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
}
}
I don't have any erros in the debugger
You made the adapter but didn't assign it to RecyclerView. Call mRecycler.setAdapter():
...
mRecycler.setAdapter(adapter);
return v;
try calling this too in your onStart() or MainActivity:
adapter.notifyDataSetChanged();

ViewPager inside RecycleView Adapter

I tried to add Viewpager inside RecycleView item, then I created the adapter for the recycle view and I created a Pager Adapter that extends from FragmentStatePagerAdapter class inside the the adapter.
Just the first item of the recycle works fine, but the rest items of recycle view do not show the view pager.
When I Log inside the Pager Adapter I can see all the fragment position.
When I scroll horizontally inside any pager of any recycle view item I can see the Log statement, but nothing appear on the screen.
Could any one help me in that case ?
Here is my code
public class RentCategoryItemAdapter extends RecyclerView.Adapter<RentCategoryItemAdapter.ViewHolder> {
Context mContext;
ArrayList<RentCategoryItem> categoryItems;
ArrayList<MyPagerAdapter> pagerAdapters = new ArrayList<>();
/*ArrayList<ViewPager> pagerArrayList = new ArrayList<>();
ArrayList<MyPagerAdapter> myPagerAdapterArrayList = new ArrayList<>();*/
public RentCategoryItemAdapter(Context context, ArrayList<RentCategoryItem> categoryItems) {
mContext = context;
this.categoryItems = categoryItems;
AppCompatActivity activity = (AppCompatActivity) mContext;
for (int i = 0; i < categoryItems.size(); i++) {
pagerAdapters.add(new MyPagerAdapter(activity.getSupportFragmentManager(), categoryItems.get(i).catItems));
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView;
itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rent_category_item,parent, false);
RentCategoryItemAdapter.ViewHolder viewHolder = new RentCategoryItemAdapter.ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.catName.setText(categoryItems.get(position).catName);
//AppCompatActivity activity = (AppCompatActivity) mContext;
//holder.mPagerAdapter = new MyPagerAdapter(activity.getSupportFragmentManager(), categoryItems.get(position).catItems);
holder.pager.setAdapter(pagerAdapters.get(position));
Log.d("Tag", pagerAdapters.get(position).getCount() + " position " + position);
/*holder.mPagerAdapter = myPagerAdapterArrayList.get(position);
holder.pager.setAdapter(myPagerAdapterArrayList.get(position));*/
int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10*16, mContext.getResources().getDisplayMetrics());
holder.pager.setPageMargin(-margin);
}
#Override
public int getItemCount() {
return categoryItems.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private PagerAdapter mPagerAdapter;
TextView catName;
ViewPager pager;
public ViewHolder(View itemView) {
super(itemView);
pager = itemView.findViewById(R.id.pager);
catName = itemView.findViewById(R.id.cat_name);
/*pagerArrayList.add(new ViewPager(mContext));
AppCompatActivity activity = (AppCompatActivity) mContext;
myPagerAdapterArrayList.add(new MyPagerAdapter(activity.getSupportFragmentManager()));*/
}
}
private class MyPagerAdapter extends FragmentStatePagerAdapter {
ArrayList<RentItem> items;
public MyPagerAdapter(FragmentManager fm, ArrayList<RentItem> items) {
super(fm);
this.items = items;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new RentCategoryForPagerFragment();
Bundle bundle = new Bundle();
bundle.putString("first_last", "first");
bundle.putString("product_id", items.get(position).productId);
bundle.putString("product_name", items.get(position).productName);
bundle.putString("product_price", items.get(position).productPrice);
bundle.putString("product_image", items.get(position).productImage);
fragment.setArguments(bundle);
Log.d("Tag", "inside my pager adapter " + position);
return fragment;
}
#Override
public int getCount() {
return items.size();
}
}
}
And here is RentCategoryForPagerFragment class
public class RentCategoryForPagerFragment extends Fragment {
String firstOrLast = "";
ImageView productImage;
TextView productName, productPrice;
String productId;
Button showDetailsButton;
public RentCategoryForPagerFragment() {
//firstOrLast = getArguments().getString("first_last");
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.rent_item_in_category_layout, container, false);
productImage = rootView.findViewById(R.id.product_image);
productName = rootView.findViewById(R.id.product_name);
productPrice = rootView.findViewById(R.id.product_price);
showDetailsButton = rootView.findViewById(R.id.show_details_button);
Bundle bundle = getArguments();
String imageURL = bundle.getString("product_image");
Glide.with(getActivity()).load(imageURL).into(productImage);
productId = bundle.getString("product_id");
productName.setText(bundle.getString("product_name"));
productPrice.setText(bundle.getString("product_price"));
showDetailsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Clicked ", Toast.LENGTH_LONG).show();
}
});
return rootView;
}
}
The result I got in this
Finally I found the solution. I was using the wrong class because it sound that FragmentStatePagerAdapter and FragmentPagerAdapter Classes do not serve my idea.
So You should extend from PagerAdapter instead to implement more than one pager in the same screen. And you should override some methods to complete it.
I hope this answer helps someone in someday.

Data not shown in RecyclerView

I am trying to make a list of items with a Recycler View in a simple way by making a method called Data() that's has a for loop to set the text view continuously but when I run the app it show's me a white screen without anything.
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
RecyclerAdapter mAdapter ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView =(RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
private class RecyclerAdapter extends RecyclerView.Adapter<MyViewHolder{
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.list_item,parent,false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.Data();
}
#Override
public int getItemCount() {
return 100;
}
}
private class MyViewHolder extends RecyclerView.ViewHolder{
public TextView mmTextView ;
private Button mButton;
public MyViewHolder(View itemView) {
super(itemView);
mmTextView = (TextView) findViewById(R.id.list_text_view);
mButton = (Button) findViewById(R.id.list_button);
}
private void Data (){
for (int i =0 ;i<=100;i++){
mmTextView.setText(String.valueOf("Text : " + i));
}
}
}
}
You should infilate mmTextView from itemView not from Activity. It should be mmTextView = (TextView) itemView.findViewById(R.id.list_text_view);, also since it's a view of holder you can get it in onBindViewHolder() method using holder.mmTextView.setText(). Infilate button on onCreate() of Activity, also it's convenient to pass data to an adapter inside it's constructor and bind data to adapter on onBindViewHolder() method since it knows which views it possesses.
In onBindViewHolder method bind the data into the textView:
mmTextView.mmTextView.setText("SOME STRING VALUE");

How to change views in ViewPager Fragment

I have a ViewPager with fragments in my activity, each page has a textview, I want to change the text of the textview from the onCreate method in the activity that contains the viewpager. How should I go about doing that?
below is the code that would return a null object exception:
Fragment:
public class MyFragment extends Fragment {
private TextView textView;
public static MyFragment getInstance(){
return new MyFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
textView = (TextView) rootView.findViewById(R.id.textView);
return rootView;
}
public void setText(String text){
textView.setText(text);
}
}
Adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return MyFragment.getInstance();
}
#Override
public int getCount() {
return 3;
}
}
Activity onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
final ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
MyFragment fragment = (MyFragment) adapter.getItem(0);
fragment.setText("Altered"); // and this returns null pointer exception
}
Thank you!
Most FragmentPagerAdapters will have an addFragment method and will keep track various fragments that are added to it via an internal object:
public class MyPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
As it stands, your implementation of getItem returns a new instance of MyFragment every time it is called. As such, MyFragment fragment = (MyFragment) adapter.getItem(0); is a new instance that will never be loaded into the ViewPager, will never be inflated, and hence has a null textView reference.
The other issue is that within the onCreate of your activity, the fragments have not yet been inflated, so the textView will be null unless you delay the call:
final MyFragment fragment = (MyFragment) mPagerAdapter.getItem(0);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
fragment.setText("Altered");
}
}, 100);
But really, why not just set it to the correct value when it is initialized?
Try This
Fragment:
public class MyFragment extends Fragment {
private TextView textView;
private String Text;
public MyFragment (String Text){
this.Text=Text;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
textView = (TextView) rootView.findViewById(R.id.textView);
textView.setText(Text);
return rootView;
}
}
Adapter :
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new MyFragment("Altered");
}
#Override
public int getCount() {
return 3;
}
}
Activity onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
final ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
}

Categories

Resources