0

I am building an android app and I am accssing the UI elements with the following method :

FindViewById

The thing is it looks like I cannot access elements that are not in the currently opened layout.
Is that possible ? If so, how can I access elements that are not in the currently loaded layout.

SetContentView (Resource.Layout.CameraLayout);

Button button1 = FindViewById<Button> (Resource.Id.firstButton);
Button button2 = FindViewById<Button> (Resource.Id.secondButton);

button1.Click += (s,e) => {//do stuff}; // In CameraLayout layout.
button2.Click += (s,e) => {//do stuff}; // Not in CameraLayout layout.

This line will throw the null exception : button2.Click += (s,e) => {//do stuff};

But if I change it to :

SetContentView (Resource.Layout.AnotherLayout);

Button button1 = FindViewById<Button> (Resource.Id.firstButton);
Button button2 = FindViewById<Button> (Resource.Id.secondButton);

button1.Click += (s,e) => {//do stuff}; // Not AnotherLayout layout.
button2.Click += (s,e) => {//do stuff}; // In AnotherLayout layout.

This line will throw the null exception : button1.Click += (s,e) => {//do stuff};

So I can only access elements form the currently loaded layout. I highly doubt that there is no way to access the other elements but I still can't find how.

phadaphunk
  • 12,785
  • 15
  • 73
  • 107
  • 1
    Why do you want to do that? – Szymon Dec 31 '13 at 04:33
  • See this answer http://stackoverflow.com/a/2271955/604493 – Ahmed Dec 31 '13 at 04:33
  • you would have to `inflate` the target layout that contain's the `secondButton` ..See [this](http://stackoverflow.com/questions/2271570/android-findviewbyid-finding-view-by-id-when-view-is-not-on-the-same-layout-in) Though if you are doing that you would have to reconsider your design.. – Anirudha Dec 31 '13 at 04:33
  • Inflate the layout whose element you want to access and then access it by `FindViewById` otherwise you will get only the current layout element which you have set in `SetContentView` –  Dec 31 '13 at 04:35
  • 1
    @Szymon Only to realize how bad my design is. Thanks guys I won't inflate anything because my design is the only reason why I have this problem. But it's good to know so you might want to post it as an answer. – phadaphunk Dec 31 '13 at 04:38

5 Answers5

2

Inflate the layout whose element you want to access and then access it by FindViewById otherwise you will get only the current layout element which you have set in SetContentView.

1

Each Activity has its own layout UI and it is defined by SetContentView() inside OnCreate() method.

In case you want to work with Objects (Views...) in another layout, you need to call those layout out, that is, inflate() to get the root layout, from here, use the root layout to access inner elements.

View rootInAnotherLayout = this.LayoutInflater.Inflate(
                                Resource.Layout.AnotherLayout,  // blah blah ...);

Button button1 = rootInAnotherLayout.FindViewById<Button> (Resource.Id.firstButton);
Button button2 = rootInAnotherLayout.FindViewById<Button> (Resource.Id.secondButton);

So button1 and button1 are the two Views from AnotherLayout, not this layout.

Pete Houston
  • 14,931
  • 6
  • 47
  • 60
1

General design is that you inflate one layout and use setContentView for that one layout only. Then you have access to all visual elements in that layout.

You may consider redesigning your solution if the current design forces you to inflate more than one layout.

Szymon
  • 42,577
  • 16
  • 96
  • 114
0

I am not sure if I understood your question properly. But hope my answer helps.

Before you access your view by using findViewById you have to add the view id in the resource file by using @+id. This can be done as follows:

<Button
    android:id="@+id/firstButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="receiveMessage"
    android:text="@string/button2_text" />

and then save the file. You will be able to access this in your method. To know more here is the literature from google

The at sign (@) is required when you're referring to any resource object from XML. It is followed by the resource type (id in this case), a slash, then the resource name (edit_message).

The plus sign (+) before the resource type is needed only when you're defining a resource ID for the first time. When you compile the app, the SDK tools use the ID name to create a new resource ID in your project's gen/R.java file that refers to the EditText element. Once the resource ID is declared once this way, other references to the ID do not need the plus sign. Using the plus sign is necessary only when specifying a new resource ID and not needed for concrete resources such as strings or layouts. See the sidebox for more information about resource objects.

Hope this helps.

poortechworker
  • 627
  • 1
  • 6
  • 21
0

The workaround is to access the root of a layout using LayoutInflater.

The code is the following, where this is an Activity:

LayoutInflater factory = (LayoutInflater)Application.Context.GetSystemService(LayoutInflaterService);

View mView = factory.Inflate(Resource.Layout.TheOtherLayout, null);

And now you can get required references by:

TextView mTextView = mView.FindViewById<TextView>(Resource.Id.textView);
ImageView mImageView = mView.FindViewById<ImageView>(Resource.Id.imageView);

//And so on....
Divins Mathew
  • 2,908
  • 4
  • 22
  • 34