I am trying to create a RecyclerView that populates CardViews based on data in Firebase. I am receiving an IndexOutOfBoundsException when there is no data in Firebase, however I would like for the RecyclerView to display (without any data) when there is no data in Firebase:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Firebase.setAndroidContext(this);
setContentView(R.layout.activity_discussion);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
setTitle(R.string.discussion_title_text);
mDateFormat = new SimpleDateFormat("MM-dd-yyyy");
mDate = new Date();
mCurrentDateString = mDateFormat.format(mDate);
mBaseRef = new Firebase(FIREBASE_URL);
mPollsRef = mBaseRef.child(POLLS_LABEL);
mUpdateRef = mPollsRef.child(mCurrentDateString).child(String.valueOf(mPollIndex + 1));
mCommentsRef = mUpdateRef.child(COMMENTS_LABEL);
mPollImage = (ImageView) findViewById(R.id.comments_image);
mPollCommentQuestion = (TextView) findViewById(R.id.poll_comment_question);
mUserComment = (EditText) findViewById(R.id.user_comment);
mUserAvatar = (ImageView) findViewById(R.id.profile_image_avatar);
mCommentArrayList = new ArrayList<Comments>();
mCommentIDArrayList = new ArrayList<String>();
mPollCommentsList = (RecyclerView) findViewById(R.id.poll_comments_list);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
mPollCommentsList.setLayoutManager(llm);
mPollCommentsList.setHasFixedSize(true);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
mUpdateRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
setImage(dataSnapshot);
setQuestion(dataSnapshot);
createInitialCommentIDArray(dataSnapshot);
mNumberOfCommentsAtPoll = (int) dataSnapshot.child(COMMENTS_LABEL).getChildrenCount();
for (int i = 0; i < mNumberOfCommentsAtPoll; i++) {
String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("COMMENT").getValue();
Log.v("COMMENT_ID", "The comment ID is " + commentID);
String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("USER_ID").getValue();
Log.v("USER_ID", "The user ID is " + userID);
mCommentArrayList.add(0, new Comments(mUserAvatar, userID, commentID));
mCommentAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
mCommentAdapter = new MyAdapter(mCommentArrayList);
mPollCommentsList.setAdapter(mCommentAdapter);
Intent intent = getIntent();
String pollID = intent.getStringExtra("POLL_ID");
mPollIndex = intent.getIntExtra("POLL_INDEX", 0);
//TODO: Store unique comment ID's in an array
//TODO: Figure out how to programmatically add images to AWS and then store URL in Firebase
ImageView fab = (ImageView) findViewById(R.id.add_comment);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
HashMap<String, Object> commentMap = new HashMap<String, Object>();
commentMap.put("USER_ID", mBaseRef.getAuth().getUid());
commentMap.put("COMMENT", mUserComment.getText().toString());
mUpdateRef.child(COMMENTS_LABEL).push().updateChildren(commentMap);
hideKeyboard(view);
mUserComment.setText("");
Toast.makeText(getApplicationContext(), R.string.comment_added, Toast.LENGTH_LONG).show();
}
});
}
My Array Adapter, I note where the error is occurring:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<Comments> mDataSet;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
protected ImageView userAvatar;
protected TextView userID;
protected TextView userComment;
public ViewHolder(View v) {
super(v);
userAvatar = (ImageView) findViewById(R.id.profile_image_avatar);
userID = (TextView) findViewById(R.id.user_ID);
userComment = (TextView) findViewById(R.id.user_comment);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<Comments> myDataset) {
mDataSet = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.individual_comment, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder x = new ViewHolder(v);
return x;
}
// Replace the contents of a view (invoked by the layout manager)
//The OutOfBoundsException is pointing here
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.userComment.setText(mCommentArrayList.get(position).getUserComment());
String x = mCommentArrayList.get(position).getUserComment();
Log.v("ON_BIND_VIEW", "THE STRING IS " + x);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mNumberOfCommentsAtPoll;
}
}
Result:
You should try to return mDataset.size() in the getItemCount() method instead of mNumberOfCommentsAtPoll.
#Override
public int getItemCount() {
return mDataSet.size();
}
Related
I building an app to practice in arraylist and recyclerView.
In the main activity I have "Add" button than I can add things to the arraylit to display in the recyclerView,However,the first time I add new line its working fine,but when I try to add another one,its replacing the first line I added with the new line.
I will be glad if you can point what am I doing wrong,Thank you.
Add Line Activity:
public void AddButton(View view){
if (imageUri != null && !mEditText.getText().toString().isEmpty()){
Intent intent = new Intent(AddCompany.this,MainActivity.class);
intent.putExtra("isAddNewCompany", true);
intent.putExtra("CompanyImage", imageUri.toString());
intent.putExtra("CompanyName", mEditText.getText().toString());
startActivity(intent);
}
}
MainActivity OnCreate with the views:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
ArrayList<String> listTitle = new ArrayList<>();
ArrayList<String> listPicture = new ArrayList<>();
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
listTitle.add(companyName);
listPicture.add(CompanyImage);
}
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerAdapter adapter = new RecyclerAdapter(this,listPicture,listTitle);
adapter.setClickListener(new RecyclerAdapter.ItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.e("Position Number - ", String.valueOf(position));
Toast.makeText(MainActivity.this, adapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(adapter);
}
RecyclerView Adapter:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private final ArrayList<String> mData;
private final ArrayList<String> mImageView;
private final LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
RecyclerAdapter(Context context, ArrayList<String> imageView, ArrayList<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.mImageView = imageView;
}
// inflates the row layout from xml when needed
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
String picture = mImageView.get(position);
Picasso.get().load(picture).into(holder.myImageView);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ImageView myImageView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.tvAnimalName);
myImageView = itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
When you start activity ,every time new list instance will be created that's why you got only one value.if you want already added value, use same list instance.
List<String> listTitle;
List<String> listPicture;
public List<String> getLisPictureInstance(){
if(listPicture ==null)
listPicture = new ArrayList<>();
return listPicture ;
}
public List<String> getListTitleInstance(){
if(listTitle ==null)
listTitle = new ArrayList<>()
return listTitle ;
}
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
getListTitleInstance().add(companyName);
getLisPictureInstance().add(CompanyImage);
}
recyclerView = findViewById(R.id.recyclerView);
database = FirebaseDatabase.getInstance();
reference_root = database.getReference("/image");
reference_grocery_and_staples = database.getReference("image/Grocery & Staples");
reference_beverages = database.getReference("image/Beverages");
reference_home_and_kitchen = database.getReference("image/Home & Kitchen");
reference_furnishing_and_home_needs = database.getReference("image/Furnishing & Home Needs");
reference_household_needs = database.getReference("image/Household Needs");
reference_personal_care = database.getReference("image/Personal Care");
reference_breakfast_and_dairy = database.getReference("image/Breakfast & Dairy");
reference_biscuits_snacks_and_chocolates = database.getReference("image/Biscuits, Snacks & Chocolates");
reference_noodles_sauces_and_instant_food = database.getReference("image/Noodles, Sauces & Instant Food");
reference_baby_and_kids = database.getReference("image/Baby & Kids");
reference_pet_care = database.getReference("image/Pet Care");
reference_frozen_food = database.getReference("image/Frozen Food");
reference_vegetables = database.getReference("image/Vegetables");
layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
final ArrayList<DatabaseReference> reference = new ArrayList<>();
reference.add(reference_grocery_and_staples);
reference.add(reference_beverages);
reference.add(reference_home_and_kitchen);
reference.add(reference_furnishing_and_home_needs);
reference.add(reference_household_needs);
reference.add(reference_personal_care);
reference.add(reference_breakfast_and_dairy);
reference.add(reference_biscuits_snacks_and_chocolates);
reference.add(reference_noodles_sauces_and_instant_food);
reference.add(reference_baby_and_kids);
reference.add(reference_pet_care);
reference.add(reference_frozen_food);
reference.add(reference_vegetables);
for(int i = 0; i < 13; i++) {
FirebaseRecyclerOptions<ImageModel> options = new FirebaseRecyclerOptions
.Builder<ImageModel>()
.setQuery(reference.get(i), ImageModel.class)
.build();
adapter = new FirebaseRecyclerAdapter<ImageModel, HomePage.ImageHolder>(options) {
#NonNull
#Override
public HomePage.ImageHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater
.from(HomePage.this)
.inflate(R.layout.row_layout, parent, false);
HomePage.ImageHolder holder = new HomePage.ImageHolder(view);
return holder;
}
#Override
protected void onBindViewHolder(#NonNull HomePage.ImageHolder holder, int position, #NonNull final e.shweta.authenticationdemo.ImageModel model) {
String url = model.getProductURL();
String name = model.getProductName();
String price = model.getProductPrice();
String descritpion = model.getProductDescription();
holder.textView1.setText(name);
holder.textView2.setText("Price: Rs. " + price);
Picasso.get()
.load(url)
.into(holder.imageView);
holder.linearLayoutRowLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(HomePage.this, e.shweta.authenticationdemo.ProductInfo.class);
intent.putExtra("productImage", model.getProductURL());
intent.putExtra("productName", model.getProductName());
intent.putExtra("productPrice", model.getProductPrice());
intent.putExtra("productDescription", model.getProductDescription());
startActivity(intent);
}
});
}
#Override
public void onDataChanged() {
super.onDataChanged();
adapter.notifyDataSetChanged();
}
};
}
recyclerView.setAdapter(adapter);
I want to show the data of all the children in my home page. I have tried to loop the references to the children. But what it is doing is putting the data of only the final loop to the page. I guess it is doing it because it is updating the view every time.
It is only showing me the data of the final loop, i.e the vegetables i want the data on my homepage of every child.
You need to structure your data differently. Add another field like productType which can be beverages, biscuits etc. If you are ready to do this then just create a class Product.java:
public class Product {
private String productName, productPrice;//etc
//add setters and getters
}
To get data and update recycler view
private List<Product> productList;
productList = new ArrayList<>();
mRef = database.getReference().child(); //path
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> productData = dataSnapshot.getChildren();
for(DataSnapshot d : productData){
Product product = d.getValue(Product.class);
if(product.getProductType() == "Beverages"){ //getProductType() is the getter from Product.java
productList.add(product);
recyclerAdapter.notifyDataSetChanged();
}
//Now only beverages are added to recycler view
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Pass the List item to the adapter
recyclerAdapter = new mRecyclerAdapter(getContext(), productList);
modify your adapter constructor to accept these values
This is the edited version of my Fragment class inside my main activity. There were some bugs- it was not displaying anything and it was no longer saving the data to the database.
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
DatabaseReference mDatabaseGig;
final List<Dessert> dessertList;
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
}
DessertAdapter adapter = new DessertAdapter(getContext());
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}
I already got the saving to firebase working perfectly and I'm using the MVC model - I created an adapter, a model and wired it to the main activity but my problem is how to use this model into the onAddValueEventChangedListener();
public class DessertAdapter extendsRecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts = new ArrayList<>();
private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
private static final int VIEW_TYPE_OBJECT_VIEW = 1;
private Context context;
// TODO: placeholder stuff here
#Override
public int getItemViewType(int position) {
if (desserts.isEmpty()) {
return VIEW_TYPE_EMPTY_LIST_PLACEHOLDER;
} else {
return VIEW_TYPE_OBJECT_VIEW;
}
}
public DessertAdapter(Context context) {
this.context = context;
this.desserts = desserts;
desserts = Dessert.prepareDesserts(
context.getResources().getStringArray(R.array.dessert_names),
context.getResources().getStringArray(R.array.dessert_descriptions),
context.getResources().getStringArray(R.array.dessert_amounts));
}
// TODO: another placeholder stuff here
#Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_dessert, parent, false);
return new DessertAdapter.DessertVh(view);
}
#Override
public void onBindViewHolder(DessertVh holder, int position) {
Dessert dessert = desserts.get(position);
holder.mName.setText(dessert.getName());
holder.mDescription.setText(dessert.getDescription());
holder.mFirstLetter.setText(String.valueOf(dessert.getFirstLetter()));
holder.mPrice.setText(String.valueOf(dessert.getAmount()));
}
#Override
public int getItemCount() {
// if nothing, return null,
// else return the number of items in the list
return desserts == null ? 0 : desserts.size();
}
public static class DessertVh extends RecyclerView.ViewHolder {
private TextView mName;
private TextView mPrice;
private TextView mDescription;
private TextView mFirstLetter;
public DessertVh(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.txt_name);
mPrice = (TextView) itemView.findViewById(R.id.txt_price);
mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
}
}
}
main activity where the tabs are displayed
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs_header);
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this , this )
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
This handles the display of the data
#Override
public void onStart(){
super.onStart();
mFirebaseAuth.addAuthStateListener(firebaseAuthListener);
// load the data from database here
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
}
// maybe this will work?
DummyFragment dummyFragment = new DummyFragment();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
some code missing here but still part of mainactivity
This is the Dummy Fragment Class inside the main activity
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
// possible to put progress dialogue
DessertAdapter adapter = new DessertAdapter(getContext());
recyclerView.setAdapter(adapter);
return view;
}
}
Put the Firebase code inside the Fragment, not the Activity and also pass the dessertList as a param to the DessertAdapter.
Example:
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
DatabaseReference mDatabaseGig;
final List<Dessert> dessertList;
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
DessertAdapter adapter = new DessertAdapter(getContext(), dessertList);
recyclerView.setAdapter(adapter);
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}
I want to display number of total items of my recyclerview in a textview. If new item is added or deleted that textview should be update. And also calculate total price of items in a list of Items in a recyclerview and display in a textview below recyclerview list.
Below is my recyclerview adapter:
public class CartAdapter extends RecyclerView.Adapter<CartAdapter.ViewHolder> {
private List<ProductView.Data> productData = Collections.emptyList();
static List<ProductModel> productModelList;
static Context context;
DatabaseHandler mDatabaseHandler;
public CartAdapter(Context context, List<ProductModel> dbList ){
this.productModelList = new ArrayList<ProductModel>();
this.context = context;
this.productModelList = dbList;
mDatabaseHandler = new DatabaseHandler( context );
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View cartListView = inflater.inflate(R.layout.list_item_cart, parent, false);
// Return a new holder instance
ViewHolder viewHolder = new ViewHolder(context,cartListView);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.tvProductName.setText(productModelList.get(position).getTitle());
holder.tvProductPrice.setText(productModelList.get(position).getPrice());
Glide
.with(context)
.load(productModelList.get(position).getImageUrl())
.into(holder.imgProduct);
// holder.tvProductStatus.setText(productModelList.get(position).getIsAvailable());
holder.tvSize.setText(productModelList.get(position).getSize());
holder.tvProductQuantity.setText(Integer.toString(productModelList.get(position).getQuantity()));
holder.tvColor.setText(productModelList.get(position).getColor());
//holder.tvMaterial.setText(productModelList.get(position).getMaterial());
holder.imgDelete.setClickable(true);
holder.imgDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String idForDelete = String.valueOf(productModelList.get(position).getVariantId());
mDatabaseHandler.deleteARow(idForDelete);
productModelList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,productModelList.size());
}
});
}
#Override
public int getItemCount() {
return productModelList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvProductName, tvProductPrice, tvProductQuantity,tvColor,
tvSize;
ImageView imgProduct;
ImageButton imgDelete;
Context context;
public ViewHolder(Context mContext, View itemView) {
super(itemView);
this.tvProductName = (TextView) itemView.findViewById(R.id.tv_cart_product_name);
this.tvProductPrice = (TextView) itemView.findViewById(R.id.tv_cart_product_price);
this.tvProductQuantity = (TextView) itemView.findViewById(R.id.tv_cart_product_Quantity);
this.imgProduct = (ImageView) itemView.findViewById(R.id.img_cart_item_product);
this.tvColor = (TextView)itemView.findViewById(R.id.tv_color);
this.tvSize = (TextView) itemView.findViewById(R.id.tv_size);
this.imgDelete = (ImageButton) itemView.findViewById(R.id.img_cart_delete);
// store the context ///
this.context = mContext;
}
}
and java Class:
public class CartActivity extends AppCompatActivity {
DatabaseHandler helper;
List<ProductModel> dbList;
RecyclerView mRecyclerView;
Toolbar toolbar;
Button btnCheckout, btnContinueShopping;
TextView tvTotalNoOfItems, tvTotalPrice;
String p;
String i;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
p = getIntent().getStringExtra("variant_id");
i = getIntent().getStringExtra("product_id");
Bundle extras = getIntent().getExtras();
if (extras != null) {
p = extras.getString("variant_id");
i= extras.getString("product_id");
}
toolbar = (Toolbar) findViewById(R.id.customToolBar);
setSupportActionBar(toolbar);
setTitle("Check-out");
toolbar.setTitleTextColor(Color.BLACK);
toolbar.setNavigationIcon(R.drawable.ic_arrow_back_black);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
helper = new DatabaseHandler(this);
dbList= new ArrayList<ProductModel>();
dbList = helper.getDataFromDB();
mRecyclerView = (RecyclerView)findViewById(R.id.rv_cart_item_list);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new CartAdapter(this,dbList);
mRecyclerView.setAdapter(mAdapter);
tvTotalNoOfItems = (TextView)findViewById(R.id.tvTotalCartItems);
tvTotalPrice = (TextView)findViewById(R.id.tvTotalCartItemsPrice);
String totalPrice = "";
for (int i = 0; i<dbList.size(); i++)
{
totalPrice = totalPrice + dbList.get(i).getPrice().toString();
}
tvTotalPrice.setText(totalPrice);
btnContinueShopping = (Button)findViewById(R.id.btnBackToProductActivity);
btnContinueShopping.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent launchCOllectionActivity = new Intent(CartActivity.this, CollectionActivity.class);
startActivity(launchCOllectionActivity);
finish();
}
});
btnCheckout = (Button)findViewById(R.id.btn_checkout);
btnCheckout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent launchCheckoutActivity = new Intent(CartActivity.this,CheckoutActivity.class);
startActivity(launchCheckoutActivity);
}
});
}
}
First, add following getter to your adapter:
public List<ProductModel> getItems(){
return productModelList;
}
Then, you can subscribe on adapter data change and do the following:
mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onChanged () {
tvTotalNoOfItems.setText(mAdapter.getItemCount());
String totalPrice = "";
for (int i = 0; i < ((CartAdapter)mAdapter).getItems().size(); i++) {
totalPrice = totalPrice + ((CartAdapter)mAdapter).getItems().get(i).getPrice().toString();
}
tvTotalPrice.setText("" + totalPrice);
}
});
just add this line below the adapter set line
tvTotalNoOfItems.setText(mAdapter.getCount());
and add this into you adapter class where you delete action perform
String totalPrice = "";
((CartActivity)context).tvTotalNoOfItems.setText(getCount());
for (int i = 0; i<productModelList.size(); i++)
{
totalPrice = totalPrice + productModelList.get(i).getPrice().toString();
}
((CartActivity)context).tvTotalPrice.setText(""+totalPrice);
Just public you textview like this
public TextView tvTotalNoOfItems, tvTotalPrice;
i have a recyclerView where i added some sections using this library
and my RecyclerView is now looking like this
as you can see that my data is not organised yet, right now my data is on this form :
Section 2015
2016-05-03
2016-04-03
2015-12-03
Section 2016
2016-05-03
2016-04-03
2015-12-03
i want it to be like :
Section 2015
2015-12-03
Section 2016
2016-05-03
2016-04-03
as you can see i want to manage the data according to their value and section's value
this is my MainAdapter Class:
public class MainAdapter extends SectionedRecyclerViewAdapter<MainAdapter.MainVH> {
Context context;
LayoutInflater inflater;
List<Data> dataArray = Collections.emptyList();
ArrayList<String> data;
ArrayList<String > sectionData;
public MainAdapter(Context context ,ArrayList<String> data , ArrayList<String> sectionData ){
inflater = LayoutInflater.from(context);
this.context = context;
this.data = data;
this.sectionData = sectionData;
}
#Override
public int getSectionCount() {
return sectionData.size(); // number of sections.
}
#Override
public int getItemCount(int section) {
return data.size(); // odd get 8
// return 8; // number of items in section (section index is parameter).
}
#Override
public void onBindHeaderViewHolder(MainVH holder, int section) {
// Setup header view.
String current = sectionData.get(section);
holder.title.setText(current);
}
#Override
public void onBindViewHolder(MainVH holder, int section, int relativePosition, int absolutePosition) {
// Setup non-header view.
// 'section' is section index.
// 'relativePosition' is index in this section.
// 'absolutePosition' is index out of all non-header items.
// See sample project for a visual of how these indices work.
if (data.get(relativePosition).contains("2015")){
Toast.makeText(context , "it contains 2015",Toast.LENGTH_SHORT).show();
}
String currentRow = data.get(relativePosition);
holder.title.setText(currentRow);
// holder.title.setText(String.format("S:%d, P:%d, A:%d", section, relativePosition, absolutePosition));
}
#Override
public int getItemViewType(int section, int relativePosition, int absolutePosition) {
if (section == 1)
return 0; // VIEW_TYPE_HEADER is -2, VIEW_TYPE_ITEM is -1. You can return 0 or greater.
return super.getItemViewType(section, relativePosition, absolutePosition);
}
#Override
public MainVH onCreateViewHolder(ViewGroup parent, int viewType) {
// Change inflated layout based on 'header'.
int layout;
switch (viewType) {
case VIEW_TYPE_HEADER:
layout = R.layout.section;
break;
case VIEW_TYPE_ITEM:
layout = R.layout.row;
break;
default:
Toast.makeText(context,"Default",Toast.LENGTH_SHORT).show();
break;
}
View v = LayoutInflater.from(parent.getContext())
.inflate(viewType == VIEW_TYPE_HEADER ? R.layout.section : R.layout.row, parent, false);
return new MainVH(v);
}
public static class MainVH extends RecyclerView.ViewHolder {
final TextView title;
public MainVH(View itemView) {
super(itemView);
// Setup view holder.
// You'd want some views to be optional, e.g. for header vs. normal.
title = (TextView) itemView.findViewById(R.id.TV);
}
}
}
and this is my MainActivity :
public class MainActivity extends AppCompatActivity {
MainAdapter mainAdapter;
RecyclerView recyclerView;
ArrayList<String> mData;
ArrayList<String > mDataSection,RawmDataSection;
ArrayList<Data> managedDataArray;
HashMap hMap;
ArrayList<ArrayList<String>> organizedData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mData = new ArrayList<String>();
mDataSection = new ArrayList<String>();
RawmDataSection = new ArrayList<String>();
hMap = new HashMap();
managedDataArray = new ArrayList<Data> ();
organizedData = new ArrayList<ArrayList<String>>();
mData.add("2016-05-3");
mData.add("2016-04-3");
mData.add("2016-02-3");
mData.add("2015-12-3");
for (int i = 0 ; i<mData.size() && i<mData.size() ; i++ ){
//spilting the data
String string = mData.get(i);
String[] parts = string.split("-");
String part1 = parts[0];
String part2 = parts[1];
String part3 = parts[2];
RawmDataSection.add(part1);
}
Set<String> uniqueSet = new HashSet<String>(RawmDataSection);
mDataSection.addAll(uniqueSet);
final List<Data> data = new ArrayList<>();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "ReFreshing", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Data dataObject = new Data();
for (int i = 0; i < mData.size(); i++) {
dataObject.RowMonth = mData.get(i);
Log.d("row :" + mData.get(i), " Section : ");
data.add(dataObject);
}
for (int i = 0; i < mDataSection.size(); i++) {
dataObject.SectionYear = mDataSection.get(i);
Log.d("row :", " Section : " + mDataSection.get(i));
data.add(dataObject);
}
recyclerView = (RecyclerView) findViewById(R.id.List);
MainAdapter adapter = new MainAdapter(MainActivity.this, mData, mDataSection);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
recyclerView.setHasFixedSize(true);
organizedData.add(mDataSection);
organizedData.add(mData);
}
});
}
}
i even don't know where to start so if any body can give me any hint or guidance than it'll be so helpful and highly appreciated by me , thanks
if my question is not understandable then please let me know i'll fix it
You can achieve that in a simpler way with the library SectionedRecyclerViewAdapter.
First create a Section class to group your items:
class MySection extends StatelessSection {
String title;
List<String> list;
public MySection(String title, List<String> list) {
// call constructor with layout resources for this Section header, footer and items
super(R.layout.section_header, R.layout.section_item);
this.title = title;
this.list = list;
}
#Override
public int getContentItemsTotal() {
return list.size(); // number of items of this section
}
#Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
// return a custom instance of ViewHolder for the items of this section
return new MyItemViewHolder(view);
}
#Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
MyItemViewHolder itemHolder = (MyItemViewHolder) holder;
// bind your view here
itemHolder.tvItem.setText(list.get(position));
}
#Override
public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
return new SimpleHeaderViewHolder(view);
}
#Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
MyHeaderViewHolder headerHolder = (MyHeaderViewHolder) holder;
// bind your header view here
headerHolder.tvItem.setText(title);
}
}
Then you set up the RecyclerView with your Sections:
// Create an instance of SectionedRecyclerViewAdapter
SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter();
// Create your sections with the list of data for each year
MySection section2015 = new MySection("2015", dataList2015);
MySection section2016 = new MySection("2016", dataList2016);
// Add your Sections to the adapter
sectionAdapter.addSection(section2015);
sectionAdapter.addSection(section2016);
// Set up your RecyclerView with the SectionedRecyclerViewAdapter
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(sectionAdapter);