I am following g this tutorial https://inducesmile.com/android/android-recyclerview-and-cardview-in-material-design-tutorial/
My previous app file had it so the spinners were populated by a csv file. Now I am just making another app file because I wanted to start again by using cardviews and recyclerview.
However I am having some trouble with trying to implement my previous spinner code into this new app file using recycler views and cardviews.
The Example linked above calls for a class called ItemObject.java. I assum ed this is where I put the code that reads the csv.
ItemObject class
public class ItemObject {
Spinner spinner;
public void setText(String spinner) {
private Map<String, String> numberItemValues = new HashMap<>();
private class CSVFile {
InputStream inputStream;
public CSVFile(InputStream inputStream) {
this.inputStream = inputStream;
}
public List<String> read() {
List<String> resultList = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] row = line.split(",");
//TODO I edited this part so that you'd add the values in our new hash map variable
numberItemValues.put(row[1], row[0]);
resultList.add(row[1]);
}
} catch (IOException e) {
Log.e("Main", e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
Log.e("Main", e.getMessage());
}
}
return resultList;
}
}
}
}
Then the example calls for a RecyclerViewAdatper. I am confused what to put in the OnBindViewHolder part. What is suppose to go in there, to do with my spinner?
RecyclerViewAdapter class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
private List<ItemObject> itemList;
private Context context;
public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
this.itemList = itemList;
this.context = context;
}
#Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_products, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
return rcv;
}
#Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) {
// **WHAT TO PUT HERE**
//holder.countryPhoto.setImageResource(itemList.get(position).getPhoto());
}
#Override
public int getItemCount() {
return this.itemList.size();
}
}
And here is the RecyclerViewHolders class just for anyones reference.
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView countryName;
public ImageView countryPhoto;
public Spinner spinner;
public TextView textView5;
public CheckBox checkBox;
public EditText editText;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
/* countryName = (TextView)itemView.findViewById(R.id.country_name);
countryPhoto = (ImageView)itemView.findViewById(R.id.country_photo);*/
spinner = (Spinner)itemView.findViewById(R.id.spinner);
textView5 = (TextView)itemView.findViewById(R.id.textView5);
checkBox = (CheckBox)itemView.findViewById(R.id.checkBox);
editText = (EditText)itemView.findViewById(R.id.editText);
}
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Clicked Country Position = " + getPosition(), Toast.LENGTH_SHORT).show();
}
}
You can pass CSV values in an String Array form to your recyleview adpater constructor. You can use these values to populate your spinner something like this
String [] spinnerValues;
public RecyclerViewAdapter(Context context, List<ItemObject> itemList, String [] spinnerValues) {
this.itemList = itemList;
this.context = context;
this.spinnerValues = spinnerValues
}
Make View Holder class a inner class in your adapter and use below code.
spinner = (Spinner)itemView.findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_spinner_item, YOUR_STRING_ARRAY);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
Related
I have it so, when the user presses the fab, a cardview is added to the recyclerview layout. Inside each cardview that the user adds, is a spinner, checkbox edittext and textview. The spinner is populated by the first column in a csv file. The first column has item names, the second column has specific numbers relating to that product some of which can be the same
i had a previous similar app where when the user selects an item from the spinner, the coressponding number from the csv file shows in the textview. However that was without the recyclerviews or cardviews so I am trying to implement it in my code now (with recyclerview and cardviews)
However as I've been trying to implmenent that code in my current ProductAdapter (recyclerviewadapter) Code I have got an error:
Compilation Errors:
error: cannot find symbol method getResources()
It comes from this chunk of code
InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
CSVFile csvFile = new CSVFile(inputStream);
final List<String> mSpinnerItems = csvFile.read();
Here is my full ProductAdapter.java code
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
private Map<Integer, Integer> mSpinnerSelectedItem = new HashMap<Integer, Integer>();
private Map<String, String> numberItemValues = new HashMap<>();
private SearchableSpinner spinner;
//we are storing all the products in a list
private List<Product> productList;
private Activity create;
//TODO CODE FOR CSV FILE
/*InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
CSVFile csvFile = new CSVFile(inputStream);
final List<String> mSpinnerItems = csvFile.read();*/
InputStream inputStream = null;
List<String> mSpinnerItems = null;
CSVFile csvFile = null;
//TODO END OF CODE FOR CSV FILE
public ProductAdapter(Activity activity) {
create = activity;
}
//getting the context and product list with constructor
public ProductAdapter(Activity activity, List<Product> productList) {
// this.mCtx = mCtx;
/* inputStream = create.getResources().openRawResource(R.raw.shopitems);
csvFile = new CSVFile(inputStream);
mSpinnerItems = csvFile.read();*/
create = activity;
this.productList = productList;
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(create);
View view = inflater.inflate(R.layout.layout_products, null);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(final ProductViewHolder holder, final int position) {
// //getting the product of the specified position
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(create, R.layout.item_spinner_layout,
Product.getSpinnerItemsList());
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.spinner.setAdapter(spinnerArrayAdapter);
holder.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int mPosition, long id) {
mSpinnerSelectedItem.put(position, mPosition);
TextView mTextView = view.findViewById(R.id.mSpinnerText);
//TODO CODE FOR GETTING AISLE NUMBER AND PUTTING IT IN THE TEXTVIEW
String currentItem = mSpinnerItems.get(position);
String aisleNumber = numberItemValues.get(currentItem);
holder.textView5.setText(aisleNumber);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
//binding the data with the viewholder views
if (mSpinnerSelectedItem.containsKey(position)) {
holder.spinner.setSelection(mSpinnerSelectedItem.get(position));
}
holder.getView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(create);
// set title
alertDialogBuilder.setTitle("Delete Item");
// set dialog message
alertDialogBuilder
.setMessage("Are you sure you want to delete this item?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, close
// current activity
holder.checkBox.setChecked(false);
holder.spinner.setSelection(0);
productList.remove(holder.getAdapterPosition());
notifyItemRemoved(holder.getAdapterPosition());
Toast.makeText(create, "Item removed.", Toast.LENGTH_LONG).show();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
});
}
#Override
public int getItemCount() {
return productList.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
SearchableSpinner spinner;
EditText editText;
TextView textView5;
CheckBox checkBox;
LinearLayout linearLayout;
View rootView;
public ProductViewHolder(View itemView) {
super(itemView);
spinner = itemView.findViewById(R.id.spinner);
editText = itemView.findViewById(R.id.editText);
textView5 = itemView.findViewById(R.id.textView5);
checkBox = itemView.findViewById(R.id.checkBox);
rootView = itemView.findViewById(R.id.linearLayout);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// makes the set disappear when checkbox is ticked.
if(isChecked){
checkBox.setChecked(false);
spinner.setSelection(0);
productList.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
Toast.makeText(create, "Done!", Toast.LENGTH_LONG).show();
}
}
});
}
public View getView() {
return rootView;
}
}
//TODO CODE FOR CSV FILE
private class CSVFile {
InputStream inputStream;
public CSVFile(InputStream inputStream) {
this.inputStream = inputStream;
}
public List<String> read() {
List<String> resultList = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] row = line.split(",");
numberItemValues.put(row[1], row[0]);
resultList.add(row[1]);
}
} catch (IOException e) {
Log.e("Main", e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
Log.e("Main", e.getMessage());
}
}
return resultList;
}
}
}
create.java code which is my mainactivity where the cards are added and the fab is etc
public class create extends AppCompatActivity {
//a list to store all the products
List<Product> productList;
//the recyclerview
RecyclerView recyclerView;
Product mProduct;
private Map<String, String> numberItemValues = new HashMap<>();
private Map<Integer, Integer> mSpinnerSelectedItem = new HashMap<Integer, Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create);
//opens csv
InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
CSVFile csvFile = new CSVFile(inputStream);
final List<String> mSpinnerItems = csvFile.read();
//getting the recyclerview from xml
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//initializing the productlist
productList = new ArrayList<>();
productList.add(new Product(mSpinnerItems, "Test Edit Text",false, "Text String 2"));
final ProductAdapter adapter = new ProductAdapter(this, productList);
//TODO FAB BUTTON
FloatingActionButton floatingActionButton =
findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
productList.add(mProduct);
if(adapter != null)
adapter.notifyDataSetChanged();
//Handle the empty adapter here
}
});
//setting adapter to recyclerview
recyclerView.setAdapter(adapter);
}
private class CSVFile {
InputStream inputStream;
public CSVFile(InputStream inputStream) {
this.inputStream = inputStream;
}
public List<String> read() {
List<String> resultList = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] row = line.split(",");
//TODO I edited this part so that you'd add the values in our new hash map variable
numberItemValues.put(row[1], row[0]);
resultList.add(row[1]);
}
} catch (IOException e) {
Log.e("Main", e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
Log.e("Main", e.getMessage());
}
}
return resultList;
}
}
}
The adapter has know idea about getResources(). This needs to come from an Activity or Context object. So do this:
InputStream inputStream = null;
List<String> mSpinnerItems = null;
CSVFile csvFile = null;
then in your public ProductAdapter() method initialize the InputStream properly.
public ProductAdapter(Activity activity, List<Product> productList) {
create = activity;
//INFO:: Now initialize the InputStream
inputStream = create.getResources().openRawResource(R.raw.shopitems);
csvFile = new CSVFile(inputStream);
mSpinnerItems = csvFile.read();
this.productList = productList;
}
Of course you could create a string-array resource and fill the spinner view with that.
<string-array name="my_values">
<item>Hello</item>
<item>World</item>
<item>Back</item>
<item>Again</item>
</string-array>
Then in the layout file:
<Spinner
android:id="#+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:entries="#array/my_values"
/>
.
EDIT
With the updated code you can remove:
InputStream inputStream = null;
List<String> mSpinnerItems = null;
CSVFile csvFile = null;
From the ProductAdapter.
The NullPointerException error occurring at line:
String currentItem = mSpinnerItems.get(position);
is caused because mSpinnerItems is no longer being used and is set to null. So, in order to get the value of the selection in the spinner do this:
holder.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int mPosition, long id) {
mSpinnerSelectedItem.put(position, mPosition);
TextView mTextView = view.findViewById(R.id.mSpinnerText);
//TODO CODE FOR GETTING AISLE NUMBER AND PUTTING IT IN THE TEXTVIEW
//SearchableSpinner spinner = (SearchableSpinner)view;
String currentItem = holder.spinner.getItemAtPosition(mPosition).toString();
// or try
// spinner.getAdapter.getItem(mPosition).toString();
String aisleNumber = numberItemValues.get(currentItem);
holder.textView5.setText(aisleNumber);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
.
NEW EDIT:
in the ProductAdapter use this:
public ProductAdapter(Activity activity, List<Product> productList, HashMap<String, String> numberList) {
numberItemValues = numberList;
create = activity;
this.productList = productList;
}
and change this line in the "create" Activity:
final ProductAdapter adapter = new ProductAdapter(this, productList, numberItemValues);
I have been following this tutorial right through with a few minor adjustments for my own use: Android RecyclerView and CardView Tutorial
(The point of my app is when you press the fab, a cardview appears. Inside each cardview is a spinner, edittext, textview and checkbox.)
However I need to finally add some code into the FAB so that a cardview is added. But I am unsure how to do this with all I have done with adapters. the tutorial asked me to do productList = new ArrayList<>(); and so I could use productList.add but I don't know how to go on from there.
Here is the snippet of my main activity code:
FloatingActionButton floatingActionButton =(FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
productList.add //what goes here???//
}
});
And this is my current create.java code (which the above snippet is in)
public class create extends AppCompatActivity {
//a list to store all the products
List<Product> productList;
//the recyclerview
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create);
//opens csv
InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
CSVFile csvFile = new CSVFile(inputStream);
Product.spinnerItemsList = csvFile.read();
//getting the recyclerview from xml
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//initializing the productlist
productList = new ArrayList<>();
//TODO FAB BUTTON
FloatingActionButton floatingActionButton =
(FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
productList.add //what goes here???//
}
});
//creating recyclerview adapter
ProductAdapter adapter = new ProductAdapter(this, productList);
//setting adapter to recyclerview
recyclerView.setAdapter(adapter);
}
private class CSVFile {
InputStream inputStream;
public CSVFile(InputStream inputStream) {
this.inputStream = inputStream;
}
public List<String> read() {
List<String> resultList = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] row = line.split(",");
//TODO I edited this part so that you'd add the values in our new hash map variable
/*
numberItemValues.put(row[1], row[0]);
*/
resultList.add(row[1]);
}
} catch (IOException e) {
Log.e("Main", e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
Log.e("Main", e.getMessage());
}
}
return resultList;
}
}
}
This is MyListAdapter.java which is for the Spinner.
public class MyListAdapter extends ArrayAdapter<String> {
int groupid;
List<String> items;
Context context;
String path;
public MyListAdapter(Context context, int vg, int id, List<String> items) {
super(context, vg, id, items);
this.context = context;
groupid = vg;
this.items = items;
}
static class ViewHolder {
public TextView textid;
public TextView textname;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
{
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(groupid, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.textid = (TextView) rowView.findViewById(R.id.txtid);
viewHolder.textname = (TextView) rowView.findViewById(R.id.txtname);
rowView.setTag(viewHolder);
}
// Fill data in the drop down.
ViewHolder holder = (ViewHolder) rowView.getTag();
String row = items.get(position);
//holder.textid.setText(row[0]); //prints aisle number, dont need
holder.textname.setText(row);
return rowView;
}
}
}
This is Product.Java from tutorial
public class Product {
private String editText;
private Boolean checkBox;
private String textView5;
public static List<String> spinnerItemsList = new ArrayList<String>();
public Product(List spinner, String editText, Boolean checkBox, String textView5) {
this.editText = editText;
this.checkBox = checkBox;
this.textView5 = textView5;
}
public String getEdittext () {
return editText;
}
public boolean getCheckbox () {
return checkBox;
}
public String getTextview () {
return textView5;
}
}
And this is ProductAdapter.java also from tutorial
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
//this context we will use to inflate the layout
private Context mCtx;
private Spinner spinner;
//we are storing all the products in a list
private List<Product> productList;
//getting the context and product list with constructor
public ProductAdapter(Context mCtx, List<Product> productList) {
this.mCtx = mCtx;
this.productList = productList;
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.layout_products, null);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
//getting the product of the specified position
Product product = productList.get(position);
//binding the data with the viewholder views
MyListAdapter adapter = new MyListAdapter(mCtx, R.layout.listrow, R.id.txtid, Product.spinnerItemsList);
spinner.setAdapter(adapter);
}
#Override
public int getItemCount() {
return productList.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
Spinner spinner;
EditText editText;
TextView textView5;
CheckBox checkBox;
public ProductViewHolder(View itemView) {
super(itemView);
spinner = itemView.findViewById(R.id.spinner);
editText = itemView.findViewById(R.id.editText);
textView5 = itemView.findViewById(R.id.textView5);
checkBox = itemView.findViewById(R.id.checkBox);
}
}
}
I've done the same xml stuff as the tutorial fyi.
EDIT
final Spinner spinner;
final EditText editText;
final CheckBox checkBox;
final TextView textView5;
spinner = findViewById(R.id.spinner);
editText = findViewById(R.id.editText);
checkBox = findViewById(R.id.checkBox);
textView5 = findViewById(R.id.textView5);
final ProductAdapter adapter = new ProductAdapter(this, productList);
//TODO FAB BUTTON
FloatingActionButton floatingActionButton =
(FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Product mProduct = new Product(List spinner, String editText, Boolean checkBox, String textView5);
productList.add(mProduct); //what goes here???//
if(adapter != null)
adapter.notifyDataSetChanged();
//Handle the empty adapter here
}
});
layout_products.xml
<?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="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<Spinner
android:id="#+id/spinner"
android:layout_width="159dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true" />
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="36dp" />
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="89dp"
android:text="TextView" />
<EditText
android:id="#+id/editText"
android:layout_width="34dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:ems="10"
android:inputType="number" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Change your Product Model with the following
public class Product {
private String editText;
private Boolean checkBox;
private String textView5;
// The following list is useless unless u don't use it somewhere so lets create getters and setters for this item
private List<String> spinnerItemsList = new ArrayList<String>();
public Product(List spinner, String editText, Boolean checkBox, String textView5) {
this.editText = editText;
this.spinnerItemsList = spinner;
this.checkBox = checkBox;
this.textView5 = textView5;
}
public String getEdittext () {
return editText;
}
public boolean getCheckbox () {
return checkBox;
}
public String getTextview () {
return textView5;
}
public String getSpinnerItemsList () {
return spinnerItemsList;
}
}
Well I think you just need to add a dummy object in your array list and then just call notifyDataSetChanged()
//Step 1 reposition your adapter
ProductAdapter adapter = new ProductAdapter(this, productList);
//TODO FAB BUTTON
FloatingActionButton floatingActionButton =
(FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//The problem is in the following line you need to pass the values but what you are doing is incorrect
//Product mProduct = new Product(List spinner, String editText, Boolean checkBox, String textView5);
//So replace the above line with the following code
ArrayList<String> spinnerItem = new ArrayList<String>();
spinnerItem.add("StackOverFlow");
//There are better and efficient ways to achieve this, If you explain what do you want exaclty I might be able to help
Product mProduct = new Product(spinnerItem, "EditText Value", true, "TextView Value");
productList.add(mProduct); //what goes here???//
if(adapter != null)
adapter.notifyDataSetChanged();
else
//Handle the empty adapter here
}
});
I guess now with the above code you are good to go!
UPDATE Try changing the following code block inside ProductAdapter.java
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
//getting the product of the specified position
Product product = productList.get(position);
//binding the data with the viewholder views
//MyListAdapter adapter = new MyListAdapter(mCtx, R.layout.listrow, R.id.txtid, Product.spinnerItemsList);
//spinner.setAdapter(adapter);
//Try using Simple ArrayAdapter if all you need to display is one text
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String> (mCtx, android.R.layout.simple_spinner_item, Product.getSpinnerItemsList());
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter);
}
productList is a list of products. You must supply an object of type product when doing `productList.add().
example:
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Product p = new Product(...)
productList.add(p);
ProductAdapter adapter = new ProductAdapter(this, productList);
//setting adapter to recyclerview
recyclerView.setAdapter(adapter);
}
});
p.s: The first argument in the constructor of Product is useless as you aren't using it anywhere.
There are better ways of implementing this tho.
when user presses FAB, a cardview appears in recyclerview. Inside the cardview is a spinner with some other elements. When i add multiple cardviews and select an item from the spinners, then I add another cardview from the fab then all the spinner selected items reset?
I have a method productList.size() which could possibly help in saving the spinner selected values but I do not know where to go from here. Thanks
activity code
public class create extends AppCompatActivity {
//a list to store all the products
List<Product> productList;
//the recyclerview
RecyclerView recyclerView;
Product mProduct;
private Map<String, String> numberItemValues = new HashMap<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create);
//opens csv
InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
CSVFile csvFile = new CSVFile(inputStream);
final List<String> mSpinnerItems = csvFile.read();
//getting the recyclerview from xml
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//initializing the productlist
productList = new ArrayList<>();
final Spinner spinner;
final EditText editText;
final CheckBox checkBox;
final TextView textView5;
spinner = findViewById(R.id.spinner);
editText = findViewById(R.id.editText);
checkBox = findViewById(R.id.checkBox);
textView5 = findViewById(R.id.textView5);
final ProductAdapter adapter = new ProductAdapter(this, productList);
//TODO FAB BUTTON
FloatingActionButton floatingActionButton =
(FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
List<Product> mProductList = new ArrayList<>();
productList.add(mProduct);
if(adapter != null)
adapter.notifyDataSetChanged();
//Handle the empty adapter here
}
});
/* //TODO Add the spinner on item selected listener to get selected items
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
String currentItem = mSpinnerItems.get(position);
String aisleNumber = numberItemValues.get(currentItem);
//TODO you can use the above aisle number to add to your text view
//mTextviews.get(mTextviews.size() -1).setText(aisleNumber);
textView5.setText(aisleNumber);
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// do nothing
}
});*/
//setting adapter to recyclerview
recyclerView.setAdapter(adapter);
}
private class CSVFile {
InputStream inputStream;
public CSVFile(InputStream inputStream) {
this.inputStream = inputStream;
}
public List<String> read() {
// The problem with your adapter is solved now you need to do some work here its giving an error while reading the file
//why is it giving an error because it use to work fine before I added cardview and recyclerview
//Is the file there?
List<String> resultList = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] row = line.split(",");
//TODO I edited this part so that you'd add the values in our new hash map variable
numberItemValues.put(row[1], row[0]);
resultList.add(row[1]);
}
} catch (IOException e) {
Log.e("Main", e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
Log.e("Main", e.getMessage());
}
}
return resultList;
}
}
}
product.java code
public class Product {
private static String editText;
private static Boolean checkBox;
private static String textView5;
// The following list is useless unless u don't use it somewhere so lets create getters and setters for this item
public static List<String> spinnerItemsList = new ArrayList<String>();
public Product(List spinner, String editText, Boolean checkBox, String textView5) {
this.editText = editText;
this.spinnerItemsList = spinner;
this.checkBox = checkBox;
this.textView5 = textView5;
}
public static String getEdittext () {
return editText;
}
public static boolean getCheckbox () {
return checkBox;
}
public static String getTextview () {
return textView5;
}
public static List<String> getSpinnerItemsList () {
return spinnerItemsList;
}
}
productadapter.java
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
//this context we will use to inflate the layout
private Context mCtx;
private Spinner spinner;
//we are storing all the products in a list
private List<Product> productList;
//getting the context and product list with constructor
public ProductAdapter(Context mCtx, List<Product> productList) {
this.mCtx = mCtx;
this.productList = productList;
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.layout_products, null);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
//getting the product of the specified position
Product product = productList.get(position);
//binding the data with the viewholder views
//MyListAdapter adapter = new MyListAdapter(mCtx, R.layout.listrow, R.id.txtid, Product.spinnerItemsList);
//spinner.setAdapter(adapter);
//Try using Simple ArrayAdapter if all you need to display is one text
//Lets see
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String> (mCtx, android.R.layout.simple_spinner_item, Product.getSpinnerItemsList());
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Did it work?
//yes but when I press the spinner I do not see the items that usually comes up also the layout of Oit Oipen the screen let me take the screen shot
//how do i do that? the screen is open on my phone ok wait click the spinner yes
//There is no item??
//nothing comes up. not even a dropdown. but before i had it like it was populated by items in a csv.
//Okay wait let me get your old code
//also, I added cardviews in my phone but i try to scroll up and I cannot? i thought you could scroll in recyclerview?
//Yes you can scroll it should work
holder.spinner.setAdapter(spinnerArrayAdapter);
}
#Override
public int getItemCount() {
return productList.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
Spinner spinner;
EditText editText;
TextView textView5;
CheckBox checkBox;
public ProductViewHolder(View itemView) {
super(itemView);
spinner = itemView.findViewById(R.id.spinner);
editText = itemView.findViewById(R.id.editText);
textView5 = itemView.findViewById(R.id.textView5);
checkBox = itemView.findViewById(R.id.checkBox);
}
}
}
**mylistadapter.java which is for spinner **
public class MyListAdapter extends ArrayAdapter<String> {
int groupid;
List<String> items;
Context context;
String path;
public MyListAdapter(Context context, int vg, int id, List<String> items) {
super(context, vg, id, items);
this.context = context;
groupid = vg;
this.items = items;
}
static class ViewHolder {
public TextView textid;
public TextView textname;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
{
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(groupid, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.textid = (TextView) rowView.findViewById(R.id.txtid);
viewHolder.textname = (TextView) rowView.findViewById(R.id.txtname);
rowView.setTag(viewHolder);
}
// Fill data in the drop down.
ViewHolder holder = (ViewHolder) rowView.getTag();
String row = items.get(position);
//holder.textid.setText(row[0]); //prints aisle number, dont need
holder.textname.setText(row);
return rowView;
}
}
}
There are multiple steps to achieve this:
Step 1:
Map<Integer, Integer> mSpinnerSelectedItem = new HashMap<Integer, Integer>();
Step 2:
Inside onBindViewHolder add the following lines
if (mSpinnerSelectedItem.containsKey(position)) {
spinner.setSelection(mSpinnerSelectedItem.get(position));
}
Step 3:
Now where you have set your spinner onItemSelected method add the following line to store your selected item for that spinner.
mSpinnerSelectedItem.put(position, selectedIndex);
I doubt I've done any typo but about 10 minutes ago all my buttons would press and do what it is suppose to, but now when I press them it does nothing. I can't even click my spinner to open. I tried deleting the app from my phone and restarting but it still wouldn't work and I'm 99% sure I didn't make any significant changes to make my app not work.
create.java
public class create extends AppCompatActivity {
Button buttontest;
private LinearLayout mLinearLayout;
private ArrayList<Spinner> mSpinners;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mSpinners = new ArrayList<>();
mLinearLayout = findViewById(R.id.my_linearLayout);
mLinearLayout.addView(makeSpinner()); // First spinner
Button duplicateSpinner = findViewById(R.id.bt_duplicate); //button to duplicate spinner
duplicateSpinner.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Spinner spinner = makeSpinner();// this makes spinner from the private Spinner code below. so you just need to do the same for the frame layout? put everything in one layout oand do that.
mLinearLayout.addView(spinner); // Add another spinner
}
});
Button getSpinner = findViewById(R.id.bt_getSpinner);
getSpinner.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (int i = 0; i < mSpinners.size(); i++) { // Read all spinners
Spinner spinner = mSpinners.get(i);
Log.i("TAG", spinner.getSelectedItem().toString());
}
}
});
}
private Spinner makeSpinner() { //how to make spinners
//opens csv
InputStream inputStream = getResources().openRawResource(R.raw.shopitems);
CSVFile csvFile = new CSVFile(inputStream);
List<String> itemList = csvFile.read();
//Create new spinner
Spinner spinner = new Spinner(this, Spinner.MODE_DROPDOWN);
// Setup layout
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
spinner.setLayoutParams(layoutParams);
MyListAdapter adapter = new MyListAdapter(this, R.layout.listrow, R.id.txtid, itemList);
spinner.setAdapter(adapter);
//Add it to your list of spinners so you can retrieve their data when you click the getSpinner button
mSpinners.add(spinner);
return spinner;
}
private class CSVFile {
InputStream inputStream;
public CSVFile(InputStream inputStream) {
this.inputStream = inputStream;
}
public List<String> read() {
List<String> resultList = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] row = line.split(",");
resultList.add(row[1]);
}
} catch (IOException e) {
Log.e("Main", e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
Log.e("Main", e.getMessage());
}
}
return resultList;
}
} }
mylistadapter code
public class MyListAdapter extends ArrayAdapter<String> {
int groupid;
List<String> items;
Context context;
String path;
public MyListAdapter(Context context, int vg, int id, List<String> items) {
super(context, vg, id, (List<String>) items);
this.context = context;
groupid = vg;
this.items = items;
}
static class ViewHolder {
public TextView textid;
public TextView textname;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
{
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(groupid, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.textid = (TextView) rowView.findViewById(R.id.txtid);
viewHolder.textname = (TextView) rowView.findViewById(R.id.txtname);
rowView.setTag(viewHolder);
}
// Fill data in the drop down.
ViewHolder holder = (ViewHolder) rowView.getTag();
String row = items.get(position);
//holder.textid.setText(row[0]); prints aisle number, dont need
holder.textname.setText(row);
return rowView;
}
}
}
Had a problem with the xml code, I put the element in a layout instead of outside a layout
I have a button inside CardView which represents item of RecycleView. I've managed to handle the click event inside the ViewHolder class but I need to call function on MainActivity, How can I implement that with below code?
My code as below
ShopItemRecyclerViewAdapter.java
public class ShopItemRecyclerViewAdapter extends RecyclerView.Adapter<ShopItemRecyclerViewAdapter.ListItemViewHolder> {
static ArrayList<ShopListItemModel> list;
LayoutInflater inflater;
public ShopItemRecyclerViewAdapter(ArrayList<ShopListItemModel> list, Context context){
inflater = LayoutInflater.from(context);
this.list = list;
}
public ListItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_item, parent , false);
ListItemViewHolder vh = new ListItemViewHolder(view);
return vh;
}
public void onBindViewHolder(ListItemViewHolder holder, int position) {
ShopListItemModel current = list.get(position);
holder.name.setText(current.getName());
holder.price.setText(String.valueOf(current.getPrice()));
}
public int getItemCount() {
return list.size();
}
public static class ListItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView name;
TextView price;
ImageButton btnDelete;
ListItemViewHolder(final View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cvShopListItem);
name = (TextView)itemView.findViewById(R.id.name);
price = (TextView)itemView.findViewById(R.id.price);
btnDelete = (ImageButton)itemView.findViewById(R.id.btnDeleteItem);
itemView.setOnClickListener(this);
btnDelete.setOnClickListener(this);
}
#Override
public void onClick(View v) {
//here i can handle the click but i think i need to use it in the main activity
}
}
}
MainActivity.java (skipped irrelevent code)
public class ShopCartScreen extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
RecyclerView cartItems; //recycler to hold the cart list
ArrayList<ShopListItemModel> list = new ArrayList<ShopListItemModel>();
ShopItemRecyclerViewAdapter adapter;
GetShopingCartList getShopingCartList; ////instance of network operation class to retrieve shop cart items list from server data base
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shop_carts_list);
cartItems = (RecyclerView) findViewById(R.id.newListItem);
cartItems.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
cartItems.setLayoutManager(llm)
}
public void bindData(int listNumber) {
getShopingCartList = new GetShopingCartList(this, list, adapter, cartItems, listNumber, totalPrice);
getShopingCartList.execute("link to query which returns json object");
}
}
GetShopingCartList.java for network operation
public class GetShopingCartList extends AsyncTask<String, String, ArrayList<ShopListItemModel>> {
private ArrayList<ShopListItemModel> shopCartItemList;
Context context;
RecyclerView items;
ShopItemRecyclerViewAdapter adapter;
int listNumber;
public GetShopingCartList(Context context, ArrayList<ShopListItemModel> shopCartItemList, ShopItemRecyclerViewAdapter adapter,
RecyclerView items ,int listNumber) {
this.context = context;
this.shopCartItemList = shopCartItemList;
this.adapter = adapter;
this.items = items;
this.listNumber = listNumber;
}
protected ArrayList<ShopListItemModel> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
shopCartItemList = new ArrayList<ShopListItemModel>();
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("result");
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);//get the cuttent json object which is representaion of shop cart model object
String name = finalObject.getString("name");
String price = finalObject.getString("price");
Double d = Double.parseDouble(price);
ShopListItemModel item = new ShopListItemModel(name, d);
shopCartItemList.add(item);//adds the shopcart to the list of shop carts model
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return shopCartItemList;
}
protected void onPostExecute(ArrayList<ShopListItemModel> s) {
super.onPostExecute(s);
adapter = new ShopItemRecyclerViewAdapter(shopCartItemList, context);
items.setAdapter(adapter);
}
public ArrayList<ShopListItemModel> getList() {
return shopCartItemList;
}
}
Implement a method inside ShopCartScreen.java, then you can use the context object inside the adapter.
((ShopCartScreen)context).methodImplemented(ShopListItemModel model)
//add this code inside onClick event of the button
ok this is my solution if anyone needs it (i combined 2 methods/ 1 in the main activity and 1 in the recycler adapter):
in my recycler adapter i added this delete method:
//delete the item from the recycler Immediately for user interaction
public void delete(int position){
list.remove(position);
notifyItemRemoved(position);
}
in my ViewHolder class:
ListItemViewHolder(final View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cvShopListItem);
name = (TextView)itemView.findViewById(R.id.name);
price = (TextView)itemView.findViewById(R.id.price);
btnDelete = (ImageButton)itemView.findViewById(R.id.btnDeleteItem);
itemView.setOnClickListener(this);
btnDelete.setOnClickListener(this);
}
#Override
public void onClick(View v) {
((ShopCartScreen)context).deleteItem(getPosition());//calls method in main activity
delete(getPosition());
}
and in the main activity:
public void deleteItem(int postion){
list = getShopingCartList.getList();
ShopListItemModel tmp = list.get(postion);
tmp.getName(); //gets the item name to remove
shopCartModel.getNumber(); //gets the cart number for deleting the item for the correct cart
new DeleteCartItem(this , shopCartModel , tmp).execute(); //remove the item from the data base
}