Access custom view properties after inflation in Android - android

I have an activity with a LinearLayout which I want to add multiple buttons to. These buttons are Custom Views which I inflate. I need to add these custom buttons to my Linear Layout in code. All of this works.
What I cant get to work is to use findViewById in my custom button after I have inflated it so I can set its properties. findViewById returns null.
Activity Code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.levelbrowser);
LinearLayout uttonLayout = (LinearLayout)findViewById(R.id.ButtonLayout);
LevelBrowserButton button1 = new LevelBrowserButton(this, "Level 1");
ButtonLayout.addView(button1);
}
Custom Button Code:
public LevelBrowserButton(Context context, String name)
{
super(context);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.levelbrowser_button, this);
TextView nameTextView = (TextView) layout.findViewById(R.id.NameTextView);
// nameTextView = null!
NameTextView.setText("test"); // This will throw an exception
}
I have read through many posts on the internet and still cant get this to work. I have also tried "Clean..." in Eclipse on my project.

Related

findViewById() returns null for an inflated layout

I have an Activity and its layout. Now I need to add a LinearLayout from another layout, menu_layout.xml.
LayoutInflater inflater;
inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.menu_layout, null);
After this, findViewById() returns null. Is there is any solution for that?
Note: I can't put both XML in one place, and using <include> also is not working.
Explanation
When you inflate a layout, the layout is not in the UI yet, meaning the user will not be able to see it until it's been added. To do this, you must get a hold of a ViewGroup (LinearLayout,RelativeLayout,etc) and add the inflated View to it. Once they're added, you can work on them as you would with any other views including the findViewById method, adding listeners, changing properties, etc
Code
//Inside onCreate for example
setContentView(R.layout.main); //Sets the content of your activity
View otherLayout = LayoutInflater.from(this).inflate(R.layout.other,null);
//You can access them here, before adding `otherLayout` to your activity
TextView example = (TextView) otherLayout.findViewById(R.id.exampleTextView);
//This container needs to be inside main.xml
LinearLayout container = (LinearLayout)findViewById(R.id.container);
//Add the inflated view to the container
container.addView(otherLayout);
//Or access them once they're added
TextView example2 = (TextView) findViewById(R.id.exampleTextView);
//For example, adding a listener to the new layout
otherLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Your thing
}
});
Assuming
main.xml contains a LinearLayout with the id container
other.xml is a layout file in your project
other.xml contains a TextView with the id exampleTextView
Try using
layoutObject.findViewById();

how to display new activity over another activity?

i have an activity that displays two buttons , on click of call button i want to show another activity as shown in image.
Please help .How to achieve this
One way to do it is to have a custom layout which you add to each activity with a viewgroup as such:
private View view;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewGroup parent = (ViewGroup) findViewById(R.id.linearLayout1);
view = LayoutInflater.from(getBaseContext()).inflate(R.layout.custom_layout,
null);
parent.addView(view);
Then you just need to implement your listeners and whatnot further down :)
You need to create xml file of these two buttons and add that new xml into old one by using Layout Inflator. for e.g
1) your new xml
LayoutInflator buttons = LayoutInflater.from(getBaseContext()).inflate(R.layout.buttons,
currentxml, false);
2) your old xml parent referenced through id -->
RelativeLayout relativeLayout = (RelatveLayout) findViewById(R.id.oldxml);
3) now add..
relativeLayout.addView(buttons);
You can Use Pop up By Adding this in your function. Popuser is a xml file which you want to inflate.
public void popupshow(){
try{
LayoutInflater inflater=(LayoutInflater)SRSDMain.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Display display=getWindowManager().getDefaultDisplay();
int width=display.getWidth()/2;
int height=display.getHeight()/2;
View pop=inflater.inflate(R.layout.popupuser,null,false);
pop.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED);
height=pop.getMeasuredHeight();
width=pop.getMeasuredWidth()+50;
pu=new PopupWindow(pop,width,height,true);
pu.showAtLocation(findViewById(R.id.ll3),Gravity.CENTER,1,1);
Button btn=(Button)pu.getContentView().findViewById(R.id.button);
btn.getBackground().setColorFilter(new LightingColorFilter(0xFF505450,0xFF101010));
btn.setTextColor(Color.WHITE);
btn.setTypeface(null,Typeface.BOLD);
btn.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
//anything you want to do
pu.dismiss();
}
});
}
catch(Exception ex){
//Catch The Exception
}
}
}

Android: Load Layout-File dynamically

