1

I have simple Relative layout with one button.

And Im using this layout multiple times using include in Main Layout.

Its possible to write one method (using ButterKnife or not) for all this buttons using listener(this) and not creating multiple listeners like this ---->

  (relativeLayout1.findViewById(R.id.currencyButton)).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(ForeignExchangeActivity.this, "Euro", Toast.LENGTH_SHORT).show();
        }
    });

    (relativeLayout2.findViewById(R.id.currencyButton)).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(ForeignExchangeActivity.this, "GBP", Toast.LENGTH_SHORT).show();
        }
    });

Single item layaout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorBackgroundSeekbar">

    <TextView
        android:id="@+id/currencyTitle"
        android:text="EUR - PLN"
        android:padding="5dp"
        android:textSize="20sp"
        android:textStyle="bold"
        android:textColor="#FFFFFF"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@color/colorButtonHiglight"/>

    <TextView
        android:id="@+id/currencyDate"
        android:layout_below="@id/currencyTitle"
        android:text="24-01-2015"
        android:textStyle="bold"
        android:layout_marginTop="12dp"
        android:gravity="center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/currencyValue"
        android:layout_below="@+id/currencyDate"
        android:text="4.4567"
        android:layout_marginTop="12dp"
        android:textColor="#FFFFFF"
        android:textStyle="bold"
        android:textSize="25sp"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:layout_centerHorizontal="true"
        android:gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorCalculatorActivity"/>


    <TextView
        android:text="Inna data"
        android:textAllCaps="false"
        android:layout_marginTop="10dp"
        android:id="@+id/currencyButton"
        android:textSize="12sp"
        android:padding="5dp"
        android:gravity="center"
        android:layout_below="@id/currencyValue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:background="@drawable/button_rounder_corners"
        android:layout_alignLeft="@+id/currencyValue"
        android:layout_alignRight="@+id/currencyValue"
        android:onClick="onClickDataButton"
        />


    <View
        android:layout_marginTop="10dp"
        android:layout_below="@id/currencyButton"
        android:layout_width="match_parent"
        android:layout_height="1dp"/>





</RelativeLayout>

Example Inlcude

<LinearLayout
                android:layout_width="match_parent"
                android:weightSum="2"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_marginTop="@dimen/activity_horizontal_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin">


                <include
                    android:id="@+id/currency1"
                    android:layout_height="wrap_content"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    layout="@layout/single_item_foreign_exchange"/>


                <View
                    android:layout_width="10dp"
                    android:layout_height="match_parent"/>

                <include
                    android:id="@+id/currency2"
                    android:layout_height="wrap_content"
                    android:layout_width="0dp"
                    android:layout_weight="1"
                    layout="@layout/single_item_foreign_exchange"/>

            </LinearLayout>

Binded inlcude layaouts

@Bind(R.id.currency1) RelativeLayout relativeLayout1;
    @Bind(R.id.currency2) RelativeLayout relativeLayout2;

SOLVED

Added onClick method to my RelativeLayaout. Then created something like this

public void onClickDataButton(View view){
        if (view == buttonEuro){
            Toast.makeText(ForeignExchangeActivity.this, "Euro", Toast.LENGTH_SHORT).show();
        } else if ( view == buttonGBP){
            Toast.makeText(ForeignExchangeActivity.this, "GBP", Toast.LENGTH_SHORT).show();
        }
    }

And my button looks like

buttonEuro = (TextView) relativeLayout1.findViewById(R.id.currencyButton);
        buttonGBP = (TextView) relativeLayout2.findViewById(R.id.currencyButton

);

so the same button id but finded in diffrent layaouts.

