Reputation: 462
I have a fragment created that, in turn, loads two tabs with separate fragments (students and questions). These two fragments are two ListViews: one with the student's name and a checkbox, and another with some questions.
What I want is to know which students from the ListView are checked. This I get easily with an ArrayList in the custom adapter. I called 'selectedStudents'.
But now I want to pass that ArrayList 'selectedStudents' with the students checked to the main fragment. But I can not do it.
This is my code:
MainClass:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listaAlumnos = (ListView)findViewById(R.id.listViewAlumnosF);
listaCuestiones = (ListView)findViewById(R.id.listViewCuestionesF);
//HERE I WANT TO READ THE ARRAYLIST WITH STUDENTS CHECKED
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main2, container, false);
return rootView;
}
My Student Fragment:
public class StudentsFragment extends Fragment {
ListView listStudentsF;
ArrayList<String> IdAlumnos = new ArrayList<String>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_alumnos, container, false);
listStudentsF = (ListView)v.findViewById(R.id.listStudentsF);
perform();
}
public void perform() {
myAdapterUsers myAdapterUsers = new myAdapterUsers(getActivity(), R.layout.list_item_alumnos, IdAlumnos);
listStudentsF.setAdapter(myAdapterUsers);
}
}
And my Custom Adapter (method getView):
@Override
public View getView(final int position, View convertView, ViewGroup viewGroup) {
View v = convertView;
LayoutInflater layoutInflater = LayoutInflater.from(this.contextM);
v = layoutInflater.inflate(R.layout.list_item_alumnos, null);
final String currentIdAlumnos = IdAlumnos.get(position);
final CheckBox checkBox = v.findViewById(R.id.checkBox2);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
//Comprueba si está checkeado el registro y lo añade o quita a un ArrayList de usuarios seleccionados.
if (isChecked){
selectedStudents.add(currentIdAlumnos);
}else {
selectedStudents.remove(currentIdAlumnos);
}
Log.e("SELEC: ", String.valueOf(selectedStudents));
}
});
return v;
}
I have try create a method in adapter like:
public ArrayList<String> getArrayList() {
return selectedStudents;
}
And called from outer Activity, but don't work.
Upvotes: 0
Views: 237
Reputation: 27236
Let's start by saying that communication between fragments should be done using the parent activity, an interface, and some glue code. This has been asked multiple times, and it's also A google documentation section.
With all that being said, what I would do in your case, is separate the data from the views.
Your list of selected students, should not live or be modified in the activity or fragment.
Your Activity (and its fragments) are merely containers and policy delegates (if I may use Google's terminology) for what Android as a framework offers. You cannot have an Android app without them (at least an app that displays a UI), so you must have them around. But that doesn't mean all your code should live there.
Far from it. Activities and Fragments are complicated on their own (they have a lot of things to do), so instead...
Your Fragment should "ask for its data" to display the list, and push the changes to a place (let's call it repository), so once the user taps an "Alumno" from the list, the list tells the repo: "hey, this Alumno is selected".
The Repository will receive this information, filter the results and publish them.
On the other end, the Other fragment (the one interested in the selected Alumnos), will listen for these changes and will be told what to display.
Think of it as:
FragmentOther starts and asks the repo: "give me the data to display" Repository will reply: Here's the list of Alumnos.
If the user changes the selection (in the students fragment), it will do what it did before, tell the repo: hey, here's the selected students again, they changed.
The repo will filter the question list again, and offer it to anyone interested.
If FragmentOther (questions) is open, it will receive it, if not, once it's opened, it will ask for the current list, and the repo will return it then.
So you see, the key in all this is the infamous separation of concerns.
Each class/object must have the least amount of responsibilities and be as reusable as possible.
For achieving all this using modern Android practices, I recommend you spend time learning:
LiveData, The Repository Pattern, and LifeCycle for example.
All these are part of Android Jetpack.
Upvotes: 2