I have a question about Android.
Assume we have our main xml layout file, and defining there a place holder by using (for example) a FrameLayout. Also assume we have 2 other xml layout files displaying any content.
So what I want to do is inject dynamically and programmtically one of the two layouts into the place holder. I know there exists the concept of Activitis, Fragments, ViewFlipper etc. But I find it comfortable to do things like this:
public class MainActivity extends Activity {
private FrameLayout placeHolder;
private View view1;
private View view2;
private RelativeLayout canvasPlaceHolder;
private PuzzleCanvas canvas;
private TextView infoLabel;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init gui
setContentView(R.layout.activity_main);
// Load layouts from xml
LayoutInflater factory = getLayoutInflater();
view1 = factory.inflate(R.layout.view1, null);
view2 = factory.inflate(R.layout.view2, null);
}
}
with for example a Button on screen that does something like this:
#Override
public void onClick(View v) {
placeHolder.removeView(view1);
placeHolder.addView(view2);
}
For example to show a loadingAnimation (view2) instead of the normal content (view1) and so I can define both views comfortable and independent in xml.
Is the use of LayoutInflater commendable? What about the performance and memory management? What do you think about this? Is that a common way in Android?
Use 'include ' tag on the xml's frame layout to include both your xml's in the main xml. All you have to do is switch their ' VISIBILITY' through java according to ur app logic.
eg: on a listener, set :
public void onClick(View v) {
innerView1.setVisibilty(View.INVISIBLE);
innerView2. setVisibilty(View.VISIBLE);
}
// Load layouts from xml
LayoutInflater factory = getLayoutInflater();
view1 = factory.inflate(R.layout.view1, null);
view2 = factory.inflate(R.layout.view2, null);
Using LayoutInflater is ok, but I suggest not directly do this action in onCreate, if your layout is very complex, it might cause ANR (draw layout over 5 secs). Since these two views only appears after user reaction, I prefer to do with sendEmptyMessage with handler.
onCreate(...){
handler.sendEmptyMessage(1);
}
private Handler handler = new Handler(){
#Override
public void handleMessage(final Message msgs) {
if(msgs.what == 1){
view1 = factory.inflate(R.layout.view1, null);
view2 = factory.inflate(R.layout.view2, null);
}
}
}

findViewById in specific layout?

Instead of prefixing id's in xml, is it possible to specify the particular layout in code? For example, if I have 3 layouts, each with a button that has an id of "btn". Is it possible to specify which layout to findViewById(R.id.btn) in?
The basic context is defined via setContentView(R.lyaout.my_layout). If you inflate another layout using LayoutInflater.inflate() you get a layout object, lets call it buttonLayout. You can now differ between this.findViewById(R.id.button) and buttonLayout.findViewById(R.id.button) and both will give you different button references.
findViewById is a method of the View class. You can specify where the view should be searched for like that
final View container = new View(context);
container.findViewById(R.id.btn);
If your content view is a complex hierarchy that has several views with id btn, you will need to navigate to a subtree of the hierarchy and search from there. Suppose you have three LinearLayout views, each with a btn view somewhere in it. If you can first select the correct LinearLayout (by id, tag, position, or some other means), you can then find the correct btn view. If the relevant LinearLayout has id of branch1, for instance:
View parent = findViewById(R.id.branch1); // Activity method
View btn = parent.findViewById(R.id.btn); // View method
if you have your btns inside different Viewgroups, it is possible, but requires to give ViewGroups a different name! Easyiest will be for that purpose to define the Layout of the Button inside its own XML (i.e button_layout.xml)
inside your Activity you can do this:
public MyActivity extends Activity{
Button btn1, btn2, btn3;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
LinearLayout ll = new LinearLayout(this);
setContentView(ll);
btn1 = (Button)inflater.inflate(R.layout.button_layout, ll);
btn2 = (Button)inflater.inflate(R.layout.button_layout, ll);
btn3 = (Button)inflater.inflate(R.layout.button_layout, ll);
}
}

How to get layout components not on an Acitivty's own layout

I'm trying to manipulate components not on an Activity's own layout view. How would I reference them?
I have the resource ID but when I try to reference them using:
DatePicker date = ((DatePicker) findViewById(resID));
.. I get a NullPointerException.
If you want to get views in different layout xml file, the best practice is to use a LayoutInflater to inflate(load) these files. You can do something like this:
LayoutInflater inflater;
View firstView;
View secondView;
Button aboutFirst;
Button aboutSecond;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);//initialize the layout inflater
firstView = inflater.inflate(R.layout.firstview, null); // inflate firstview.xml layout file
secondView = inflater.inflate(R.layout.secondview, null);//inflate secondview.xml layout file
aboutFirst = (Button) firstView.findViewById(R.id.button1);//get button in firstview.xml
aboutSecond = (Button) secondView.findViewById(R.id.button1);//get button in secondview.xml
}
The only solution that I found to this was to change the current content view to the one that holds the View you're trying to find:
setContentView(R.layout.second_layout);
DatePicker date = ((DatePicker)findViewById(resID));
setContentView(R.layout.main);
then changing back to the original layout. I'm still looking for a better solution, but this is what I've got currently.

Categories

Resources