androidandroid-viewandroid-custom-viewandroid-components

Custom Listener for Compound component


I wrote a compound component and was adding a custom listener to react.

Inside the class for the compound component which uses an xml file.

public class VerticalCounterBlock extends LinearLayout {

    public interface VerticalCounterBlockListener {
        public void onCountChanged(int newCount);
    }

    private VerticalCounterBlockListener mVerticalCounterBlockListener = null;

    public void setVerticalCounterBlockListener(VerticalCounterBlockListener listener){
        mVerticalCounterBlockListener = listener;
    }

    // ... Other functions
}

I got my interface, I got the listener and I got the setter and I engage the listener like this in the button I have in the compound component. I can see that toast that is showing there when I test

addBtn = (Button)findViewById(R.id.btn_addcount);
addBtn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        count++;
        counttv.setText(String.format("%1$d", count));
        Toast.makeText(getContext(), "VCB", Toast.LENGTH_SHORT).show();
        if(mVerticalCounterBlockListener != null) {
            mVerticalCounterBlockListener.onCountChanged(count);
        }
    }
});

In my main activity

m20_vcb = (VerticalCounterBlock) findViewById(R.id.vcb_m20);
m20_vcb.setVerticalCounterBlockListener(new VerticalCounterBlock.VerticalCounterBlockListener() {
    @Override
    public void onCountChanged(int newCount) {
        increasePreachCountTotal();
        Toast.makeText(CounterActivity.this, String.format("%1$d", newCount), Toast.LENGTH_SHORT).show();
    }
});

I do not see that toast nor does it engage the function call. What am I missing?


Solution

  • I can suggest you several improvement scope here mainly restructuring the current format.

    Lets not keep the interface as a inner class. So here's your VerticalCounterBlockListener.java

    public interface VerticalCounterBlockListener {
        public void onCountChanged(int newCount);
    }
    

    Now implement this interface in your MainActivity

    public class MainActivity implements VerticalCounterBlockListener {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            m20_vcb = (VerticalCounterBlock) findViewById(R.id.vcb_m20);
            m20_vcb.setVerticalCounterBlockListener(this);
        }
    
        // ... Other methods
    
        // Override the onCountChanged function. 
        @Override
        public void onCountChanged(int newCount) {
            increasePreachCountTotal();
            Toast.makeText(CounterActivity.this, String.format("%1$d", newCount), Toast.LENGTH_SHORT).show();
        }
    }
    

    You might consider removing the Toast from the addBtn click listener which might create exception.

    addBtn = (Button)findViewById(R.id.btn_addcount);
    addBtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            count++;
            counttv.setText(String.format("%1$d", count));
    
            if(mVerticalCounterBlockListener != null) {
                mVerticalCounterBlockListener.onCountChanged(count);
            }
        }
    });