I have a LinearLayout View with a OnClickhandler and I want to add a View after the LinearLayout programatically when the OnClick event is fired.
public void onClick(View view) {
LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout info = (LinearLayout) li.inflate(R.layout.infolayer, null);
// view.addViewAfter(info)
}
info is the View i want to add. view is the View on which the click goes and after which I want to add info.
How can I do that?
IF u want add a view after the current linear layout then first get the id of the parent layout in which the linear layout is .
for example let u have the the Linear Layout with id "ll" in relative layout(having id parentlayout) and on a button click u want add the text view under the liner layout
public void onClick(View view) {
RelativeLayout rl=new RelativeLayout(this);
TextView tv=new TextView(this)
//set param value ur requirement
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW,R.id.ll);
}
Assuming you have a known amount of linearlayouts could you just place them inside the XML resource and mark them as 'GONE'. When the event occurs make them visible. When they are marked as gone they shouldnt be taking any screen space up.
You can insert through coding and you don't need to inflate. You can create a view of any type calling the constructor and passing the context. A reference to the context can be stored on the view as a field, when the view is being constructed. This way you can always create your view on the fly.
To add the view to the LinearLayout, you just need to call addView. And afterwards, if you would want to remove it, just call removeView.
But the onClick event is inside the LinearLayout object? This might be a problem because the views inside the the LinearLayout might consume the event before it reaches your method. See this post to learn about that.
Related
I have a title as processed with three textview and an images
and then another title with same three textview.
How to create this in dynamic layout? Since I need this to generate in dynamic in android.
I am new to this. please give me an idea.
Thanks
LinearLayout mContainer;
public void onCreate(Bundle) {
setContentView(R.layout.container);
mContainer = (LinearLayout) findViewByid(R.id.coainter);
View view = layoutInflater.inflate(R.id.inflaterView);
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mContainer.addView(view,1);
Info -
create the XML you need to add the Views inside.
create the view you need to Dyanmiclly add (inflate or create it)
set the LayoutParams according to the Conatiner.
add the View to the Conatiner the number 1 is the location inside the Container.
of crouse this is an Example i just followed your image.
you can use mConatiner.addView(view) this will insert them according to the Container Choice
Hope it Helps.
I am actually developing an android application which needs to inflates many times the same XML layout.
This layout contains 2 buttons, some textViews and a progressBar which I'll need to update later. I would like to add onClick listeners to the buttons and to set custom tags with setTag() to all of these elements, so I will be able to know which button has been clicked and to modify the right textView (or progressBar).
I inflate the XML with this code :
LinearLayout countersList = (LinearLayout)findViewById(R.id.countersLayout);
View child = getLayoutInflater().inflate(R.layout.counter, null);
countersList.addView(child);
How can I access to the right view to set the tag and to add listeners? Is there a better way to do what I want to do ?
Thank you very much !
As far as how to tag or add onClick listeners to your views: You can add an ID to the views you want to tag and find them using findViewById. For example,
LinearLayout countersList = (LinearLayout)findViewById(R.id.countersLayout);
ViewGroup child = (ViewGroup) getLayoutInflater().inflate(R.layout.counter, null);
child.findViewById(R.id.myButton).setTag("myTagForTheButton");
countersList.addView(child);
On the second question, I'm not sure what your UI looks like, but many repeated views might call for using a ListView.
There is no problem of setting tags and listener
LinearLayout countersList = (LinearLayout)findViewById(R.id.countersLayout);
View child = getLayoutInflater().inflate(R.layout.counter, null);
child.setTag("YourString");
// Similarly
view.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
}
});
countersList.addView(child);
If you want it for some of its child you can also do it using findViewById
you can user view.setTag(key, tag) to many tags.
ex:
view.setTag("right_view", rightView);
i want to add Layout Dynamically on Add button click and on Dynamic Layout show Datepicker,Timepicker Dialog and set value in given Edit Text. show in image on Date Click set Date Right side . Here problem Start when Add Second Same layout and set date it set only on newly created layout
For example you need to create xml layout file with ScrollView and LinearView inside.
Then in your Activity class:
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View main = inflater.inflate(R.layout.your_layout, null);
setContentView(main);
LinearLayout linear = (LinearLayout)main.findViewById(R.id.linear_layout);
and then in onClick method just:
View yourView = inflater.inflate(R.layout.yourView, null);
// Do whatever you want with your View, set up some variables etc.
and to add your view to main view:
linear.addView(yourView);
I know that this is not a direct answer to your question, but maybe will help you with dynamically adding Views.
I know in my onCreate() I can inflate a view from XML by something like:
loadingScreen = (RelativeLayout) findViewById(R.id.loadingScreen);
But how could I do this from another view? Im trying to call up a loading screen by setting its visibility from GONE to VISIBLE but cant seem to figure out how to do this from my glSurfaceView
If you want to inflate a layout the code looks like this:
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout myRoot = new LinearLayout(context);
View itemView = inflater.inflate(R.layout.layout_details, myRoot);
Here you first create a new LinearLayout an then inflate the layout with id R.layout.layout_details into it. The inflate method then returns the myRoot view.
Here is a tutorial about the LayoutInflater:
Layout resources in Android
Thats actually not inflating. Inflating is the process that parses a XML layout file and creates a structure of View and ViewGroup class instances out of it (setContentView() does this for you in the background for example).
What you do is getting a reference to a view in code that you have defined in your XML layout file. To change the visibility of your GLSurfaceView you have to reference it like you did above. But remember that the View (GLSurfaceView in this case) has to be defined in your layout file.
After referencing you have to call GLSurfaceView.setVisibility() to change it's visibility.
Here's an example:
GLSurfaceView glsurface = (GLSurfaceView) findViewById(R.id.myglsurfaceid);
glsurface.setVisibility(View.VISIBLE);
Of course you can use View.INVISIBLE or View.GONE either, depending on what you want to do.
If you reference a layout (such as a RelativeLayout), you may find children of this layout with the findViewById() of your RelativeLayout instance:
RelativeLayour rl = (RelativeLayout) findViewById(R.id.mylayout);
(Button) mybutton = (Button) rl.findViewById(R.id.mybutton);
But thats usually not neccessary (at least when you just started with Android) because the activities findViewById() finds all Views that are displayed, even in sublayouts. You only have to use it if you have duplicate ids in your ui structure (tbh I never had that case yet) and want to specifiy where to look for your particular View.
You can't get a reference to a View that's doesn't exists in your current Layout, or your current View, (your current Activity content) , but you can create a new View from another XML layout, using LayoutInflater from current Activity.
you can add to you current Activity content, a new View, that's what you mentioned as " loading screen ", even by showing it as a Dialog or by creating View and then add it to root layout in your Activity
I hope I helped you
If I correctly understood what you wanna do:
Supposing you have a glSurfaceView object and you wanna grab a view that's inside that one.
You'll do just the same thing you did for you normal view. Let's say a button:
Button button = (Button) glSurfaceView.findViewById(R.id.buttonid);
If you meant something different let me know in the comments.
EDIT: And then you can just set the button's visibility:
button.setVisibility(Button.GONE)
Let's say I have a LinearLayout, and I want to add a View to it, in my program from the Java code. What method is used for this? I'm not asking how it's done in XML, which I do know, but rather, how can I do something along the lines of this sample code?
(One View).add(Another View)
Like one can do in Swing.
Calling addView is the correct answer, but you need to do a little more than that to get it to work.
If you create a View via a constructor (e.g., Button myButton = new Button();), you'll need to call setLayoutParams on the newly constructed view, passing in an instance of the parent view's LayoutParams inner class, before you add your newly constructed child to the parent view.
For example, you might have the following code in your onCreate() function assuming your LinearLayout has id R.id.main:
LinearLayout myLayout = findViewById(R.id.main);
Button myButton = new Button(this);
myButton.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
myLayout.addView(myButton);
Making sure to set the LayoutParams is important. Every view needs at least a layout_width and a layout_height parameter. Also getting the right inner class is important. I struggled with getting Views added to a TableRow to display properly until I figured out that I wasn't passing an instance of TableRow.LayoutParams to the child view's setLayoutParams.
The best way I found is to use the inflate static method of View.
View inflatedView = View.inflate(context, yourViewXML, yourLinearLayout);
where yourViewXML is something like R.layout.myView
please notice that you need a ViewGroup in order to add a view (which is any layout you can think of)
so as an example lets say you have a fragment which it view already been inflated and you know that the root view is a layout, and you want to add a view to it:
View view = getView(); // returns base view of the fragment
if (view == null)
return;
if (!(view instanceof ViewGroup))
return;
ViewGroup viewGroup = (ViewGroup) view;
View popup = View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);
EDIT:
Kotlin code for the example above (view is the getView() of a fragment)
(view as? ViewGroup)?.let {
View.inflate(context, R.layout.add_credit_card, it)
}
To add the view programmatically, you can do:
LinearLayout rlmain = new LinearLayout(this);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
LinearLayout ll1 = new LinearLayout (this);
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.logo);
LinearLayout .LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
iv.setLayoutParams(lp);
ll1.addView(iv);
rlmain.addView(ll1);
setContentView(rlmain, llp);
You can also add any number of views.
LinearLayout is a subclass of ViewGroup, which has a method called addView. The addView method should be what you are after.
The idea of programmatically setting constraints can be tiresome. This solution below will work for any layout whether constraint, linear, etc. Best way would be to set a placeholder i.e. a FrameLayout with proper constraints (or proper placing in other layout such as linear) at position where you would expect the programmatically created view to have.
All you need to do is inflate the view programmatically and it as a child to the FrameLayout by using addChild() method. Then during runtime your view would be inflated and placed in right position. Per Android recommendation, you should add only one childView to FrameLayout [link].
Here is what your code would look like, supposing you wish to create TextView programmatically at a particular position:
Step 1:
In your layout which would contain the view to be inflated, place a FrameLayout at the correct position and give it an id, say, "container".
Step 2
Create a layout with root element as the view you want to inflate during runtime, call the layout file as "textview.xml" :
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
</TextView>
BTW, set the layout-params of your frameLayout to wrap_content always else the frame layout will become as big as the parent i.e. the activity i.e the phone screen.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
If not set, because a child view of the frame, by default, goes to left-top of the frame layout, hence your view will simply fly to left top of the screen.
Step 3
In your onCreate method, do this :
FrameLayout frameLayout = findViewById(R.id.container);
TextView textView = (TextView) View.inflate(this, R.layout.textview, null);
frameLayout.addView(textView);
(Note that setting last parameter of findViewById to null and adding view by calling addView() on container view (frameLayout) is same as simply attaching the inflated view by passing true in 3rd parameter of findViewById(). For more, see this.)
One more way to add view from Activity
ViewGroup rootLayout = findViewById(android.R.id.content);
rootLayout.addView(view);
You guys should also make sure that when you override onLayout you HAVE to call super.onLayout with all of the properties, or the view will not be inflated!