Button Onclick Listener in included layouts Button Onclick Listener in included layouts android android

Button Onclick Listener in included layouts


I had the same problem with a menu which I used in several layouts. I solved the problem by inflating the layout xml file in a class extending RelativeLayout where I then defined the onClickListener. Afterwards I included the class in each layout requiring the menu. The code looked like this:

menu.xml

<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <ImageButton android:id="@+id/map_view"        android:layout_alignParentTop="true"        android:layout_alignParentLeft="true"        android:src="@drawable/button_menu_map_view"        android:background="@null"        android:scaleType="fitCenter"        android:layout_height="@dimen/icon_size"        android:layout_width="@dimen/icon_size">    </ImageButton>    <ImageButton android:id="@+id/live_view"        android:layout_alignParentTop="true"        android:layout_alignParentLeft="true"        android:src="@drawable/button_menu_live_view"        android:background="@null"        android:scaleType="fitCenter"        android:layout_height="@dimen/icon_size"        android:layout_width="@dimen/icon_size">    </ImageButton>    <ImageButton android:id="@+id/screenshot"        android:layout_alignParentTop="true"        android:layout_alignParentRight="true"        android:src="@drawable/button_menu_screenshot"        android:background="@null"        android:scaleType="fitCenter"        android:layout_height="@dimen/icon_size"        android:layout_width="@dimen/icon_size">    </ImageButton></merge>

MenuView.java

public class MenuView extends RelativeLayout {    private LayoutInflater inflater;    public MenuView(Context context, AttributeSet attrs) {        super(context, attrs);        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);        inflater.inflate(R.layout.menu, this, true);        ((ImageButton)this.findViewById(R.id.screenshot)).setOnClickListener(screenshotOnClickListener);                ((ImageButton)this.findViewById(R.id.live_view)).setOnClickListener(liveViewOnClickListener);               ((ImageButton)this.findViewById(R.id.map_view)).setOnClickListener(mapViewOnClickListener);    }    private OnClickListener screenshotOnClickListener = new OnClickListener() {        public void onClick(View v) {            getContext().startActivity(new Intent(getContext(), ScreenshotActivity.class));        }    };      private OnClickListener liveViewOnClickListener = new OnClickListener() {        public void onClick(View v) {            getContext().startActivity(new Intent(getContext(), LiveViewActivity.class));        }    };    private OnClickListener mapViewOnClickListener = new OnClickListener() {        public void onClick(View v) {            getContext().startActivity(new Intent(getContext(), MapViewActivity.class));        }    };  }

layout.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/main"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <SurfaceView android:id="@+id/surface"        android:layout_width="fill_parent"        android:layout_weight="1"        android:layout_height="fill_parent">    </SurfaceView>    <!-- some more tags... -->    <com.example.inflating.MenuView            android:layout_width="fill_parent"            android:layout_height="fill_parent" /></RelativeLayout>

with the <com.example.inflating.MenuView /> tag, you are now able to reuse your selfwritten Layout (incl onClickListener) in other layouts.


This is something that is getting added to roboguice in the near the future. It will allow you to build controller classes for things like titlebar's and footers and have the events autowired for you.

Checkout http://code.google.com/r/adamtybor-roboguice/ for the initial spike.

Basically if you are using roboguice you can define a component for footer and just inject that footer component into each activity.

Unfortunately you still have to add the controller to every activity, just like you did with the include layout, but the good news is everything gets wired up for you and all your logic stays in a single class.

Below is some pseudo code of some example usage.

public class FooterController {  @InjectView(R.id.footer_button) Button button;  @Inject Activity context;  @ContextObserver  public void onViewsInjected() {    button.setOnClickListener(new OnClickListener() {       void onClick() {         Toast.makeToast(context, "My button was clicked", Toast.DURATION_SHORT).show();        }    });  }}public class MyActivity1 extends RoboActivity {  @Inject FooterController footer;}public class MyActivity2 extends RoboActivity {  @Inject FooterController footer;}


The solution as you describe is impossible, sorry. But you can have common parent activity for all your activities that use the footer. In the activity just provide handler methods for your footer buttons, then just inherit from it every time you need to handle the footer actions.