When I add an item by button Scan Now, the public double sumCost value incrementes by the cost value in the AddItem method and then TextView(android:id="#+id/SumText") assigns this value. And How to decrease sumCost by the number that is in cost and set new text in TextView when pressing the Delete button? Thanks for any help
enter image description here
My full code:
MainActivity:
package com.example.testfirst;
...
public class MainActivity extends AppCompatActivity {
TextView sumText;
Button buttonAdd;
List<Contact> contacts = new LinkedList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_users);
buttonAdd = (Button) findViewById(R.id.scanBtn);
sumText = (TextView) findViewById(R.id.SumText);
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AddItem("Tom", 2.45);
sumText.setText(Double.toString(sumCost));
}
});
}
public void AddItem(String name, double cost){
sumCost += cost;
RecyclerView rvContacts = (RecyclerView) findViewById(R.id.recyclerView);
ContactsAdapter adapter = new ContactsAdapter(contacts);
rvContacts.setAdapter(adapter);
rvContacts.setLayoutManager(new LinearLayoutManager(this));
contacts.add(new Contact(name,Double.toString(cost)));
}
public double sumCost = 0;
}
Contact(Model class):
...
public class Contact {
private String mName;
private String mCost;
public Contact(String name, String cost) {
mName = name;
mCost = cost;
}
public String getName() {
return mName;
}
public String getCost() {
return mCost;
}
}
ContactsAdapter:
...
public class ContactsAdapter extends RecyclerView.Adapter<ViewHolder>{
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View contactView = inflater.inflate(R.layout.item_contact, parent, false);
return new ViewHolder(contactView).linkAdapter(this);
}
///////////////
#NonNull
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Contact contact = mContacts.get(position);
TextView textViewId = holder.nameId;
textViewId.setText(contact.getName());
TextView textViewCost = holder.nameCost;
textViewCost.setText(contact.getCost());
}
#Override
public int getItemCount() {
return mContacts.size();
}
List<Contact> mContacts;
public ContactsAdapter(List<Contact> contacts) {
mContacts = contacts;
}
}
class ViewHolder extends RecyclerView.ViewHolder {
private ContactsAdapter adapter;
public TextView nameId;
public TextView nameCost;
public ViewHolder(#NonNull View itemView) {
super(itemView);
nameId = (TextView) itemView.findViewById(R.id.text);
nameCost = (TextView) itemView.findViewById(R.id.textCost);
itemView.findViewById(R.id.delete).setOnClickListener(view -> {
adapter.mContacts.remove(getAdapterPosition());
adapter.notifyItemRemoved(getAdapterPosition());
});
}
public ViewHolder linkAdapter(ContactsAdapter adapter){
this.adapter = adapter;
return this;
}
}
item_contact.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="10dp"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:contentPadding="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="#string/app_name"
android:textSize="20sp" />
<TextView
android:id="#+id/textCost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/text"
android:text="#string/app_name"
android:textSize="20sp" />
<Button
android:id="#+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="3dp"
android:layout_marginEnd="3dp"
android:text="Delete" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
activity_users.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/SumText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="0.00"
android:textSize="30sp"/>
<Button
android:id="#+id/scanBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scan now"
android:textSize="30sp"
android:layout_gravity="center_horizontal"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
One easy way to do that would be do add a "Decrementer" interface in the adapter that it can call to decrement the total cost, like this:
// Define the interface
public interface Decrementer {
void onDelete(double cost);
}
// Define an instance of the interface to hold
private final Decrementer mDecrementer;
// Pass in a decrementer at construction
public ContactsAdapter(List<Contact> contacts, Decrementer decr) {
mContacts = contacts;
mDecrementer = decr;
}
#NonNull
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
// get views and such ...
// Call the decrementer method when the button is clicked
// Could set this in onBindViewHolder, or pass the decrementer
// into the ViewHolder itself and use it there.
deleteButton.setOnClickListener(view -> {
int pos = holder.getAdapterPosition();
Contact c = mContacts.get(pos);
// add getCostAmount to return a double, or better yet, just
// store it as a Double instead of a string in Contact
mDecrementer.onDelete(c.getCostAmount());
mContacts.remove(pos);
notifyItemRemoved(pos);
});
}
and you would define the Decrementer when you create the adapter so it can access the Activity class members, like this:
ContactsAdapter adapter = new ContactsAdapter(contacts, new ContactsAdapter.Decrementer() {
#Override
public void onDelete(double cost) {
sumCost -= cost;
// change activity TextViews and such here too
sumText.setText(Double.toString(sumCost));
}
});
Side note: you don't need to create a whole new adapter every time you add an item, just add it to the contacts array and call an appropriate notifyDataSetChanged method on the existing adapter.
private ContactsAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_users);
//...
RecyclerView rvContacts = (RecyclerView) findViewById(R.id.recyclerView);
ContactsAdapter adapter = new ContactsAdapter(contacts);
rvContacts.setAdapter(adapter);
rvContacts.setLayoutManager(new LinearLayoutManager(this));
}
public void AddItem(String name, double cost){
sumCost += cost;
contacts.add(new Contact(name,Double.toString(cost)));
adapter.notifyDataSetChanged(); // or a less expensive notify call
}
Related
I am developing an app in which I am showing users data in a recyclerview. I have used a library which shows preview of a url.
My Problem
Each user has video1, video2, and video3 nodes and I want to display the data of each user 3 times i.e. in the first itemView I want to display video1, in the 2nd video2, and in the 3rd video3. So each user will have 3 itemViews. Below is my code. Please do ask if you need any clarification. Thanks in advance
[![Database Struction][1]][1]
[1]: https://i.stack.imgur.com/XJQqt.png
Adapter Class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context context;
ArrayList<ModelClass> modelClass = new ArrayList<>();
public MyAdapter(Context context, ArrayList<ModelClass> modelClass) {
this.context = context;
this.modelClass = modelClass;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.gig_display_layout, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.urlEmbeddedView.setURL(modelClass.get(position).getVideo1(), new URLEmbeddedView.OnLoadURLListener() {
#Override
public void onLoadURLCompleted(URLEmbeddedData data) {
holder.urlEmbeddedView.title(data.getTitle());
holder.urlEmbeddedView.description(data.getDescription());
holder.urlEmbeddedView.host(data.getHost());
holder.urlEmbeddedView.thumbnail(data.getThumbnailURL());
holder.urlEmbeddedView.favor(data.getFavorURL());
}
});
}
#Override
public int getItemCount() {
return modelClass.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
URLEmbeddedView urlEmbeddedView;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
urlEmbeddedView = itemView.findViewById(R.id.urlView);
}
}
}
Model Class
public class ModelClass {
public String name, video1, video2, video3, videos;
int showVideoCount = 1;
int lifeTimeClicks = 0;
int lifeTimeClicksOnProfile = 0;
int dailyClicksOnProfile = 0;
int dailyClicksByYou = 0;
public ModelClass(String name, String video1, String video2, String video3) {
this.name = name;
this.video1 = video1;
this.video2 = video2;
this.video3 = video3;
}
public ModelClass() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVideo1() {
return video1;
}
public void setVideo1(String video1) {
this.video1 = video1;
}
public String getVideo2() {
return video2;
}
public void setVideo2(String video2) {
this.video2 = video2;
}
public String getVideo3() {
return video3;
}
public void setVideo3(String video3) {
this.video3 = video3;
}
HomeFragment
dRef.addListenerForSingleValueEvent(new ValueEventListener() { // singleValueEvent will only call the firebase database once
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list = new ArrayList<ModelClass>();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
ModelClass modelClass = dataSnapshot.getValue(ModelClass.class);
list.add(modelClass);
Collections.shuffle(list); // This will shuffle the links
}
MyAdapter adapter = new MyAdapter(getActivity(), list);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
Sir Use Nested Recyclerview, Inside your main Item view in xml use another recyclerview.
e.g:
MainAcitivty.xml
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>
FirstItem.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#f3f3f3"
app:cardElevation="8dp"
android:layout_margin="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:orientation="vertical">
<TextView
android:id="#+id/tv_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12sp"
android:textSize="18sp"
android:text="Item Title"/>
//recycler for video
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_sub_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
SubItem.xml (for displaying videos) :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tv_sub_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="Sub item title"/> //Video
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
you have model and adapter for MainItem already, Now create model and adapter for subitem(for videos), now in onBindViewHolder of the MainItemAdapter, set subItem layout, also initialize in ItemViewHolder in MainItemAdapter.
e.g. something like this
#Override
public void onBindViewHolder(#NonNull ItemViewHolder itemViewHolder, int i) {
LinearLayoutManager layoutManager = new LinearLayoutManager(
itemViewHolder.rvSubItem.getContext(),
LinearLayoutManager.VERTICAL,
false
);
// Create sub item view adapter
SubItemAdapter subItemAdapter = new SubItemAdapter(item.getSubItemList());
itemViewHolder.rvSubItem.setLayoutManager(layoutManager);
itemViewHolder.rvSubItem.setAdapter(subItemAdapter);
itemViewHolder.rvSubItem.setRecycledViewPool(viewPool);
}
class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView tvItemTitle;
private RecyclerView rvSubItem;
ItemViewHolder(View itemView) {
super(itemView);
tvItemTitle = itemView.findViewById(R.id.tv_item_title);
rvSubItem = itemView.findViewById(R.id.rv_sub_item);
}
}
I have an AlertDialog in it there used to be a ListView in which the contents of the ArrayList were displayed. For beauty, I decided to replace it with Recyclerview, Card and the problems started.
Items are added to ArrayList <String> mainListWord during the work and they should be included in the Recyclerview cards. The problem is that either the entire list falls into one card at once, or each next card contains the previous elements + 1. For example: the first card: 1 element, the second card: 2 elements, etc.
How to implement it so that when a new element is added to the array, it will be placed in its own card?
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="#+id/innerText"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_centerInParent="true"/>
<Button
android:id="#+id/press"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Press"
android:layout_below="#id/innerText"
android:layout_centerHorizontal="true"
android:onClick="openDialog"/>
</RelativeLayout>
recycler_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="4dp"
android:layout_margin="4dp"
app:cardBackgroundColor="#color/colorCardBack">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#color/colorCard">
<ImageView
android:id="#+id/imageView_1"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="4dp" />
<TextView
android:id="#+id/textview_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text_1"
android:textStyle="bold"
android:textColor="#android:color/black"
android:layout_centerInParent="true"
android:textSize="16sp"
android:layout_marginStart="5dp"
android:layout_toEndOf="#id/imageView_1"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
stats_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="50dp"
android:layout_margin="10dp"
android:background="#color/colorAccent"
android:scrollbars="vertical"
android:layout_above="#id/butClose"/>
<Button
android:id="#+id/butClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private EditText innerText;
private Button press, butClose;
private ArrayList<RecyclerViewItem> recyclerViewItem;
private ArrayList<String> mainListWord;
private AlertDialog OptionDialog;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerViewItem = new ArrayList<>();
mainListWord = new ArrayList<>();
innerText = findViewById(R.id.innerText);
press = findViewById(R.id.butClose);
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void makeRecyclerList(ArrayList<String> income){
String[] listWord_lenght = income.toArray(new String[0]);
String keyWord = (String.join("", listWord_lenght));
recyclerViewItem.add(new RecyclerViewItem(R.drawable.star, keyWord));
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void openDialog(View v){
String word = innerText.getText().toString();
mainListWord.add(word);
makeRecyclerList(mainListWord);
Dialogus();
innerText.setText("");
}
public void Dialogus(){
LayoutInflater li = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = li.inflate(R.layout.stats_fragment, null, false);
OptionDialog = new AlertDialog.Builder(this).create();
OptionDialog.setTitle("TestInfo");
recyclerView = v.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
adapter = new RecyclerViewAdapter(recyclerViewItem);
layoutManager = new LinearLayoutManager(this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(layoutManager);
butClose = v.findViewById(R.id.butClose);
OptionDialog.setView(v);
OptionDialog.setCancelable(true);
butClose.setBackgroundColor(Color.CYAN);
butClose.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
OptionDialog.dismiss();
}
});
OptionDialog.show();
}
}
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewViewHolder> {
private ArrayList<RecyclerViewItem> arrayList;
public static class RecyclerViewViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView_1;
public TextView textview_1;
public RecyclerViewViewHolder(#NonNull View itemView) {
super(itemView);
imageView_1 = itemView.findViewById(R.id.imageView_1);
textview_1 = itemView.findViewById(R.id.textview_1);
}
}
public RecyclerViewAdapter(ArrayList<RecyclerViewItem> arrayList){
this.arrayList = arrayList;
}
#NonNull
#Override
public RecyclerViewViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_item, viewGroup, false);
RecyclerViewViewHolder recyclerViewViewHolder= new RecyclerViewViewHolder(view);
return recyclerViewViewHolder;
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewViewHolder recyclerViewViewHolder, int position) {
RecyclerViewItem recyclerViewItem = arrayList.get(position);
recyclerViewViewHolder.imageView_1.setImageResource(recyclerViewItem.getImageResource());
recyclerViewViewHolder.textview_1.setText(recyclerViewItem.getText_1());
}
#Override
public int getItemCount() {
return arrayList.size();
}
}
RecyclerViewItem.java
package freijer.app.one;
public class RecyclerViewItem {
private int imageResource;
private String text_1;
public int getImageResource() {
return imageResource;
}
public void setImageResource(int imageResource) {
this.imageResource = imageResource;
}
public String getText_1() {
return text_1;
}
public void setText_1(String text_1) {
this.text_1 = text_1;
}
public RecyclerViewItem(int imageResource, String text_1) {
this.imageResource = imageResource;
this.text_1 = text_1;
}
}
So, for a personal project I'm making a stream app for Android which are separated by three fragments in the main screen where each of those fragment will be a list of a type of show in our archive, like movies, TV series and animations by using a RecyclerView inside of them.
That being said, after some errors that I managed to fix, the app is not showing what was expected, by skipping the RecyclerView because it has no "adapter".
Here is the code so far:
The main activity:
public class MenuPrincipal extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_principal);
AbasMenuPrincipalAdapter adapter = new AbasMenuPrincipalAdapter( getSupportFragmentManager() );
adapter.adicionar( new FilmesFragment() , "Filmes");
adapter.adicionar( new SeriesFragment() , "Series");
adapter.adicionar( new AnimacoesFragment() , "Animações");
ViewPager viewPager = (ViewPager) findViewById(R.id.abas_view_pager);
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.abas);
tabLayout.setupWithViewPager(viewPager);
}
}
One of the fragments used on the main screen:
public class AnimacoesFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
ArrayList<Item> exemploItemList = new ArrayList<Item>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.animacoes_fragment, container, false);
TextView tv = view.findViewById(R.id.text1);
tv.setText("Você está na terceira aba");
exemploItemList.add(new Item(R.drawable.ic_android, "Line1", "line2"));
exemploItemList.add(new Item(R.drawable.ic_desktop_mac, "Line2", "line3"));
exemploItemList.add(new Item(R.drawable.ic_laptop_windows, "Line4", "line5"));
mRecyclerView = (RecyclerView) view.findViewById(R.id.AnimacaoRecyclerView);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(llm);
ItemAdapter adapter = new ItemAdapter(exemploItemList);
mAdapter = adapter;
mRecyclerView.setAdapter(mAdapter);
return view;
}
}
And its layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/AnimacaoRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:scrollbars="vertical" />
</LinearLayout>
This is what I'm trying to show on that RecyclerView (later will be the real thing, now it's just a test):
public class Item {
private int mImageResource;
private String text1;
private String text2;
public Item(int mImageResource, String text1, String text2) {
this.mImageResource = mImageResource;
this.text1 = text1;
this.text2 = text2;
}
public int getmImageResource() {
return mImageResource;
}
public void setmImageResource(int mImageResource) {
this.mImageResource = mImageResource;
}
public String getText1() {
return text1;
}
public void setText1(String text1) {
this.text1 = text1;
}
public String getText2() {
return text2;
}
public void setText2(String text2) {
this.text2 = text2;
}
}
It's layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="#string/imagem"
android:padding="2dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="50dp"
android:layout_marginTop="0dp"
android:text="#string/line1"
android:textColor="#000000"
android:textSize="20sp"
android:textStyle="bold"
android:id="#+id/textView"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="50dp"
android:layout_marginTop="28dp"
android:text="#string/line2"
android:textSize="15sp"
android:textStyle="bold"
android:id="#+id/textView2"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
Finally, the adapter used to convert the list:
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ItemViewHolder> {
private ArrayList<Item> mItemList;
public static class ItemViewHolder extends RecyclerView.ViewHolder{
public ImageView mImageView;
public TextView mTextView1;
public TextView mTextView2;
public ItemViewHolder(#NonNull View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.imageView);
mTextView1 = itemView.findViewById(R.id.textView);
mTextView2 = itemView.findViewById(R.id.textView2);
}
}
#NonNull
#Override
public ItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
ItemViewHolder ivh = new ItemViewHolder(v);
return ivh;
}
public ItemAdapter(ArrayList<Item> itemList){
mItemList = itemList;
}
#Override
public void onBindViewHolder(#NonNull ItemViewHolder holder, int position) {
Item currentItem = mItemList.get(position);
holder.mImageView.setImageResource(currentItem.getmImageResource());
holder.mTextView1.setText(currentItem.getText1());
holder.mTextView2.setText(currentItem.getText2());
}
#Override
public int getItemCount() {
return mItemList.size();
}
}
First of all, check your fragment layout file. The linear layout parent orientation set to 'horizontal' and width of it's child views ('textview' & 'recyclerview') is match parent. This won't work.
Try to initialize your recyclerview adapter in 'onCreate' and use 'notifyDataSetChanged()' after setting up the adapter with recyclerview.
I'm writing a shopping list app that will save data to a Firebase Realtime database and update the screen in real time. As of right now I have it so that when you click the "+ List item" button, it adds a ShoppingListItem to the database with the name "test". It does that correctly, but it isn't updating the screen. I've double checked that the methods are being called, but the screen isn't reflecting the updated data. I have also tried using notifyDataSetChanged() and that hasn't seemed to help either.
This is the code for the ShoppingListFragment:
public class ShoppingListFragment extends Fragment {
private ArrayList<String> listItems = new ArrayList<String>();
private ListView mListView;
private TextView addItemButton;
private LinearLayout ll;
private RecyclerView rv;
private FirebaseRecyclerAdapter<ShoppingListItem, ShoppingListHolder> firebaseRecyclerAdapter;
private DatabaseReference mDatabase;
public ShoppingListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
mDatabase = FirebaseDatabase.getInstance().getReference();
//get reference to user
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
Query query = mDatabase.child("users").child(uid).child("shopping");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_shopping_list, container, false);
rv = view.findViewById(R.id.shopping_list);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
// find the + List Item button
final TextView addCheckBox = view.findViewById(R.id.add_check_box);
addCheckBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addNewCheckBox(container);
}
});
FirebaseRecyclerOptions<ShoppingListItem> options = new FirebaseRecyclerOptions.Builder<ShoppingListItem>()
.setQuery(query, ShoppingListItem.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ShoppingListItem, ShoppingListHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ShoppingListHolder holder, int position, #NonNull ShoppingListItem item) {
holder.setItem(item);
}
#NonNull
#Override
public ShoppingListHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shopping_list_item, parent, false);
return new ShoppingListHolder(view);
}
};
return view;
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
rv.setAdapter(firebaseRecyclerAdapter);
}
#Override
public void onStop() {
super.onStop();
if (firebaseRecyclerAdapter != null) {
firebaseRecyclerAdapter.stopListening();
}
}
public void addNewCheckBox(ViewGroup container) {
String key = mDatabase.child("users").child(getUid()).child("shopping_list").push().getKey();
ShoppingListItem item = new ShoppingListItem("test");
mDatabase.child("users").child(getUid()).child("shopping_list").child(key).setValue(item);
firebaseRecyclerAdapter.notifyDataSetChanged();
}
public int convertToPx(int input) {
DisplayMetrics metrics = getResources().getDisplayMetrics();
int px = (int) (input * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
private class ShoppingListHolder extends RecyclerView.ViewHolder {
private final EditText itemName;
public ShoppingListHolder(View itemView) {
super(itemView);
itemName = itemView.findViewById(R.id.item_name);
}
public void setItem(ShoppingListItem item) {
itemName.setText(item.getItemName());
}
}
private String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
and the ShoppingListItem:
public class ShoppingListItem {
private String itemName;
private String type;
private String unit;
private int quantity;
private String location;
public ShoppingListItem() {
}
public ShoppingListItem(String name) {
this.itemName = name;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
}
XML for the shopping list view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/home_fragment_main_layout"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.jggdevelopment.wannacook.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Shopping List"
android:textStyle="bold"
android:textSize="18sp"
android:layout_marginStart="16dp"
android:layout_marginBottom="16dp"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/shopping_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:clipToPadding="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/add_check_box"
android:text="+ List item"
android:textSize="16sp"
android:layout_marginStart="40dp"
android:layout_marginTop="16dp"/>
</LinearLayout>
and XML for each line item in the shopping list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/item_name"
android:layout_weight="1"
android:layout_marginStart="12dp"
android:layout_marginEnd="32dp"
android:inputType="text"
android:background="#android:color/transparent"
/>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:id="#+id/xbutton"
android:layout_marginEnd="12dp"
android:src="#drawable/ic_close_white_24dp"
android:layout_gravity="center_vertical"/>
</LinearLayout>
This is not working because you forgot to set the adapter in the onCreate() method. To solve this, add rv.setAdapter(firebaseRecyclerAdapter);, right before you are returning the view like this:
rv.setAdapter(firebaseRecyclerAdapter);
return view;
And you can remove that line of code from the onStart() method because is not needed there.
If you are interested, I have created a tutorial in which I'm explaining step by step, how to build a Shopping List App using Cloud Firestore and Android.
I am trying to implement a RecyclerView with two different layouts. In the MainActivity I first create ListItem object and add it to the list and then add that to the adapter, but it doesn't show. And also I am calling a method that creates ListItem object and adds it to the list and then notifies the adapter, but it still doesn't show. Here is my code so far:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="nl.iansoft.www.recyclerviewproblem.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="100dp"
/>
</android.support.constraint.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ArrayList<ListItem> listItems;
private CustomAdapter customAdapter;
private RecyclerView rvList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rvList = (RecyclerView)findViewById(R.id.rvList);
listItems = new ArrayList<>();
ListItem listItem = new ListItem("MyName", "MyLatsName", "MyEmail");
listItems.add(listItem);
customAdapter = new CustomAdapter(listItems);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
rvList.setLayoutManager(mLayoutManager);
rvList.setItemAnimator(new DefaultItemAnimator());
rvList.setAdapter(customAdapter);
addItemToTheList();
}
private void addItemToTheList(){
ListItem listItem = new ListItem("MyName", "MyLatsName", "MyEmail");
listItems.add(listItem);
customAdapter.notifyDataSetChanged();
}
}
CustomAdapter.java
public class CustomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<ListItem> listItems;
public class ListItem1ViewHolder extends RecyclerView.ViewHolder {
public TextView tvName;
public TextView tvLastName;
public TextView tvEmail;
public ListItem1ViewHolder(View view) {
super(view);
tvName = (TextView) view.findViewById(R.id.tvName);
tvLastName = (TextView) view.findViewById(R.id.tvLastName);
tvEmail = (TextView) view.findViewById(R.id.tvEmail);
}
}
public class ListItem2ViewHolder extends RecyclerView.ViewHolder {
public TextView tvName2;
public TextView tvLastName2;
public TextView tvEmail2;
public ListItem2ViewHolder(View view) {
super(view);
tvName2 = (TextView) view.findViewById(R.id.tvName2);
tvLastName2 = (TextView) view.findViewById(R.id.tvLastName2);
tvEmail2 = (TextView) view.findViewById(R.id.tvEmail2);
}
}
public CustomAdapter(ArrayList<ListItem> listItems) {
this.listItems = listItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
if(viewType == 1){
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_list_item, parent, false);
return new CustomAdapter.ListItem1ViewHolder(itemView);
}else{
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_list_item2, parent, false);
return new CustomAdapter.ListItem2ViewHolder(itemView);
}
}
#Override
public int getItemViewType(int position) {
if(listItems.get(position).getName().equals("MyName")){
return 1;
}else{
return 2;
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ListItem listItem = listItems.get(position);
if(holder.getItemViewType() == 1) {
ListItem1ViewHolder listItem1ViewHolder = (ListItem1ViewHolder) holder;
listItem1ViewHolder.tvName.setText(listItem.getName());
listItem1ViewHolder.tvLastName.setText(listItem.getLastName());
listItem1ViewHolder.tvEmail.setText(listItem.getEmail());
}else{
ListItem2ViewHolder listItem2ViewHolder = (ListItem2ViewHolder)holder;
listItem2ViewHolder.tvName2.setText(listItem.getName());
listItem2ViewHolder.tvLastName2.setText(listItem.getLastName());
listItem2ViewHolder.tvEmail2.setText(listItem.getEmail());
}
}
#Override
public int getItemCount() {
return listItems.size();
}
}
ListItem.java
public class ListItem {
private String name;
private String lastName;
private String email;
public ListItem() {
}
public ListItem(String name, String lastName, String email) {
this.name = name;
this.lastName = lastName;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
my_list_item2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvName2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="Name2"
android:layout_marginTop="15dp"
android:padding="5dp"/>
<TextView
android:id="#+id/tvLastName2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="Last Name2"
android:layout_below="#+id/tvName2"
android:layout_marginTop="10dp"
android:padding="5dp" />
<TextView
android:id="#+id/tvEmail2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="my#email.com"
android:layout_below="#+id/tvLastName2"
android:layout_marginTop="5dp"
android:padding="5dp" />
</RelativeLayout>
my_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="Name"
android:layout_marginTop="15dp"
android:padding="5dp"/>
<TextView
android:id="#+id/tvLastName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="Last Name"
android:layout_below="#+id/tvName"
android:layout_marginTop="10dp"
android:padding="5dp" />
<TextView
android:id="#+id/tvEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="my#email.com"
android:layout_below="#+id/tvLastName"
android:layout_marginTop="5dp"
android:padding="5dp" />
</RelativeLayout>
The issue is in ConstraintLayout. Because you haven't specified any constraints to your RecyclerView.
Either specify constraints, or move to another layout (e.g. FrameLayout).
But specifically in this case you do not need parent layout, because it is useless, as long as you have only RecyclerView in your view hierarchy.