This question already has an answer here:
showing RecyclerView on fragment with data from Firebase
(1 answer)
Closed 3 years ago.
I am not able to attach the Firestore Recycler Adapter in the fragment.
I googled many things but no good yet.
The fragment is one of the tabs of the bottomtablayout.
The data is retrieved from a single collection. I want represent the list of multlipe-user post in a single view.
I have tried the below code but to no good yet.
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
//just change the fragment_dashboard
//with the fragment you want to inflate
//like if the class is HomeFragment it should have R.layout.home_fragment
//if it is DashboardFragment it should have R.layout.fragment_dashboard
View view = inflater.inflate(R.layout.fragment_home, container, false);
final FragmentActivity c = getActivity();
LinearLayoutManager layoutManager = new LinearLayoutManager(c);
Query query = PostsRef.orderBy("timestamp", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<PostsModel> options = new FirestoreRecyclerOptions.Builder<PostsModel>()
.setQuery(query, PostsModel.class)
.build();
adapter = new PostsAdapter(options);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(c));
recyclerView.setAdapter(adapter);
mParent =view.findViewById(R.id.relative_home);
return inflater.inflate(R.layout.fragment_home, null);
}
Adapter Code
public class PostsAdapter extends FirestoreRecyclerAdapter<PostsModel, PostsAdapter.PostsHolder> {
private OnItemClickListener listener;
public PostsAdapter(#NonNull FirestoreRecyclerOptions<PostsModel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull PostsHolder holder, int position, #NonNull PostsModel model) {
//retrieve the fields here
holder.textViewTitle.setText(model.getPostTitle());
holder.textViewDescription.setText(model.getPostContent());
holder.textViewPriority.setText(String.valueOf(model.getSpinnerC()));
holder.AuthorName.setText(model.getName());
holder.AuthorGender.setText(model.getGender());
}
#NonNull
#Override
public PostsHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_list_layout,
parent, false);
return new PostsHolder(v);
}
public void deleteItem(int position) {
getSnapshots().getSnapshot(position).getReference().delete();
}
class PostsHolder extends RecyclerView.ViewHolder {
TextView textViewTitle;
TextView textViewDescription;
TextView textViewPriority;
TextView AuthorName;
TextView AuthorGender;
public PostsHolder(View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.quote1);
textViewDescription = itemView.findViewById(R.id.name1);
textViewPriority = itemView.findViewById(R.id.timestamp1);
}
}
}
You're inflating the other view in the onCreateView method.
return inflater.inflate(R.layout.fragment_home, null);
Related
I'm new to android studio . I'm trying to display items in RecycleView but it's doesn't show anything.
This is what android studio says:
E/RecyclerView: No layout manager attached; skipping layout
My Fragment :
public class Articles extends Fragment {
View root;
RecyclerView recyclerView;
NewsList[] myListData = new NewsList[] {
new NewsList("Article 1", "Some Author"),
new NewsList("Article2", "Some Author"),
new NewsList("Article3", "Some Author"),
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_articles, container, false);
recyclerView = root.findViewById(R.id.recyclerView);
NewsAdapter adapter = new NewsAdapter(myListData);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
return root;
}
Here is the code of my Adapter class :
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {
private NewsList[] listdata;
// RecyclerView recyclerView;
public NewsAdapter(NewsList[] listdata) {
this.listdata = listdata;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem= layoutInflater.inflate(R.layout.list_item, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final NewsList myListData = listdata[position];
holder.textView1.setText(listdata[position].getTitle());
holder.textView2.setText(listdata[position].getAuthor());
holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(),"click on item: "+myListData.getTitle(),Toast.LENGTH_LONG).show();
}
});
}
#Override
public int getItemCount() {
return listdata.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView1;
public TextView textView2;
public RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
this.textView1 = (TextView) itemView.findViewById(R.id.textView1);
this.textView2 = (TextView) itemView.findViewById(R.id.textView2);
relativeLayout = (RelativeLayout)itemView.findViewById(R.id.relativeLayout);
}
}
Previously I had an error where the app crashed when opened the fragment but now it's skips the RecyclerView.
I will be gratefull if you help me to resolve this issue.
You need to add a layoutManager to your recycler view:
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_articles, container, false);
recyclerView = root.findViewById(R.id.recyclerView);
NewsAdapter adapter = new NewsAdapter(myListData);
recyclerView.setHasFixedSize(true);
// Add this line
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()))
recyclerView.setAdapter(adapter);
return root;
}
It's mandatory to have a Layout manager for your Recyclerview. For example, you can use a linear one by adding this after inflating your view :
recyclerView.setLayoutManager(new LinearLayoutManager( context ));
where context is whatever your context is
The RecyclerView has components with text, I need that by clicking on a component that has text for example "Chess", the DialogFragment opens and the text "Chess" from the RecyclerView component is transferred to the TextView which is inside this DialogFragment.
To get a key from my item layout file, I write this:
Bundle bundle = new Bundle();
bundle.putString("item", String.valueOf(dialogSRS));
dialogSRS.setArguments(bundle);
But what needs to be written in the DialogFragment so that our text is transferred there?
I am writing the following in my DialogFragment but it doesn't work
public class DialogSkatingRinkSchedule extends DialogFragment{
TextView number_srs_2;
TextView start_srs_2;
TextView end_srs_2;
TextView cost_srs_2_1;
TextView cost_srs_2_2;
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_skatingrinkschedule, container, false);
number_srs_2 = view.findViewById(R.id.number_srs_2);
start_srs_2 = view.findViewById(R.id.start_srs_2);
end_srs_2 = view.findViewById(R.id.end_srs_2);
cost_srs_2_1 = view.findViewById(R.id.cost_srs_2_1);
cost_srs_2_2 = view.findViewById(R.id.cost_srs_2_2);
Bundle getArguments = new Bundle();
number_srs_2 = (TextView) getArguments.getSerializable("item");
return view;
}
}
My adapter
public class AdapterSkatingRinkSchedule extends RecyclerView.Adapter<AdapterSkatingRinkSchedule.SkatingRinkScheduleViewHolder> {
public ArrayList<ItemSkatingRinkSchedule> mSkatingRinkScheduleList;
public List<ItemSkatingRinkSchedule> mSearch;
private AppCompatActivity mActivity;
public AdapterSkatingRinkSchedule(ArrayList<ItemSkatingRinkSchedule> SkatingRinkScheduleList) {
mSkatingRinkScheduleList = SkatingRinkScheduleList;
mSearch = new ArrayList(mSkatingRinkScheduleList);
}
#NonNull
#Override
public SkatingRinkScheduleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_srs, parent, false);
return new SkatingRinkScheduleViewHolder(v);
}
public static class SkatingRinkScheduleViewHolder extends RecyclerView.ViewHolder {
public TextView number_srs, start_time_srs, end_time_srs, cost_1_srs, cost_2_srs;
public TextView number_srs_2;
public LinearLayout ll_main;
public SkatingRinkScheduleViewHolder(View itemView) {
super(itemView);
number_srs = itemView.findViewById(R.id.number_srs);
start_time_srs = itemView.findViewById(R.id.start_time_srs);
end_time_srs = itemView.findViewById(R.id.end_time_srs);
cost_1_srs = itemView.findViewById(R.id.cost_1_srs);
cost_2_srs = itemView.findViewById(R.id.cost_2_srs);
ll_main = itemView.findViewById(R.id.ll_main);
}
}
#SuppressLint("LongLogTag")
#Override
public void onBindViewHolder(SkatingRinkScheduleViewHolder holder, int position) {
ItemSkatingRinkSchedule currentItem = mSkatingRinkScheduleList.get(position);
holder.number_srs.setText(currentItem.get_session_number());
holder.start_time_srs.setText(currentItem.get_session_start());
holder.end_time_srs.setText(currentItem.get_session_end());
holder.cost_1_srs.setText(currentItem.get_weekdays());
holder.cost_2_srs.setText(currentItem.get_weekends_and_holidays());
holder.ll_main.setOnClickListener(v -> {
DialogSkatingRinkSchedule dialogSRS = new DialogSkatingRinkSchedule();
dialogSRS.show(((AppCompatActivity) v.getContext()).getSupportFragmentManager(), "item");
Bundle bundle = new Bundle();
bundle.putString("item", String.valueOf(dialogSRS));
dialogSRS.setArguments(bundle);
});
holder.getAdapterPosition();
}
#Override
public int getItemCount() {
return mSkatingRinkScheduleList.size();
}
}
You can access the arguments Bundle of a Fragment or DialogFragment by calling the method getArguments(). Since you put a String there previously by writing
bundle.putString("item", String.valueOf(dialogSRS));
you should retrieve the value by using getString("item"). Then you can display the text from the Bundle with the TextView as follows:
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_skatingrinkschedule, container, false);
number_srs_2 = view.findViewById(R.id.number_srs_2);
// assign other Views like before
Bundle args = getArguments();
String myText = args.getString("item");
number_srs_2.setText(myText);
return view;
}
I've created a recyclerView into a fragment. Everything goes well but when i scroll in the list of elements, the attributes change without reason
Here is the code of the fragment:
public class HistorySectionFragment extends Fragment {
private static final String TAG = HistorySectionFragment.class.getSimpleName();
static ArrayList<String> a;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RecyclerView recyclerView = (RecyclerView) inflater.inflate(
R.layout.recycler_view, container, false);
ContentAdapter adapter = new ContentAdapter();
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return recyclerView;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
static TextView card_title;
static TextView card_text;
public ViewHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.item_card, parent, false));
card_title = (TextView)itemView.findViewById(R.id.card_title);
card_text = (TextView)itemView.findViewById(R.id.card_text);
}
}
public static class ContentAdapter extends RecyclerView.Adapter<ViewHolder>{
// Set numbers of Card in RecyclerView.
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final String name = MainActivity.getTestByPosition(position).getName();
holder.card_title.setText(name);
final String description = MainActivity.getTestByPosition(position).getDescription();
holder.card_text.setText(description);
}
#Override
public int getItemCount() {
return MainActivity.getSize();
}
}
}
The problem is when the recyclerview calls to create new elements.
EDIT:
When i say the attributes change i mean the information of each cardView change doing scroll
I have a feeling the views in your RecyclerView are not stable. When the views get recycled, the ids are being saved and the data is mismatched.
Trying doing this.
recyclerView.setHasStableIds(false);
Firstly why you use inflater for the recyclerview? the best way is to declare your recyclerview in xml file and get the recyclerview via findviewById.
Secondly, what do you mean about the attributes change without reason
And finally:it's not very appreciate to use viewholder and adapter like that,
http://javatechig.com/android/android-recyclerview-example
SOLVED.
The problem was in the recycler and in the viewHolder are both Static classes.
I've a NavigationDrawer to start fragments. I've a fragment with 4 tabs from TabPageIndicator with fragments which contains a listview.
If I click the entry in the menu again which launches the fragment, the elements are gone. Sometimes if I switch between them they are gone too. I also have to swipe sometimes to get them back.
ArchivFragment
public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
View view = layoutInflater.inflate(R.layout.fragment_archiv, viewGroup, false);
List<String> titles=new ArrayList<String>();
titles.add(getString(R.string.category_animal));
titles.add(getString(R.string.category_earth));
titles.add(getString(R.string.category_water));
titles.add(getString(R.string.category_air));
FragmentPagerAdapter adapter = new ArchivTabAdapter(getFragmentManager(), titles);
ViewPager pager = (ViewPager)view.findViewById(R.id.pager);
pager.setAdapter(adapter);
TabPageIndicator indicator = (TabPageIndicator)view.findViewById(R.id.indicator);
indicator.setViewPager(pager);
return view;
}
ArchivTabAdapter using from an example
public class ArchivTabAdapter extends FragmentPagerAdapter {
private List<String> tabs;
public ArchivTabAdapter(FragmentManager fm, List<String> tabs) {
super(fm);
this.tabs = tabs;
}
#Override
public Fragment getItem(int position) {
return ArchivListFragment.newInstance(position);
}
#Override
public CharSequence getPageTitle(int position) {
return tabs.get(position % tabs.size()).toUpperCase(Locale.getDefault());
}
#Override
public int getCount() {
return tabs.size();
}
}
ArchivListFragment
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
View view = (View) inflater.inflate(R.layout.archiv_list, viewGroup, false);
ListView lv = (ListView) view.findViewById(R.id.tab);
ArrayList<Item> al = new ArrayList<Item>();
al = getArrayListToApply(filter);
lv.setAdapter(new ArchivArrayAdapter(getActivity(), al));
return view;
}
ArchivArrayAdapter
similar to ArchivTabAdapter
update 1
it seems, that I've to scroll over all items (especially the last one) to get the others back
ArchivTabAdapter
similar problem
change from
android.support.v4.app.FragmentPagerAdapter to android.support.v4.app.FragmentStatePagerAdapter
Im trying to add a listview inside a fragment witch is also inside a tabhost. the app is not crashing or anything, but the list view is not showing anything.
Here is my code:
Class for the tabPager
public class TabPagerAdapter extends FragmentPagerAdapter {
public TabPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FragmentHome();
case 1:
return new FragmentBadges();
case 2:
return new FragmentBenefits();
}
return null;
}
Following is the fragment where I want the listview:
public class FragmentBadges extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_badges_list, null);
BadgesListAdapter adapter = new BadgesListAdapter(this.getActivity(), getCurrentBadges());
ListView badgeslist = (ListView) rootView.findViewById(R.id.badges_list);
badgeslist.setAdapter(adapter);
badgeslist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//TODO do some
}
});
return rootView;
}
And following is the adapter:
public class BadgesListAdapter extends ArrayAdapter<String> {
private final Activity context;
private List<Badge> badges;
public BadgesListAdapter(Activity context, List<Badge> badges) {
super(context, R.layout.fragment_badges_listrow);
this.context = context;
this.badges = badges;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.fragment_badges_listrow, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.text);
ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
txtTitle.setText(badges.get(position).getName());
imageView.setImageResource(badges.get(position).getDrawableValue());
return rowView;
}
while debugging I found out that the getView method inside the badgesListAdapter is never called.
I have this same code for another app but without the tabpager and there it all works perfectly...
Check whether getCurrentBadges() method not returns empty list. If so there is no data to show in ListView.
I was able to make it work by inhering ListFragment in FragmentBadges, following this tutorial https://www.youtube.com/watch?v=heR4zhj_wV0