I have a RecyclerView inside a fragment where each line has an adapter which inflates a layout which looks as follows:
I want to access to the value of the EditText (in the following code numberET) of each row and pick the value if EditText is not empty.
How can I cycle on each element of the RecyclerView (I think inside the adapter) to have this behaviour? How can I access the EditText for each element to retrieve the value and use them inside the fragment?
Adapter:
`
public class UserFBEditTextAdapter <T extends UserFBEditTextAdapter.ViewHolder> extends UserFBAdapter<UserFBEditTextAdapter.ViewHolder>{
public UserFBEditTextAdapter(List<UserFB> users,int layoutId, Context context) {
super(users, layoutId, context);
}
#Override
public UserFBEditTextAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
return new UserFBEditTextAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(UserFBAdapter.ViewHolder holder, int position) {
holder.userFB = users.get(position);
holder.usernameTV.setText(holder.userFB.getName());
}
public class ViewHolder extends UserFBAdapter.ViewHolder {
protected EditText numberET;
public ViewHolder(View itemView) {
super(itemView);
numberET = (EditText) itemView.findViewById(R.id.number_et);
}
}
}`
Fragment:
public class ExpenseCustomFragment extends Fragment {
private OnFragmentInteractionListener mListener;
private UserFBAdapter adapter;
private RecyclerView userCustomList;
public ExpenseCustomFragment() {
// Required empty public constructor
}
public static ExpenseCustomFragment newInstance() {
ExpenseCustomFragment fragment = new ExpenseCustomFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_expense_custom, container, false);
userCustomList = (RecyclerView) view.findViewById(R.id.amountlist_rv);
userCustomList.setLayoutManager(new LinearLayoutManager(getContext()));
NewExpenseDescriptionActivity activity = (NewExpenseDescriptionActivity) getActivity();
adapter = new UserFBEditTextAdapter(activity.getUsersGroup(), R.layout.listitem_expensecustom, getContext());
userCustomList.setAdapter(adapter);
return view;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
You have to retain that data in some map-based data structure, and then, whenever those values are needed, iterate over that data structure.
You cannot rely on saving that data in a ViewHolder, because ViewHolders are being reused as soon as you perform scrolling. If you currently do not save the data that is filled in EditText, then you'll lose that data if you have many items and perform scrolling (i.e. screen fits 10 items, but your adapter is 20 items, as soon as you scroll to 15th item, the EditText value for the first item will be lost).
private Map<Integer, String> map = new ArrayMap<>(adapterSize);
...
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
String text = map.get(holder.getAdapterPosition());
// maybe we haven't yet saved text for this position
holder.editText.setText(text != null ? text : "");
// updated value in map as soon as the `EditText` in this position changes
holder.editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
map.put(holder.getAdapterPosition(), s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
Now you'll have access to all EditText values in your RecyclerView. The only change that you can consider is updating map after user stops typing. Currently if user types "123456789" the map will be updated 9 times, whereas we need only once. An easy solution to this can be using RxJava's debounce operator combined with RxBinding library. This maybe sounds complicated, but you can see how plain it is in this answer.
This will work. But after you perform scrolling up and forth, soon you'll find out that some mess is going on there. That's because each time onBindViewHolder() gets called a new TextWatcher is being added to the EditText that already has a TextWatcher attached to it. Thus, you also have to take care of removing the TextWatcher after your ViewHolder is being recycled.
But there is no an API to remove all TextWatcher of the EditText. You can use a custom EditText implementation shown in this answer which will clear all TextWatcher attached to this EditText:
#Override
public void onViewRecycled(MyViewHolder holder) {
holder.editText.clearTextChangeListeners();
super.onViewRecycled(holder);
}
Related
Basically we need to get the email from the recyclerview
We tried adding onClickListener on the TextView in the RecyclerView, but when there are more than one entries in the RecyclerView, we cannot get the value.
Is there any way that I can store the values in variables before populating the RecyclerView and passing the values to another Activity?
I tried getting the values from the TextView in the RecyclerView, but I always show the text on the first row
Intent doesn't work on the Adapter class because its not an activity
ArrayList<ModelClass> objModelClassArrayList;
public DatabaseRecyclerAdapter(ArrayList<ModelClass> objModelClassArrayList) {
this.objModelClassArrayList = objModelClassArrayList;
}
#NonNull
#Override
public DatabaseViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View singleRow= LayoutInflater.from(parent.getContext()).inflate(R.layout.single_row,parent,false);
return new DatabaseViewHolder(singleRow);
}
#Override
public void onBindViewHolder(#NonNull DatabaseViewHolder holder, int position)
{
ModelClass objModelClass=objModelClassArrayList.get(position);
holder.userNameTV.setText(objModelClass.getName());
holder.userLocation.setText(objModelClass.getAddress());
String e1=objModelClass.getEmail();
holder.userEmail.setText(e1);
}
#Override
public int getItemCount() {
return objModelClassArrayList.size();
}
public static class DatabaseViewHolder extends RecyclerView.ViewHolder
{
TextView userNameTV,userLocation,userEmail;
public DatabaseViewHolder(#NonNull View itemView)
{
super(itemView);
userNameTV=itemView.findViewById(R.id.sr_userNameTV);
userLocation=itemView.findViewById(R.id.sr_location);
userEmail=itemView.findViewById(R.id.sr_email);
}
}
I want to extract the email from a single row and pass it to another page where I can pass it in the DB query to get the results from the database.
first, need to pass context in the constructor of the adapter which can help you to open another activity from the recyclerView adapter. Then Inside BindViewHolder, you can create clickListener like as below,
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String emailText=holder.userEmail.getText().trim();
Intent intent=new Intent(context,activity_name_you _want_ to_open);
intent.setExtra("emailName",emailText);
(name of activity contains RV)context.startActivity(intent)
//Note: here context needs to be typecasted to activity from which we want to open new activity.
}
});
Im trying to implement a dynamic text size option within my app. For some reason the recycler is only randomly changing text size within my cardviews instead of setting all the text to the desired size. As I scroll the list, the top cardview text will change correctly but the next 3-4 will stay default and randomly down the list another cardview text will display correctly. when i scroll back up the list, the cardview that displays correctly will change at random.
Main Activity....
// Dark Mode Menu
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawer.openDrawer(GravityCompat.START);
return true;
case R.id.menu_night_mode_day:
setNightMode(AppCompatDelegate.MODE_NIGHT_NO);
break;
case R.id.menu_night_mode_night:
setNightMode(AppCompatDelegate.MODE_NIGHT_YES);
break;
case R.id.menu_night_mode_auto:
setNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
break;
// Text Size Options
case R.id.menu_text_size_small:
setTextSize(18);
break;
case R.id.menu_text_size_medium:
setTextSize(20);
break;
case R.id.menu_text_size_large:
setTextSize(22);
break;
}
return super.onOptionsItemSelected(item);
}
// Dark Mode Menu
private void setNightMode(#AppCompatDelegate.NightMode int nightMode) {
AppCompatDelegate.setDefaultNightMode(nightMode);
if (Build.VERSION.SDK_INT >= 11) {
recreate();
}
}
// Dynamic text size
private void setTextSize(int textSize) {
TextView description = (TextView) findViewById(R.id.cardview_description);
description.setTextSize(textSize);
saveToPreferences(this, "THE_TEXT_SIZE", "" + textSize);
}
My Adapter....
public class MyPageAdapter extends Adapter<MyPageHolder> {
public List<MenuPageItems> datas;
private Activity activity;
public String dynamicTextSize;
public MyPageAdapter(Activity activity){
datas = new ArrayList<>();
this.activity = activity;
}
public void add(MenuPageItems dataModel){
datas.add(dataModel);
}
public void add(MenuPageItems dataModel, int position){
datas.add(position, dataModel);
}
public void addAll(List<MenuPageItems> menuPageItems){
datas.addAll(menuPageItems);
}
#Override
public MyPageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return createViewHolder(v, viewType);
}
#Override
public void onBindViewHolder(MyPageHolder holder, int position) {
holder.bind(datas.get(position), activity, position);
dynamicTextSize = "20";
}
#Override
public int getItemCount() {
return datas.size();
}
#Override
public int getItemViewType(int position){
return datas.get(position).getViewResId();
}
public int searchViewTypePosition(int viewType){
int i = 0;
boolean found = false;
while(i < datas.size() && !found){
if(datas.get(i).getViewResId() == viewType){
found = true;
i--;
}
i++;
}
return i;
}
public MyPageHolder createViewHolder(View v, int viewType){
return datas.get(searchViewTypePosition(viewType)).createViewHolder(v, activity, this);
}
}
Holder....
public abstract class MyPageHolder extends RecyclerView.ViewHolder{
protected final Activity activity;
protected MyPageAdapter adapter;
public TextView txtTitle, txtDescription, txtTheContent;
public ImageView imgImage;
public View view;
public MyPageHolder(View v, Activity activity, MyPageAdapter adapter) {
super(v);
this.activity = activity;
this.adapter = adapter;
imgImage = (ImageView) v.findViewById(R.id.cardview_image);
txtTitle = (TextView) v.findViewById(R.id.cardview_title);
txtDescription = (TextView) v.findViewById(R.id.cardview_description);
view = (CardView) v.findViewById(R.id.card_view);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/*/ this is where the magic happens when clicked /*/
}
});
}
public void bind(MenuPageItems dataModel, Activity activity, final int position) {
final MenuPageItems m = (MenuPageItems)dataModel;
imgImage.setImageResource(m.image);
txtTitle.setText(m.title);
txtDescription.setText(m.description);
//txtTheContent.setText(m.theContent);
view.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v){
Intent cvIntent = new Intent(view.getContext(), EndpageActivity.class);
// header image to pass to endpage activity
cvIntent.putExtra("endpageHeader", m.image);
// text to pass to endpage activity
cvIntent.putExtra("endpageTitle", m.title);
cvIntent.putExtra("endpageTheContent", m.theContent);
view.getContext().startActivity(cvIntent);
}
});
}
}
Do I need to add something to my adapter or viewholder to update all the text properly?
I think I get it, but I don't see where you are setting the text size at all, you said it changes in some cards randomly.
As I see it, what needs to be done is to set the size in the Holder's bind method. This gets executed every time the card needs to be redrawn. You can read the shared preferences inside the bind(), but that is terribly inefficient since the holder's bind method will be called many times over when scrolling. You wan to avoid any excess work inside the Holders bind()
Add a dynamicTextSize member variable to the adapter and set the value with either:
Add a setText/getText size to the adapter and the activity can set this when needed.
Retrieve the text size inside the adapter's constructor and then override the notifyDataSetChanged() method and pull the value again each time that is called. Then call super.notifyDataSetChanged()
Example:
#Override
public void notifyDataSetChanged() {
this.dynamicTextSize = // Pull value from shared preferences
super.notifiyDataSetChanged();
}
What I also don't see is the dynamicTextSize value being passed into the holder. Since the holder has a reference to the adapter, you can add a getTextSize() method to the adapter, then the holder can call into the adapter to get it.
public MyPageHolder(View v, Activity activity, MyPageAdapter adapter) {
...
this.dynamicTextSize = adapter.getTextSize()
}
Finally, in the setTextSize() method you'll need to call the adapter.notifyDataSetChanged() to update the adapter.
Update 10/17
I've attempted to add some detail to by previous post.
Main Activity
// Dynamic text size
private void setTextSize(int textSize) {
// Add a call to set the text to the adapter's member variable:
mAdapter.setTextSize(textSize);
// I'm not sure what description is here... I don't see what type the member is
description.setTextSize(textSize);
saveToPreferences(this, "THE_TEXT_SIZE", "" + textSize);
}
In your adapter, add a method to set and get the text size. The set will be called by the main activity, when the text size changes, and the get is called by the holder each time it needs to set the size of the TextView.
public class MyPageAdapter extends Adapter<MyPageHolder> {
...
public String dynamicTextSize;
public void setTextSize(int textSize) {
dynamicTextSize = textSize;
}
// This will be called by the holder
public int getTextSize() {
return dynamicTextSize;
}
...
}
In your holder:
public abstract class MyPageHolder extends RecyclerView.ViewHolder{
public void bind(MenuPageItems dataModel, Activity activity, final int position) {
...
// Call into the adapter to get the text size.
int textSize = adapter.getTextSize();
txtDescription.setTextSize(textSize);
}
}
Update 10/19
I was able to get it to work with just a small change.
Add a getDynamicTextSize in your MainActivity
Add a call to the get from within the MyPageAdapter constructor.
public MyPageAdapter(Activity activity){
datas = new ArrayList<>();
this.activity = activity;
dynamicTextSize = ((MainActivity)activity).getDynamicTextSize();
}
While this does work, there is are few things it will not do for you.
Ties your fragments to always being a child of the MainActivity activity, you can get around this with an interface, but still not pretty.
Will not update the current activity as soon as the user chooses the new text size. Since the mainActivity takes the menu event, you will need to inform whatever Fragment(s) is/are active, that the text setting has changed and then call notifiyDataSetChanged on the adapter.
Does not set the size of the text outside of the custom RecyclerView. I see you have a few fragments that do not use you recycler view. These will not take the setting. The setting in the menu would make you think all the text in the app should change.
The accepted reply in this post seems to be a good way to adjust the text size for the entire app. Some changes in your app almost show that you've seen it.
Ok, my problem is saving inputs of edit text.
I have a recycler view with some edit text inside. I have an adapter and button "add" to add another new edit text. There is a problem because if I write something inside one edit text it doesn't always save when I change focus or I cick on "add" button.
Here is my hosting fragment:
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(view.getContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new AddPlayerAdapter(players);
mRecyclerView.setAdapter(mAdapter);
addButton.setOnClickListener {
// overrides
players.add(new Player(""));
mAdapter.notifyDataSetChanged();
}
So now, after click on "add" button new Player class is added to class Players (item players) and adapter is notified, I see on my screen that new item is added (declared in AddPlayerViewHolder). It works fine.
Here are fragments of my adapter class:
public AddPlayerAdapter(Players players) {
this.players = players;
}
#Override
public AddPlayerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.add_player, parent, false);
return new AddPlayerViewHolder(v);
}
#Override
public void onBindViewHolder(final AddPlayerViewHolder holder, final int position) {
holder.name.setText(players.get(position).getName());
holder.name.setHint("Player " + Integer.toString(position+1));
holder.name.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if (view != null) players.get(position).setName(holder.name.getText().toString());
}
});
}
So each time focus is changed field is updated and it should contain actual data.
But, when I put some data in one edit text, then press "start" button (which open another fragment with "players" data) the focus don't lose and data is not updated. So, I think the idea with OnFocusChangeListener is wrong, but I don't see here anything better.
Could anyone of you make me an example of proper update data inside edit text boxes like here?
I think it is common problem, hope someone will be interested in solution.
You can simply add TextWatcher to save entered player name.
public class EditTextSaverWatcher implements TextWatcher {
private Player player;
public MyTextWatcher(Player player) {
this.player= player;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Another option is to save name here
}
#Override
public void afterTextChanged(Editable s) {
player.setName(s.toString());
}
}
To add the text watcher, you should use
editText.addTextChangedListener(new EditTextSaverWatcher(concretePlayer));
I have the list of travelers with custom adapter what consist two EditText - edtFirstName and edtLastName. I want when user enters text save changes to List, and when next button click send this List to another activity.
My code:
public class TravellersAdapter extends BaseAdapter {
private List<Traveler> itemsList;
private LayoutInflater inflater;
private Activity context;
public TravellersAdapter(Activity context, List<Traveler> itemsList) {
super();
this.itemsList = itemsList;
this.context = context;
inflater = LayoutInflater.from(context);
}
public int getCount() { return itemsList.size(); }
public Object getItem(int i) { return itemsList.get(i); }
public View getView(final int position, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.traveller_item, null);
}
Traveler currentItem = (Traveler) getItem(position);
EditText firstNameView = (EditText) view.findViewById(R.id.edtFirstName);
firstNameView.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable editable) {
currentItem.setFirstName(editable.toString());
}
});
return view;
}
}
For exemple List itemsList consist 5 items. When I edit 2-4 element all ok, but when I edit first or last element edited value assigned to all element in List. In dubugger i saw that method afterTextChanged calls 5 times with different values of position.
How to fix it?
in getView method, the parameter position gives the position of the newly created childView, not the clicked childView's position.
use this to get the correct position:
final int actual_position = myList.getPositionForView((View) v.getParent());
in onClick(View v); of the onClickListener of any View. In you case, you must implement onTextChangedListener for that EditText.
here:
myList is the ListView
v is the View you clicked, in this case the childView of the parent(myList).
The issue happens because views are reusable (that is by design in Android API). So eventually you may assign more than 1 text watcher to the same text view. And all of the assigned watchers are fired when text inside of the text view is changed.
A quick fix (and non-optimal if the list is really long, say, of 1000+ items) would be to have a map of Traweller -> TextWatcher.
Then inside of getView() you can do this (pseudo-code):
check the map if there is a TextWatcher for this Traweller
if map does not have any, then create a new TextWatcher, put in the map and assign to EditText
otherwise detach the TextWatcher from the EditText and remove from the map
create a new TextWatcher, put in the map and assign to EditText
Create one more EditText in the screen that is invisible with name invivisbleEt.
And do the following thing in the addTextChangedListener
firstNameView.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable editable) {
if(!firstNameView.isFocused())
currentItem.setFirstName(editable.toString());
}
});
Also add this code in the onCreate method for ListView object.
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
//public boolean scrolling;
#Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
invivisbleEt.requestFocus();
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
});
I have a Fragment which carries a Button and a RecyclerView, set up by an RecyclerView Adapter. In the RecyclerView are several Items, one of it is a EditText. Now I want that when the Button is clicked(which is NOT in the RecyclerView object), that I get the values of the EditTexts.
I already tried to get the recyclerView.getItemAtPosition() but there is no function like that, also tried the same for the adapter. So I would need something like
ArrayList s.add(recyclerView.getItemAtPosition(position).getEditText().getText().toString());
This is my Adapter:
public class RVSetAdapter extends RecyclerView.Adapter<RVSetAdapter.ViewHolder> {
private Exercise exercise;
public static class ViewHolder extends RecyclerView.ViewHolder {
public EditText et_weight;
public TextView tv_sets,tv_indication;
public ViewHolder(#NonNull final View itemView) {
super(itemView);
tv_sets = itemView.findViewById(R.id.tv_sets);
tv_indication = itemView.findViewById(R.id.tv_indication);
et_weight = itemView.findViewById(R.id.et_weight);
}
}
public RVSetAdapter(Exercise exercise) {
this.exercise = exercise;
}
#NonNull
#Override
public RVSetAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rv_set,viewGroup,false);
RVSetAdapter.ViewHolder vh_set = new RVSetAdapter.ViewHolder(view);
return vh_set;
}
#Override
public void onBindViewHolder(#NonNull final RVSetAdapter.ViewHolder viewHolder,final int i) {
if(exercise.getKind() == 80) {
viewHolder.tv_sets.setText("");
viewHolder.tv_indication.setText("sec.");
}else if(exercise.getKind() == 90) {
viewHolder.tv_sets.setText("");
viewHolder.tv_indication.setText("min.");
}else {
viewHolder.tv_sets.setText(Integer.toString(i + 1) + ".");
}
viewHolder.et_weight.setText(Integer.toString(exercise.getWeights().get(i)));
}
#Override
public int getItemCount() {
return exercise.getWeights().size();
}
}
this is my Fragment:
final View view = layoutInflater.inflate(R.layout.fragment_exercise, container,false);
ImageView iv_exercise = view.findViewById(R.id.iv_exercise);
ImageView iv_musclekind = view.findViewById(R.id.iv_musclekind);
ImageView iv_save = view.findViewById(R.id.iv_save);
TextView tv_exercisename = view.findViewById(R.id.tv_exercisename);
TextView tv_exercisedescription = view.findViewById(R.id.tv_exercisedescription);
iv_exercise.setImageResource(exercises.get(position).getImage());
iv_musclekind.setImageResource(exercises.get(position).getMusclekindImage());
tv_exercisename.setText(exercises.get(position).getName());
tv_exercisedescription.setText(exercises.get(position).getDescription());
iv_save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//here I want to get the Values of the EditTexts and put them into an Array
}
});
recyclerView = view.findViewById(R.id.rv_sets);
recyclerView.setHasFixedSize(true); //maybe change this
layoutManager = new LinearLayoutManager(view.getContext());
adapter = new RVSetAdapter(exercises.get(position));
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
container.addView(view);
return view;
I don't have any ideas to go on so I would appreciate your help. If there is any uncertainty with my description of the problem please don't hesitate to ask.
Greetings Alexander
With RecyclerView, you have to understand that your EditTexts will be recycled. For example, if you have a list of 200 items, and it shows 2 items at one time, you will only ever have 2 EditText. They will reuse the higher EditText for the lower elements.
For example, here is a list that contains EditText showing only 2 at a time, and as the user scrolls, it will recycle and reuse them.
EditText A
Edittext B
EditText A (recycled)
EditText B (recycled)
....
This means you cannot just loop over all the elements later and get the values, as they don't store their values.
So, what you want to do, is when the user modifies an EditText, you want to store that value right away. You can do this by adding a TextWatcher to your EditText.
Note - I did assume you store your weights as String values, so I just took the value from the EditText and stored it into your Exercise Object. You may want to convert it before that.
public class RVSetAdapter extends RecyclerView.Adapter<RVSetAdapter.ViewHolder> {
private Exercise exercise;
// ...
#Override
public void onBindViewHolder(#NonNull final RVSetAdapter.ViewHolder viewHolder,final int i) {
// ...
viewHolder.et_weight.setText(Integer.toString(exercise.getWeights().get(i)));
viewHolder.et_weight..addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
// This will be the text from the EditText
String text = s.toString();
// Store the value back into your exercise Object.
exercise.getWeights().get(i).setWeight(text);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
// ...
// Add a method for easy access to your weights.
public ArrayList<String> getWeights() {
return exercise.getWeights();
}
}
And now, within your Fragment, you can easily get the values out of your RVSetAdapter.
public View onCreateView() {
final View view = layoutInflater.inflate(R.layout.fragment_exercise, container,false);
// ...
iv_save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Use the method we added to your adapter to return the weights.
ArrayList<String> weights = adapter.getWeights();
}
});
// ...
return view;
}
I think you should use ArrayList in Adapter class to keep your items (or just Strings of EditText components). Add String to ArrayList in your onBindViewHolder() after you set text for editext. Then make a function which will get item from your ArrayList like:
public String getItem(int position){
arrayList.get(position);
}
and call it from your onClick() function in Fragment.
I think you can create static button and you can then access that button in your adapter then implement the functionality on the onclick of your button.
static Button btn;
Then implement like this in your adapter...
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for(int i=0;i<arraylist.size();i++)
{
arr[i]= holder.edit_Text.getText().toString();
}
}
});
and put this onclick in your onbindviewholder method.