In my activity there are two views. Both are in different parents. I have their coordinates with respect to the screen. How to interchange the location of the two views?
You will need to call the parent ViewGroup method removeView() for both views then addView() to add them back but swapper about.
So if your parent views are called mommy and daddy, one has a child called foo, the other a child called bar:
ViewGroup daddy = (ViewGroup)findViewById(R.id.daddy);
ViewGroup mommy = (ViewGroup)findViewById(R.id.mommy);
View foo = findViewById(R.id.foo);
View bar = findViewById(R.id.bar);
//detach children
daddy.removeView(foo);
mommy.removeView(bar);
//re-attach children
daddy.addView(bar);
mommy.addView(foo);
Read the reference for ViewGroup for more information about the removeView and addView methods and to see other available methods.
Try this:
int x1 = view1.getX();
int y1 = view1.getY();
view1.setX(view2.getX());
view1.setY(view2.getY());
view2.setX(x1);
view2.setY(y1);
You could also consider an animation effect to make this look nice.
Related
I have a list of type Foo with a custom array Adapter. I want to be able to click on a child element in one of the views in the array adapter and get back the view I clicked on of type Foo.
This is how I am clicking on a child element:
// fill array with a test set of objects
final ArrayList<Foo> locations = Foo.getTestingList();
final myCustomArrayAdapter adapter = new myCustomArrayAdapter(rootView.getContext(), myarrayList);
adapter.setDefaultRequestBtnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
//if child element is clicked
if(v.getId() == R.id.deleteBTN){
//tag is set to the position in my custom adapter
int pos = (Integer)v.getTag();
//Get this child's parent view (type foo)
}
}
});
I want to be able to use certain Foo methods on the Fooparent of the child View I just clicked on.
If you wanna get the direct parent of a view, you can call the method getParent() and it will return immediate parent of the target view. Note, this method doesn't directly return a view but instead a ViewParent. ViewParent does not technically need to be a View but all views capable of holding child views i.e. a "view parent" in the Android SDK are of type ViewGroup which itself implements the ViewParent. So in reality virtually all ViewParents are a ViewGroup, which in itself is a View.
Furthermore, if you wanna access an ancestor view that's beyond the direct parent, you can recursively call getParent() and perform checks on the return parent view to determine if they are the desired view.
I've add five views on frameLayout.
how to re arrange the childIndex of framelayout.
i use below code:
fromindex = 3;
toindex = 4;
View tempFrom = frameLayout.getChildAt(fromindex);
View tempTo = frameLayout.getChildAt(toindex);
frameLayout.removeViewAt(fromindex)
frameLayout.removeViewAt(toindex)
frameLayout.addView(tempFrom, toindex)
frameLayout.addView(tempTo,fromindex)
But its throws the below error.
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
How to re arrange the childindex of framelayout ?
how to re arrange the childIndex of framelayout.
The FrameLayout doesn't have the ability to re arrange its children directly but you can do it by removing those children and re adding them in the right positions. Your code doesn't work because you remove the views in an incorrect order resulting in views still being attached to the parent:
fromindex = 3;
toindex = 4;
View tempFrom = frameLayout.getChildAt(fromindex);
View tempTo = frameLayout.getChildAt(toindex);
// first remove the view which is above in the parent's stack
// otherwise, if you remove the other child you'll call the `removeViewAt`
// method with the wrong index and the view which was supposed to be detached
// from the parent is still attached to it
frameLayout.removeViewAt(toindex);
frameLayout.removeViewAt(fromindex);
// first add the child which is lower in the hierarchy so you add the views
// in the correct order
frameLayout.addView(tempTo,fromindex)
frameLayout.addView(tempFrom, toindex)
Try this code
frameLayout.removeView(tempFrom) //to remove views
frameLayout.removeView(tempTo)
You can't swap views I think. You need to define new view group and inflate to his parent and remove old one.
View C = findViewById(R.id.C);
ViewGroup parent = (ViewGroup) C.getParent();
int index = parent.indexOfChild(C);
parent.removeView(C);
C = getLayoutInflater().inflate(optionId, parent, false);
parent.addView(C, index);
Okay so I do this (not actual code)
try {
final View view = LayoutInflater.from(context).inflate(R.layout.ownComponent, null);
} catch (InflateExpection e) {
}
if (view != null) {
// This child is null about 5/10 times!
View child = view.findViewById(R.id.ownComponentChild);
}
I read that after inflate it is not guaranteed that child views are inflated, so what would be neat way to get callback when all childs are ready?
Maybe I misunderstood what you're trying to do, but it seems like you're inflating a View and not a layout...
Try
View view = LayoutInflater.from(context).inflate(R.layout.LAYOUT_THAT_HOLDS_ownComponent, this, true);
and then view will hold the entire layout, from which you can find the child by Id with
view.findViewById(...);
Edit:
Hard to know if it's related as you didn't post enough code but try this:
Get the View view out of the try/catch and put it as a class member. loose the final and cast the child.
example (assuming ownComponentChild is a FrameLayout):
FrameLayout child = (FrameLayout)view.findViewById(R.id.ownComponentChild);
This seems to happen randomly so my only guess is that memory is getting low in this case, because I have to recreate so many UI components fast to get this reproduced.
I have a ViewSwitcher and want to add views to it:
// initialize views
final ViewSwitcher switcher = new ViewSwitcher(this);
layMenu = (LinearLayout)findViewById(R.id.menu_main_view);
final LevelPicker levelPicker = new LevelPicker(getApplicationContext());
(//)switcher.addView(layMenu);
(//)switcher.addView(findViewById(R.layout.menu_switcher));
One is a custom view, the other one from XML. I commented one of them, but they both seem to throwIllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
I tried doing several things like putting the views in a 'container' first (another layout), or tried removeView((View)getParent), like I believe the logcat tries to say..
Here's my xml file (in a nutshell):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menu_main_view">
<TextView>
</TextView>
<LinearLayout>
<Button></Button> //couple of buttons
</LinearLayout>
</LinearLayout> //this is the parent i guess
My first guess was that all childs had to be in 1 parent, which in my case is the LinearLayout. This didn't seem to work.
Thanks
yes any View instance should have only 1 parent according to the source file
{android}/frameworks/base/core/java/android/view/View.java
in order to remove a View instance from its container, you need to do following things:
// View view = ...
ViewParent parent = view.getParent();
if (parent instanceof ViewGroup) {
ViewGroup group = (ViewGroup) parent;
group.removeView(view);
}
else {
throw new UnsupportedOperationException();
}
I guess you invoked Activity.this.setContentView(R.layout....) on the xml layout file. in this case, the parent of the LinearLayout view was another LinearLayout instance provided by a "decorate window".
it's often not a good practice to remove the only child of the "decorate window". you'd better create the children of the ViewSwitcher explicitly:
// Activity.this.setContentView(viewSwitcher);
// final Context context = Activity.this;
final android.view.LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View layMenu = inflater.inflate(R.layout...., null /* container */);
final View menuSwitcher = inflater.inflate(R.layout...., null /* container */);
viewSwitcher.addView(layMenu);
viewSwitcher.addView(menuSwitcher);
I need to get an dynamically added view position in LinearLayout with vertical orientation.
For example i have 4 TextViews added dynamically on LinearLayout, then i need to change position of text colour at 3rd position will be in different color.How can i achieve it by getting position of added views.
You can do it just like that
ViewGroup parent;
int position;
for(int i = 0; i < parent.getChildCount(); ++i) {
int currentViewId = parent.getChildAt(i).getId();
if(currentViewId == wantendViewId) {
position = i;
}
}
That's (in my opinion) the simplest way
If you always know the number of TextViews in your LinearLayout, you can just use the function getChildAt( int position ). This returns a View which you can then cast to a TextView to be able to perform the desired operations.
If you do not know the number of elements you could set the id of each TextView (in order to be able to identify a particular one) and then run through them like this:
for( View view : myLinearLayout )
if( view instanceof TextView && view.getId().equals( idToSearchFor ) )
//Do what needs to be done.
I see following options:
Declare some id's in resources in form of <item type="id">first</item> and assign them to
views in adding to layout, after that use normal findViewById() mechanism
Assign some tags to views you're adding to a layout via setTag method and after that use findViewWithTag mechanism
Remeber position of your views and use them vie getChildAt method
I got simple option.
suppose you add
View v;//any view
linearlayout.addview(v);//add in layout
While u want to modify view.
simpaly remove old view.
linearlayout.removeView(v);
add new update view object
v-updated new view
linearlayout.addview(v);