Error404 Error404 - 4 months ago 9
Android Question

How to reference elements from two layouts in Android?

I have a

RecyclerView
with a custom
Adapter
that has a List. Each of the elements on the list have a checkbox that are handle on the custom
Adapter
in which I use:

holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {


to detect when the checkboxes are pressed.

The problem is that I also have a button but it is handled from the class of the View. In this class I can reference the layout in which the button is, like this:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View buttonInflater = inflater.inflate(R.layout.fragment_button,null);


but in the custom adapter I cannot do this. I have to do:

public MyItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);


So one time I have reference both layouts in their respective classes, I thought that I could make reference to the button on the View class referencing also its layout on the custom Adapter. Similar to this:

public MyItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
View buttonView = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_button, parent, false);


but when I try to reference the button it seems not to be referenced.

Why I want to reference the button from my custom adapter view

Because I want that each time the checkbox is selected one unit will be added to the button text. For example, the first time I select a checkbox of the list on the button the text should be 1, the second time 2 and so on.

This is the code that I have on my custom adapter when I press the checkbox:

int sum = 0;

holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(buttonView.isChecked()){
sum = sum + 1;
checkBox.setText("" + sum);
}else{
sum = sum - 1;
checkBox.setText("" + sum);
}
}
});


But this button doesnt write anything.

How can I write on the button?

Thanks in advance!

Answer

I would say it is bad design to have the button directly referenced in the list adapter, due to separation of concerns. If you really want to do it you shouldn't try to re-inflate the button. What you should just do is add property (or setter) on your list adapter, that is a reference to the button. Then when you create your list adapter, set the button onto it:

final View buttonInflater = inflater.inflate(R.layout.fragment_button,null);
mListAdapter.setButton(buttonInflater);

Then in your custom adapter:

private Button mButton;
public void setButton(Button button) { 
   mButton = button;
}

Then in your view holder you will have a reference to the button:

holder.checkBox.setOnCheckedChangeListener(setOnClickListener(new CompoundButton.OnCheckedChangeListener() {

                        @Override
                        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                            mButton.setText(...);
                        }
                    });

But, I would highly recommend a using callback pattern. Namely, similar to the way you can implement AdapterView.OnItemClickListener (https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html), you could create a custom interface like ItemCheckChangedListener. It could even match the definition of CompoundButton.OnCheckedChangeListener if you like. But basically just set your class (that has the button and the RecyclerView) as the OnCheckedChangeListener. Then whenever the checkbox state is changed, callback to the listener you created. Then in there you have access to the button, so you can update its state.