Esperanz0
  • 1,524
  • 13
  • 35
  • use OnClick function on buttons in XML and do what you want in your function – Farrukh Faizy Jan 25 '16 at 12:08
  • I dont have Buttons.. have only one button in one layout.. and im including this layaout multiple times – Esperanz0 Jan 25 '16 at 12:09
  • Try to create switch statements or If() logic in your onClickListener(). – Stanojkovic Jan 25 '16 at 12:14
  • I tried but i Need -> R.id.exampleButtonId,R.id.exampleButtonI2, R.id.exampleButtonId3 .. but i have only one Id ( R.id.currencyButton ) and how can i tell which button was clicked ? – Esperanz0 Jan 25 '16 at 12:18
  • I think the only way would be to check the **id** of the parent -- as it seems the buttons have different parents, am I right? [check here on how to get parent's **id**](http://stackoverflow.com/a/14112620/1582714) – LeoFarage Jan 25 '16 at 12:21
  • How can you, with one button, create different toasts with no conditions? – Stanojkovic Jan 25 '16 at 12:26
  • I see two parents - `relativeLayout1` and `relativeLayout2` – LeoFarage Jan 25 '16 at 12:27
  • I'm intrigued, why are you injecting the same view multiple times (with the same **id**) in the same parent layout? Is it for reusing the appearance? If so, why not use a *style* and add different buttons with same *style*? – LeoFarage Jan 25 '16 at 12:29
  • What I read from your code was: *find button with **id** currencyButton inside relativeLayout1* and *find button with **id** currencyButton inside relativeLayout2*. `relativeLayout1` and `relativeLayout2` from its names don't look like buttons to me. – LeoFarage Jan 25 '16 at 12:31
  • He is setting different listeners to one button in one view. – Stanojkovic Jan 25 '16 at 12:35
  • relativeLayaout its a parent for Single Layout which Im included. – Esperanz0 Jan 25 '16 at 12:35
  • @Bind(R.id.currency1) RelativeLayout relativeLayout1; @Bind(R.id.currency2) RelativeLayout relativeLayout2; – Esperanz0 Jan 25 '16 at 12:35
  • @Stanojkovic if he is doing a `findViewById` in different parents, he isn't getting the same instance twice, [check this answer](http://stackoverflow.com/a/14759249/1582714). Anyway, if by any chance they are indeed included in the same parent (`relativeLayout1 == relativeLayout2`), then I agree with you. – LeoFarage Jan 25 '16 at 12:49
  • He has edited question, he added @Bind(). – Stanojkovic Jan 25 '16 at 12:51
  • While I tend to say, that using styles instead of includes is better in this case, like LeoFarage said, you can use a custom class in any case. See if my answer below could help. (Examples are mixed for separate buttons and your case) – everyman Jan 25 '16 at 12:55
  • @Stanojkovic Sorry about that, I hadn't seen the notification for changes, but still he is binding two `RelativeLayouts`, and inside each there is a `Button` with id `R.id.currencyButton`. Anyway, I think what he is trying to do isn't a good solution, he should go with **styles** or with a **custom view**. – LeoFarage Jan 25 '16 at 13:00
  • view == clickedView inside OnClick saved my day! – Sudheesh Mohan Jun 06 '16 at 11:44

2 Answers2

0

EDIT: Example for your case added: Buttons with same ID in different layouts.

1) You could iterate over an Array of Buttons.

2) Or: Create a custom Button-Class which holds anything custom you need (i.e. field for currency etc) and use that in your Layout.

Kind of Pseudocode (not tested):

class CurrencyButton extends android.widget.Button {
     string currency;

     public void init(Context ctx, String currency) {
       this.currency = currency;

       this.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            Toast.makeText(ctx, this.currency, Toast.LENGTH_SHORT).show();
         }
       });
     }

     public void doSomeOtherFancyCurrencyLogicHere() {
       ....
     }
}

This can be used in your Layout files: (Pseudo)

<your.package.CurrencyButton 
   id="@+id/currency_button_eur"
   LayoutParams etc />

<your.package.CurrencyButton 
   id="@+id/currency_button_gbp"
   LayoutParams etc />

<!-- EDIT: as in your example with layouts in single_item_foreign_exchange -->

<your.package.CurrencyButton 
   id="@+id/currency_button"
   LayoutParams etc />

If you use Butterknife

@InjectView(R.id.currency_button_eur)
your.package.CurrencyButton buttonEUR;

@InjectView(R.id.currency_button_gbp)
your.package.CurrencyButton buttonGBP;

// ... initialize them somewhere
buttonEUR.init(this, "EUR");
buttonGPB.init(this, "GBP");

// EDIT: as in your example with layouts
((your.package.CurrencyButton) relativeLayout1.findViewById(R.id.currencyButton)).init(this, "EUR");
((your.package.CurrencyButton) relativeLayout2.findViewById(R.id.currencyButton)).init(this, "GBP");

Actually you could go even further and extend this class for each currency, but this should do it in the first place.

everyman
  • 3,377
  • 1
  • 34
  • 33
0

Ok, I've seen you have SOLVED your question. But since I was already working on this answer, I'll add it here anyway :P

class CurrencyLayout extends FrameLayout {
 String currency;

 // Constructors that calls init after super(...);

 public void init(Context ctx, AtributeSet attrs) {
   View includedLayout = LayoutInflater.fromContext(ctx).inflate(R.layout.single_item_foreign_exchange, this, false);

   TypedArray a = context.getTheme().obtainStyledAttributes(
            attrs,
            R.styleable.CurrencyLayout,
            0, 0);

    try {
        final String currency = a.getString(R.styleable.CurrencyLayout_currencyName);
    } finally {
        a.recycle();
    }

   includedLayout.findViewById(R.id.currencyName).setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
        Toast.makeText(ctx, this.currency, Toast.LENGTH_SHORT).show();
     }
   });
 }

this.addView(includedLayout);

}

inside res/values/attrs.xml add something like this:

<resources>
    <declare-styleable name="CurrencyLayout">
        <attr name="currencyName" format="string" />
    </declare-styleable>
</resources>

And inside your Activity layout:

<LinearLayout
android:layout_width="match_parent"
android:weightSum="2"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/activity_horizontal_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin">


    <your_package.CurrencyLayout
        android:id="@+id/currency1"
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="1"
        custom:currencyName="GBP"/>


    <View
        android:layout_width="10dp"
        android:layout_height="match_parent"/>

    <your_package.CurrencyLayout
        android:id="@+id/currency2"
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="1"
        custom:currencyName="EUR"/>

</LinearLayout>

I hope this helps you anyway :D

More information on custom views and attributes

LeoFarage
  • 517
  • 3
  • 16