Moisés Moisés - 5 months ago 45
Java Question

Add setOnClickListener on Android custom component

When making a custom component for Android, as far as I understood, I need:


  • one xml file with the layout for the component;

  • one java class.



Tried to make one, just for practice. Use two progressbars and one button in the XML, and create the class, than tried out in my main activity, worked fine.

But now I'm loking how to set OnClickListener on my button through the activity, and in this part I'm lost.

My loading_button.xml:

<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<RelativeLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:progress="0"
android:id="@+id/pg_top" />

<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_ok"
android:background="@color/colorPrimary"
android:textColor="#ffffff"
android:layout_below="@+id/pg_top"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />

<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:progress="0"
android:id="@+id/pg_bottom"
android:layout_below="@+id/btn_ok"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />

</RelativeLayout>

</merge>


Here the LoadingButton.java:

public class LoadingButton extends RelativeLayout{

private ProgressBar pbTop;
private ProgressBar pbBottom;
private Button btnOk;

private int pbTopProgress = 0;
private int pbBottomProgress = 0;

public LoadingButton(Context context, AttributeSet attrs) {
super(context, attrs);
View view = View.inflate(context, R.layout.loading_button, this);

btnOk = (Button) view.findViewById(R.id.btn_ok);
pbTop = (ProgressBar) view.findViewById(R.id.pg_top);
pbBottom = (ProgressBar) view.findViewById(R.id.pg_bottom);

btnOk.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Doing stuff ok
}
});

}// LoadingButton
}


The setOnClickListener in the class works, but how can I set it from my main activity?

MainActivity:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// My new component (it's id in activity_main.xml is 'lb')
LoadingButton lb = (LoadingButton) findViewById(R.id.lb);

// QUESTION - how to make something like this with btnOk:
lb.btnOkSetOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Do stuff
}
});
}
}


If this is possible, how?

If not, what is the right approach to make a custom component and set clickListeners on specific element of this component?

Answer

Best approach to handle all view click in LoadingButton (For custom view). And create interface.

public class LoadingButton extends RelativeLayout {


    public interface OnLoadingButtonClickListener{
        void onLoadingButtonClickListener();
    }

    private ProgressBar pbTop;
    private ProgressBar pbBottom;
    private Button btnOk;

    private int pbTopProgress = 0;
    private int pbBottomProgress = 0;
    private OnLoadingButtonClickListener mONOnLoadingButtonClickListener;

    public LoadingButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        View view = View.inflate(context, R.layout.loading_button, this);

        btnOk = (Button) view.findViewById(R.id.btn_ok);
        pbTop = (ProgressBar) view.findViewById(R.id.pg_top);
        pbBottom = (ProgressBar) view.findViewById(R.id.pg_bottom);

        btnOk.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mONOnLoadingButtonClickListener != null){
                    mONOnLoadingButtonClickListener.onLoadingButtonClickListener();
                }
            }
        });

    }// LoadingButton

    public void setOnLoadingClickListener(OnLoadingButtonClickListener onLoadingClickListener){
        mONOnLoadingButtonClickListener = onLoadingClickListener;
    }


}

And implement OnLoadingButtonClickListener in your activity.

public class MainActivity extends AppCompatActivity implements LoadingButton.OnLoadingButtonClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // My new component (it's id in activity_main.xml is 'lb') 
        LoadingButton lb = (LoadingButton) findViewById(R.id.lb);
        lb.setOnLoadingClickListener(this);

    }

    @Override
    public void onLoadingButtonClickListener() {
        //do your stuff on ok button click
    }
}