I usually prefer to work with classes instead of XML.
Now this is the ordinary way of creating a scene:
TransitionInflater inflater = TransitionInflater.from(this);
ViewGroup mSceneRoot = (ViewGroup) findViewById(R.id.sceneRoot);
Scene mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.transition_event,this);
TransitionManager mTransitionManager = inflater.inflateTransitionManager(R.anim.transitions_mgr, mSceneRoot);
mTransitionManager.transitionTo(mScene2);
Pretty neat. Since the R.layout.transition_event is only a TextView, it creates the following layouts. LinearLayout is the root.
For making things happen programmatically we can use the Scene(ViewGroup sceneRoot, ViewGroup layout) constructor instead of Scene.getSceneForLayout(..).
My problem is the ViewGroup layout parameter. Since I want to have only one textview, if I create a FrameLayout and add the textview this will create an extra view as the above screenshot which is not the same.
I either need something like <merge/> but programmatically or "convert" TextView into a ViewGroup.
Here is my best try so far:
# I try to do the equivalent of .getSceneForLayout() here
ViewGroup vg = new ViewGroup(MainActivity.this) {
#Override
protected void onLayout(boolean b, int i, int i2, int i3, int i4) {
}
};
TextView tv = new TextView(MainActivity.this);
tv.setText("YOLO!");
vg.addView(tv,0);
mScene2 = new Scene(mSceneRoot, vg);
Which btw produces:
No sure if worths the hustle but I want to figure this out.
Related
I want to get all views inside of an activity. like;
ArrayList<View> views = new Arraylist<>();
views.addAll(getAllViewsFromActivity());
what I want is "getAllViewsFromActivity()" function. I clearly want to get all the views even a single button. But I couldn't find any clear answer.
For the progress, it must be like this:
MainView : getWindow().getDecorView()
- -
RelativeLayout
- -
Button LinearLayout
-
TextView
How can I get this tree in Android programmatically? and also lets assume that I got this tree, Can I also identify the types of them like: view instanceof Button ?
the view you want to get is clear. so you can use the parent view(such as LinerarLayout) to get the children. so you can try this:
int count = parent.getChildCount();
for(int i =0; i< count;i++){
View child = parent.getChildAt(i);
//here you can to chage the view some proper.
//if you only want to change the background color, it belongs to view, don't
// need to cast.
}
I'm trying to animate the add/remove actions of the views of an LinearLayout that has it's height set as wrap_content.
Currently I've tried setting android:animateLayoutChanges="true" for the LinearLayout and programmatically enabling the transitions like this:
LayoutTransition transition = new LayoutTransition();
transition.setDuration(300);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
transition.enableTransitionType(LayoutTransition.APPEARING);
transition.enableTransitionType(LayoutTransition.DISAPPEARING);
transition.setAnimateParentHierarchy(true);
}
container.setLayoutTransition(transition);
The Appearing seems to work very smooth and it animates and resizes as I want.
The issue I'm having is with Disappearing as the LinearLayout container is resized before the remove animation is finished.
I've also tried playing around with the setAnimateParentHierarchy() and it doesn't seem to really affect on how and when the resize of the container is done.
A simple solution is to set a layout transition to the first ancestor which does not use wrap_content.
The following code finds the correct anscestor, sets the required animation and restore the original LayoutTransition (if any existed) at the end of the animation.
Call this method in your code where you perform the add/remove actions.
None of your code which is included in the question is required.
Note: This solution will only work for SDK >= JELLY_BEAN.
private static void setHeightChangeAnimation(ViewGroup animatedLayout) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ViewGroup vg = animatedLayout;
while (vg instanceof ViewGroup) {
vg = (ViewGroup) vg.getParent();
if (vg instanceof ViewGroup && vg.getLayoutParams().height != LayoutParams.WRAP_CONTENT) {
LayoutTransition animatedLayoutLt = animatedLayout.getLayoutTransition();
LayoutTransition lt = new LayoutTransition();
lt.enableTransitionType(LayoutTransition.CHANGING);
lt.setDuration(animatedLayoutLt.getDuration(LayoutTransition.CHANGE_APPEARING));
lt.setStartDelay(LayoutTransition.CHANGING, animatedLayoutLt.getStartDelay(LayoutTransition.APPEARING));
final ViewGroup finalVg = vg;
final LayoutTransition oldLt = finalVg.getLayoutTransition();
lt.addTransitionListener(new LayoutTransition.TransitionListener() {
public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {}
public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
finalVg.setLayoutTransition(oldLt);
}
});
finalVg.setLayoutTransition(lt);
break;
}
}
}
}
And use this to call:
setHeightChangeAnimation(yourAnimatedLinearLayout);
I want to fade from one view to another on in a ViewGroup.
At the moment I'm doing the transition using setAlpha, but the problem is that only one view is being rendered, the one that was on top and is fading out.
Is the view-array inside ViewGroup an order by z-axis?
Is only the top view being rendered?
My layout method looks like this:
#Override
protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) {
L.debug("laying out {} children", this.getChildCount());
for (int i = 0; i < this.getChildCount(); i++) {
L.debug("layout out {}", i);
View view = this.getChildAt(0);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}
}
Why don't you want to use ViewSwitcher? It does exactly what you want. Here is an example.
Is the view-array inside ViewGroup an order by z-axis?
There is no such thing like Z-order in android. Views are drawn in oder they were added to ViewGroup. First added draws first.
Is only the top view being rendered
No, android will draw all views in visible rect even if they are totally overlaped by others.
I think you should fix this place this.getChildAt(0) and layout all childrens in your ViewGroup.
I have an Android 3.0 Application for Tablets. On this application I have to insert several ViewsGroup on a layout, and each of these ViewsGroup has several views.
Here is the onCreate code of the Activity:
setContentView(R.layout.main);
params = new LayoutParams(500, 600);
ViewGroup v1 = new Bar(this);
this.addView(v1,params);
ViewGroup v2 = new Bar(this);
this.addView(v2,params);
This Bar class extends ViewGroup, and has several views inside it. The problem is that only the Views of the first ViewGroup (v1) are being shown on the screen. But I can see that it add both ViewGroup to the content, since for example I can set the background of the second one and i will see the results. But the Views that are inside the second ViewGroup are not being drawn on the screen. I tried to change the order, v2 first, and all views inside v2 got drawn while the ones in v1 didn't. I think it may have some to do with the onLayout method inside the Bar class, which I'll put below:
#Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
for(int nI = 0; nI < this.getChildCount(); nI++){
this.getChildAt(nI).layout(arg1, arg2, arg3, arg4);
}
}
Does this method has any problems?
I' using a LinearLayout by the way.
<LinearLayout android:background="#C6D7D2" android:orientation="horizontal" android:id="#+id/container" android:layout_width="wrap_content" android:layout_height="wrap_content"> </LinearLayout>
You should override onMeasure() also. You need to set the setMeasuredDimension(w,h) there. w and h are bar's height and width that you get after adding all its childrens dimensions.
I'm working on an extension of BaseExpandableListAdapter, and have the following implementation of getChildView():
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
AbsListView.LayoutParams lp = new AbsListView.LayoutParams
(ViewGroup.LayoutParams.FILL_PARENT, 48);
RelativeLayout layout = new RelativeLayout(myExpandableListActivity.this);
layout.setLayoutParams(lp);
TextView name = new TextView(myExpandableListActivity.this);
name.setText("testing...");
layout.addView(name);
return layout;
}
This code is working, and when I run the application, expand a group and click on a child, the parent application is able to detect onChildClick() correctly.
However, I notice that the onChildClick() does not work anymore if I don't call the setLayoutParms(). My question is, what is happening when I assign AbsListView.LayoutParams to the child view being returned? Why is this required to have my onChildClick() respond in the parent application?
Thanks in advance!
After playing with other parts of the code some more, it looks like leaving out setLayoutParms() was not what was causing my onChildClick() to not work. I was also using a layout inflater to set up my RelativeLayout, which included a CheckBox. Turns out it was the CheckBox that was causing the child to be unclickable, something that I'll have to look into further.
RelativeLayout spellLayout = (RelativeLayout)
getLayoutInflater().inflate(R.layout.testLayout, null);
Thanks for reading!