Java Question R.layout Hell

giga

Well-Known Member
Licensed User
Longtime User
I have been banging my head with this issue. I have seen others in Java with the issue using eclipse.

R.layout.main will not resolve. :(

I have removed the import android.R with no luck.
I have added import com.packagename.R with no luck.
I have tried to copy a res folder from another project with a main.xml in the layout folder with no luck.

The res folder will not create/regenerate when I "Clean" and "Build".

Any suggestions appreciated.

BIG THANKS, As always.

P.S Erel No fault of B4A this is a java issue I am struggling with, But I miss the "Head Banging Smiley"... Need it.
 

giga

Well-Known Member
Licensed User
Longtime User
Thanks for the reply thedesolatesoul, BTW Good work on the Backup App.

I am working on a library for B4A and the example I was working from with onCreate() method to my understanding brings in the layout.main while the activity is running.

If I can do without it I would like to remove it.

Do you have any suggestions.

B4X:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
 

thedesolatesoul

Expert
Licensed User
Longtime User
Thank you.

We probably need to understand what the library is doing.
It seems that this library contains an activity that wants to load a layout?
It is possible to do that without R. If I remember correctly the AHQuickactions loads xml layouts without R class. I can find out about that.
I dont know if you can load a b4a bal layout files with setContentView and you would prefer that.
But also do you even have R.layout.main?
If not, then how would you know what is on the layout for the activity?
 

warwound

Expert
Licensed User
Longtime User
You can compile your library with a modified R class that will correctly resolve the references to resources.

Take a look at this class where i've wrapped the Vitamio library.
The Vitamio library contains an Activity and that Activity references various resources using the R class.

B4X:
package io.vov.vitamio;

import anywheresoftware.b4a.BA;

public class R {
   public static final class attr {
   }

   public static final class drawable {
     public static int ic_launcher = BA.applicationContext.getResources().getIdentifier("ic_launcher", "drawable", BA.packageName);
     public static int mediacontroller_bg = BA.applicationContext.getResources().getIdentifier("mediacontroller_bg", "drawable", BA.packageName);
     public static int mediacontroller_pause01 = BA.applicationContext.getResources().getIdentifier("mediacontroller_pause01", "drawable", BA.packageName);
     public static int mediacontroller_pause02 = BA.applicationContext.getResources().getIdentifier("mediacontroller_pause02", "drawable", BA.packageName);
     public static int mediacontroller_pause_button = BA.applicationContext.getResources().getIdentifier("mediacontroller_pause_button", "drawable", BA.packageName);
     public static int mediacontroller_play01 = BA.applicationContext.getResources().getIdentifier("mediacontroller_play01", "drawable", BA.packageName);
     public static int mediacontroller_play02 = BA.applicationContext.getResources().getIdentifier("mediacontroller_play02", "drawable", BA.packageName);
     public static int mediacontroller_play_button = BA.applicationContext.getResources().getIdentifier("mediacontroller_play_button", "drawable", BA.packageName);
     public static int mediacontroller_seekbar = BA.applicationContext.getResources().getIdentifier("mediacontroller_seekbar", "drawable", BA.packageName);
     public static int mediacontroller_seekbar01 = BA.applicationContext.getResources().getIdentifier("mediacontroller_seekbar01", "drawable", BA.packageName);
     public static int mediacontroller_seekbar02 = BA.applicationContext.getResources().getIdentifier("mediacontroller_seekbar02", "drawable", BA.packageName);
     public static int mediacontroller_seekbar_thumb = BA.applicationContext.getResources().getIdentifier("mediacontroller_seekbar_thumb", "drawable", BA.packageName);
   }

   public static final class id {
     public static int mediacontroller_file_name = BA.applicationContext.getResources().getIdentifier("mediacontroller_file_name", "id", BA.packageName);
     public static int mediacontroller_play_pause = BA.applicationContext.getResources().getIdentifier("mediacontroller_play_pause", "id", BA.packageName);
     public static int mediacontroller_seekbar = BA.applicationContext.getResources().getIdentifier("mediacontroller_seekbar", "id", BA.packageName);
     public static int mediacontroller_time_current = BA.applicationContext.getResources().getIdentifier("mediacontroller_time_current", "id", BA.packageName);
     public static int mediacontroller_time_total = BA.applicationContext.getResources().getIdentifier("mediacontroller_time_total", "id", BA.packageName);
   }

   public static final class layout {
     public static int mediacontroller = BA.applicationContext.getResources().getIdentifier("mediacontroller", "layout", BA.packageName);
   }

   public static final class raw {
     public static int libarm = BA.applicationContext.getResources().getIdentifier("libarm", "raw", BA.packageName);
   }

   public static final class string {
     public static int mediacontroller_play_pause = BA.applicationContext.getResources().getIdentifier("mediacontroller_play_pause", "string", BA.packageName);
     public static int vitamio_init_decoders = BA.applicationContext.getResources().getIdentifier("vitamio_init_decoders", "string", BA.packageName);
     public static int vitamio_name = BA.applicationContext.getResources().getIdentifier("vitamio_name", "string", BA.packageName);
     public static int vitamio_videoview_error_button = BA.applicationContext.getResources().getIdentifier("vitamio_videoview_error_button", "string", BA.packageName);
     public static int vitamio_videoview_error_text_invalid_progressive_playback = BA.applicationContext.getResources().getIdentifier("vitamio_videoview_error_text_invalid_progressive_playback", "string", BA.packageName);
     public static int vitamio_videoview_error_text_unknown = BA.applicationContext.getResources().getIdentifier("vitamio_videoview_error_text_unknown", "string", BA.packageName);
     public static int vitamio_videoview_error_title = BA.applicationContext.getResources().getIdentifier("vitamio_videoview_error_title", "string", BA.packageName);
   }

   public static final class style {
     public static int MediaController_SeekBar = BA.applicationContext.getResources().getIdentifier("MediaController_SeekBar", "style", BA.packageName);
     public static int MediaController_Text = BA.applicationContext.getResources().getIdentifier("MediaController_Text", "style", BA.packageName);
   }

}

If i was compiling a 'standard' java android app in eclipse then the compilier would automatically create an R class but as i'm creating a B4A library i have had to manually create the R class.

You need to ensure that the R class you create has the correct package name - the same package name as the classes that reference this R class.
So if you have a class named MyClass in package com.mylibrary and MyClass uses the R class to reference resources then it's looking for the class com.mylibrary.R.

Martin.
 

bloxa69

Active Member
Licensed User
Longtime User
Martin,
thank you for that custom R class example / idea. I was starting to get lost in all those getResources() and so on. My java code is much cleaner now.

Also I was trying to find a way to add views from within B4A to a xml layout loaded by a library, but as soon as it happens, B4A cannot add any views to activity using regular B4A code.
 

warwound

Expert
Licensed User
Longtime User
Also I was trying to find a way to add views from within B4A to a xml layout loaded by a library, but as soon as it happens, B4A cannot add any views to activity using regular B4A code.

Look at the inflated xml Layout - is it a LinearLayout, RelativeLayout, FrameLayout, ViewGroup etc.
  • Which java methods does this Layout support in order to add child Views to it?
  • What type of java class objects do these methods require?

If the standard b4a AddView method does not work you will need to create your own new method that enables b4a Views to be added to the inflated xml layout.

Martin.
 

bloxa69

Active Member
Licensed User
Longtime User
Look at the inflated xml Layout - is it a LinearLayout, RelativeLayout, FrameLayout, ViewGroup etc.
  • Which java methods does this Layout support in order to add child Views to it?
  • What type of java class objects do these methods require?

If the standard b4a AddView method does not work you will need to create your own new method that enables b4a Views to be added to the inflated xml layout.

Martin.

thanks Martin, that's what I figured sofar - if you load XML layout from the library, you have to create methods in your library to add or modify views as B4A doesn't see anything loaded from that XML layout.
 

warwound

Expert
Licensed User
Longtime User
An idea...

You can create b4a Views in library java as well as in b4a code.
So in your library code you could create a Panel and add it to your inflated xml layout.
Keep a reference to this panel and create a getter method:

B4X:
public class MyClass {
   private PanelWrapper mPanel;
   
   public void CreatePanel(BA pBA, String EventName){
     PanelWrapper panel=new PanelWrapper();
     panel.Initialize(pBA, EventName);
     
     ViewGroup viewGroup=panel.getObject();
     //   now add the ViewGroup to your inflated xml layout
     
     mPanel=panel;
   }
   
   public PanelWrapper GetPanel(){
     return mPanel;
   }
}

Your library user can now get a reference to the b4a Panel object and use all the b4a methods and properties of the Panel with b4a code.

Martin.
 

bloxa69

Active Member
Licensed User
Longtime User
thanks Martin, DesolateSoul - great example, I'll sure use that one

now I'm trying to access a view created in B4A from Java lib code by using the view name:

B4X:
int id = pBA.activity.getResources().getIdentifier(panelName, "id", pBA.context.getPackageName());
      Common.Log("id found: "+id); //it finds ID OK, no problem here
//these lines give null pointer error
      ViewGroup container = (ViewGroup)pBA.activity.findViewById(id);
      Common.Log("container found - width: "+container.getWidth());

I guess I should use PanelWrapper instead of ViewGroup but it looks like findViewById method doesn't work with it.
When I use PanelWrapper instead of ViewGroup it says "cannot cast from View to PanelWrapper".
 

warwound

Expert
Licensed User
Longtime User
It'll probably not work using findViewById.
The b4a View will have an id assigned to it created in b4a but that id is I think an integer.
Get JDGUI and look in the b4a library core.jar and you'll get a better idea of what the various Views are and how you can work with them.

Martin.
 
Top