I am making an app on android studio. I want to display items in a recycler view using grid layout manager. I am adding three element into the array through which I want to display the recycler view. But when I am running the app, the app is displaying only two items. I don't know what's happening. I have set the height of the recycler view as wrap content still getting this problem.
Here's my code:-
ModelClass.java:-
public class ModelClass {
private String recyc_show_note;
ModelClass(String recyc_show_note){
this.recyc_show_note = recyc_show_note;
}
public String getRecyc_show_note() {
return recyc_show_note;
}}
Adapter.java:-
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private List<ModelClass> recyc_cust_notes;
public Adapter (List<ModelClass>recyc_cust_notes){
this.recyc_cust_notes = recyc_cust_notes;
}
#NonNull
#Override
public Adapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull Adapter.ViewHolder holder, int position) {
String recyc_show_note = recyc_cust_notes.get(position).getRecyc_show_note();
holder.setData(recyc_show_note);
}
#Override
//returns list size
public int getItemCount() {
return recyc_cust_notes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView recycler_view_note;
public ViewHolder(#NonNull View itemView) {
super(itemView);
recycler_view_note = itemView.findViewById(R.id.recyc_show_note);
}
public void setData(String recyc_show_note) {
recycler_view_note.setText(recyc_show_note);
}
}
}
MainActivity.java:-
RecyclerView recyclerView;
List<ModelClass>recyc_cust_notes;
Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main)
SharedPreferences getSharedPreference = getSharedPreferences("My Notes", MODE_PRIVATE);
String note = getSharedPreference.getString("Note", null);
initData();
initRecyclerView();
}
private void initRecyclerView() {
recyclerView = findViewById(R.id.recycler_view);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(),2);
gridLayoutManager.setOrientation(RecyclerView.HORIZONTAL);
recyclerView.setLayoutManager(gridLayoutManager);
adapter = new Adapter(recyc_cust_notes);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
private void initData() {
recyc_cust_notes = new ArrayList<>();
SharedPreferences getSharedPreference = getSharedPreferences("My Notes", MODE_PRIVATE);
String note = getSharedPreference.getString("Note", null);
recyc_cust_notes.add(new ModelClass(note));
recyc_cust_notes.add(new ModelClass("note"));
recyc_cust_notes.add(new ModelClass("sai"));
}
Just do it on this way
recyclerView.setLayoutManager(new GridLayoutManager(this, number_of_cols));
In XML
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_Grid"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Java Code
int cols = 3; // length of cols
RecyclerView recyclerView = findViewById(R.id.rv_Grid);
recyclerView.setLayoutManager(new GridLayoutManager(this, cols));
adapter = new MyRecyclerViewAdapter(this, list);
recyclerView.setAdapter(adapter);
And Remove setOrientation.
It's because of your gridLayoutManager Orientation.
You have 2 choices to show all items:
Change orientation to VERTICAL
Change your recyclerView width to match-parent
Related
My RecyclerAdapter
public class CollatzAdapter extends RecyclerView.Adapter<CollatzAdapter.ViewHolder> {
ArrayList<BigInteger> list = new ArrayList<BigInteger>();
List<Long> primeList;
public CollatzAdapter() {
}
public CollatzAdapter(ArrayList<BigInteger> list, ArrayList<Long> primeList) {
this.list = list;
this.primeList = primeList;
}
public CollatzAdapter(ArrayList<BigInteger> list) {
this.list = list;
}
#NonNull
#Override
public CollatzAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CollatzAdapter.ViewHolder holder, int position) {
holder.mIterationPosition.setText((position + ":"));
holder.mNumber.setText(list.get(position).toString());
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView mNumber;
public TextView mIterationPosition;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mNumber = itemView.findViewById(R.id.iteration_num);
mIterationPosition = itemView.findViewById(R.id.iteration_position);
//mPrime = itemView.findViewById(R.id.iteration_prime);
}
}
public void setList(ArrayList<BigInteger> list) {
this.list = list;
}
}
Where I Implement
iterationFragment = inflater.inflate(R.layout.fragment_iteration, container, false);
collatzViewModel = new ViewModelProvider(getActivity()).get(CollatzViewModel.class);
mRecyclerView = (RecyclerView) iterationFragment.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(false);
mLayoutManager = new LinearLayoutManager(getActivity());
mAdapter = new CollatzAdapter();
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
collatzViewModel.getCollatz().observe(getViewLifecycleOwner(),(list)->{
mAdapter.setList(list);
mAdapter.notifyDataSetChanged();
});
When RecyclerView contains large BigIntegers, say 300 characters for one integer and a list 100,000 of them, it lags when I use the scrollbar. Is there a way to prevent it from lagging when I scroll? It lags so much that it crashes the app. I don't understand why this happens since the RecyclerView should only load a couple of BigIntegers.
Repository: https://github.com/ErickSorto/Collatz-Calculator
This not like question its more like discussion
I'm using swipe cards from this library 'link.fls:swipestack:0.3.0'
With the help of these cards i'm creating recycle view on every card but the data is been repeating for every card
i have used adapter to generate cards and inside this adapter i have initialized recycle view
So my question is how to use recycle view with these swipe cards with non repeating values on every card...
Thanks in advance
Adapter code
public class ParentExamsCardAdapter extends BaseAdapter {
private Context mContext;
private List<ParentExamCards_Pojo> parentExamCardsPojoList = new ArrayList<>();
private RecyclerView recyclerView;
private ParentExamsDataAdapter dataAdapter;
public ParentExamsCardAdapter(Context mContext, List<ParentExamCards_Pojo> parentExamCardsPojoList, ParentExamsDataAdapter dataAdapter) {
this.mContext = mContext;
this.parentExamCardsPojoList = parentExamCardsPojoList;
this.dataAdapter = dataAdapter;
}
#Override
public int getCount() {
return parentExamCardsPojoList.size();
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.single_parent_exams_swipecards, viewGroup, false);
ParentExamCards_Pojo pojoCards = parentExamCardsPojoList.get(position);
CardView cardView = itemView.findViewById(R.id.singleParentExamsCards_cardView);
LinearLayout linearLayout = itemView.findViewById(R.id.singleParentExamsCards_linear);
TextView textView_Title = itemView.findViewById(R.id.singleParentExamsCards_txtTitle);
cardView.setBackgroundColor(pojoCards.getColor());
textView_Title.setText(pojoCards.getExamname());
recyclerView = itemView.findViewById(R.id.singleParentExamsCards_recycleView);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(mContext, LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(dataAdapter);
return itemView;
}
#Override
public int getItemViewType(int position) {
return position;
}
}
ParentExamsDataAdapter
public class ParentExamsDataAdapter extends RecyclerView.Adapter<ParentExamsDataAdapter.MyViewHolder>{
private Context mContext;
private List<List<ParentExams_Pojo>> parentExamsPojoDataList = new ArrayList<>();
public ParentExamsDataAdapter(Context mContext, List<List<ParentExams_Pojo>> parentExamsPojoDataList) {
this.mContext = mContext;
this.parentExamsPojoDataList = parentExamsPojoDataList;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView_name;
TextView textView_date;
TextView textView_time;
public MyViewHolder(View itemView) {
super(itemView);
textView_name=itemView.findViewById(R.id.singleParentExamsData_txtName);
textView_date=itemView.findViewById(R.id.singleParentExamsData_txtDate);
textView_time=itemView.findViewById(R.id.singleParentExamsData_txtTime);
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.single_parent_exams_data, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
ParentExams_Pojo pojoData=parentExamsPojoDataList.get(position).get(position);
holder.textView_name.setText(pojoData.getSubjectname()+"-"+pojoData.getSubjectaspectname());
holder.textView_date.setText(pojoData.getExamdate());
holder.textView_time.setText(pojoData.getStarttime());
}
#Override
public int getItemCount() {
return parentExamsPojoDataList.size();
}
}
Basically You have to Set different adapter(ParentExamsDataAdapter(exams[position].getmarks)) inside the getview() method of ParentExamCardAdapter. The problem here is you are sending one instance of adapter to your parent adapter from Activity or Fragment I guess. And you are setting this for every CardAdapter.
Edit:
Adding suggested code changes from the comments to the answer.
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(mContext, LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(new ParentExamsDataAdapter(**list of items**));
found the solution your are passing same adapter to every recyclerview in every card that is one reason for your problem in ParentExamsCardAdapter
recyclerView.setAdapter(dataAdapter);
the data adapter is same for every postion
the arraylist value is same for aa recyclerview
pass List List ParentExams_Pojo arraylist to ParentExamsCardAdapter use its size in getItemCount
then in onbindviewholder use the arraylist.get(position) to pass to adapter then in adapter use List ParentExams_Pojo to get the list and its size in getitemcount it will solve i think
thus you will have only 1 positon in the adapyter
ParentExams_Pojo pojoData=parentExamsPojoDataList.get(position)
I'm completely lost with this bug, I understand it, but I don't know what's wrong.
For the code :
// In the OnCreate of my activity
historyRecyclerView = (RecyclerView)findViewById(R.id.recycler_suggestions);
SearchBarHistoryAdapter searchBarHistoryAdapter = new SearchBarHistoryAdapter();
searchBarHistoryAdapter.setActivity(this);
historyRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
historyRecyclerView.setAdapter(searchBarHistoryAdapter);
searchBarDisplayManager.setTypeAdapter(SearchBarDisplayManager.SEARCH_TYPE.HISTORY, searchBarHistoryAdapter);
The SearchDisplayManager just contains a list of adapters.
The adapter :
public class SearchBarHistoryAdapter extends SearchBarAdapter {
private ArrayList<String> historyList;
private HistoryTask historyTask;
private void setHistoryList(ArrayList<String> history) {
historyList = history;
notifyDataSetChanged();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_list_item, parent, false);
final HistoryViewHolder historyViewHolder = new HistoryViewHolder(v);
return historyViewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((HistoryViewHolder) holder).bind(historyList.get(position));
}
#Override
public int getItemCount() {
return historyList == null ? 0 : historyList.size();
}
#Override
public void startSearch(String searchString) {
if(TextUtils.isEmpty(searchString)) {
if (historyTask != null) {
historyTask.cancel(true);
}
historyTask = new HistoryTask();
historyTask.execute();
}else{
setHistoryList(null);
}
}
private class HistoryTask extends AsyncTask<Void, Void, ArrayList<String>> {
#Override
protected ArrayList<String> doInBackground(Void... params) {
String history = HelperUI.getSearchbarHistory(activity);
if (!TextUtils.isEmpty(history)) {
return new ArrayList<>(Arrays.asList(history.split("--")));
}
return new ArrayList<>(0);
}
#Override
protected void onPostExecute(ArrayList<String> results) {
super.onPostExecute(results);
if (!results.isEmpty()) {
setHistoryList(results);
}
historyTask = null;
}
}
private class HistoryViewHolder extends RecyclerView.ViewHolder {
TextView hint, name;
ImageView img;
public HistoryViewHolder(View v) {
super(v);
name = (TextView) v.findViewById(R.id.app_label);
hint = ((TextView) v.findViewById(R.id.type_label));
img = ((ImageView) v.findViewById(R.id.item_icon));
}
public void bind(String suggestion) {
name.setText(Html.fromHtml(suggestion));
img.setImageDrawable(activity.getResources().getDrawable(R.drawable.ic_public_grey600_48dp));
img.setTag(suggestion);
}
}
}
Here is the crazy part, when I update the list in setHistoryList, I know the recycler view has the right adapter and it is not null ... but then it kinda loses it, no more adapter in the Recycler view when it tries to update by notifyDatasetChanged() ... it just disappears and, of cours, displays nothing.
Any idea what's wrong ?
You Have to Add a layoutmanager as you regularly do with any Adapter you create for a RecyclerView.
historyRecyclerView.setLayoutManager(new LinearLayoutManager(context));
Just add this line below of code below setAdpater where you are setting your recycler view with the adpapter.
You can add this to xml also (Thanks #Indra Kumar S)
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
For those using AndroidX, a slight modification of #Doongsil's solution:
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
My private Variable here
private RecyclerView recycleViewtask;
private RecyclerView.LayoutManager mLayoutManager;
Then I assign following things
recycleViewtask = findViewById(R.id.recycleViewtask);
recycleViewtask.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
recycleViewtask.setLayoutManager(mLayoutManager);
I having a recyclerview with GridLayoutManager, it populating the grid properly but not updating the data.
Below is my code,
public class AppsGridViewAdapter extends RecyclerView.Adapter<AppsGridViewAdapter.GridViewHolder>{
private ArrayList<App> appArrayList;
private Context context;
public AppsGridViewAdapter(Context context,ArrayList<App> appArrayList){
this.appArrayList = appArrayList;
this.context = context;
}
public static class GridViewHolder extends RecyclerView.ViewHolder{
CompoundAppButton compoundAppButton;
public GridViewHolder(CompoundAppButton itemView){
super(itemView);
compoundAppButton = (CompoundAppButton)itemView;
}
}
#Override
public GridViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CompoundAppButton appButton = new CompoundAppButton(context,null);
return new GridViewHolder(appButton);
}
#Override
public void onBindViewHolder(GridViewHolder holder, int position) {
App app = appArrayList.get(position);
holder.compoundAppButton.updateButtonConfig(app);
}
#Override
public int getItemCount() {
return appArrayList.size();
}
}
Having valid values in the list, but not updating. Where CustomAppButton is a customview. Anyone can help me why it doesnt update.
UPDATE:
I calling recyclerview from my activity, below is the specific code
recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
recyclerView.addItemDecoration(new MarginDecoration(this));
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
AppsGridViewAdapter adapter = new AppsGridViewAdapter(this,appList);
recyclerView.setAdapter(adapter);
The activity contains only recyclerview.
updateButtonConfig is a function in CustomAppButton class, this is where view is updated. getting data to this function, have checked the log.
public void updateButtonConfig(App app){
Picasso.with(context)
.load(app.getAppIcon())
.placeholder(R.drawable.app_icon)
.into(appIcon);
appName.setText(app.getAppName());
category.setText(app.getAppCategory());
price.setText(app.getAppPrice());
appPackage = app.getAppPackage();
}
Here is my adapter class
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.ViewHolder> {
List<CategoryItem> mItems;
public CategoryAdapter(Context context) {
super();
Resources res = context.getResources();
mItems = new ArrayList<>();
mItems.add(new CategoryItem(res.getString(R.string.category_book), R.drawable.books));
// ... few items
mItems.add(new CategoryItem(res.getString(R.string.category_clothing), R.drawable.clothes));
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_category_selection, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
CategoryItem category = mItems.get(i);
viewHolder.title.setText(category.getTitle());
viewHolder.thumbnail.setImageResource(category.getThumbnail());
}
#Override
public int getItemCount() {
return mItems.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public ImageView thumbnail;
public CardView card;
public ViewHolder(View itemView){
super(itemView);
card = (CardView)itemView.findViewById(R.id.card_view);
title = (TextView)itemView.findViewById(R.id.category_title);
thumbnail = (ImageView)itemView.findViewById(R.id.category_thumbnail);
}
}
}
My fragment
public class CategorySelectionFragment extends Fragment {
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
RecyclerView.Adapter mAdapter;
public CategorySelectionFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_category_selection, container, false);
mRecyclerView = (RecyclerView)v.findViewById(R.id.recycler_view);
setUpGrid();
return v;
}
private void setUpGrid() {
mRecyclerView.setHasFixedSize(true);
colNum = 3;
mLayoutManager = new GridLayoutManager(getActivity(), colNum);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new CategoryAdapter(getActivity());
mRecyclerView.setAdapter(mAdapter);
}
When fragment just created (onCreateView called) recyclerview works perfectly, but when app goes to background and then restore scroll start to freeze on the first few items and then continue to work smoothly.
When app restore from background onCreateView method is not called so I try to set up adapter for recyclerview in onStart(), like this:
#Override
public void onStart(){
super.onStart();
// Adapter setting here to avoid freezes, when start to scroll after switching to an app from background.
mRecyclerView.setAdapter(mAdapter);
}
This approach has solved the problem, but it seems like not realy clear way to solve that issue. Since for example, restoring the fragment leads to reset last scrolled position.
Thanks for your help!