Adding various ViewGroups to one Android Layout - android

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.

Related

App logo positioned half in the ActionBar and half on the mainActivty screen

Can something like this be achieved in Android? my guess is not since you can specify 2 different layouts one for the ActionBar and one for the Activity, but I may also be mistaken
This is a much more solid solution than the PopupWindow previously suggested.
The layout for the logo overlay is a simple ImageView, on which we've set the clickable attribute to true to prevent touch events from propagating through to Views underneath.
logo.xml layout:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher"
android:clickable="true" />
This method is meant to work with the old ActionBar, and relies on the home View as the anchor for the overlay. It is, however, easily modified to work with the support Toolbar class and its logo View, though that is probably unnecessary, since the Toolbar class is a View that can be easily setup and manipulated in layout XML.
private void showLogoOverlay() {
final View anchor = findViewById(android.R.id.home);
if(anchor == null) {
return;
}
final View overlay = getLayoutInflater().inflate(R.layout.logo, null, false);
final ViewGroup decor = (ViewGroup) getWindow().getDecorView();
anchor.addOnLayoutChangeListener(new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop,
int oldRight, int oldBottom) {
int[] offset = new int[2];
anchor.getLocationOnScreen(offset);
decor.addView(overlay, 200, 200);
overlay.setX(offset[0]);
overlay.setY(offset[1]);
anchor.removeOnLayoutChangeListener(this);
}
}
);
}

Create Scene programmatically (ViewGroup with one TextView)

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.

Android - do ViewGroup onDraw need to iterate through child view and call onDraw explicitly?

I have spent the whole day debugging various ways to add custom ViewGroup into another custom ViewGroup and nearly went crazy because none of them works, and there is no official documentation or sample that shows how it can be done...
Basically, I have 2 custom ViewGroup:
HorizontalDockView extends ViewGroup
GameEntryView extends FrameLayout
HorizontalDockView overrides onDraw, onMeasure, etc and everything is called normally and works perfectly.
However, when I create GameEntryView from inside HorizontalDockView's constructor and call addView(gameEntryView), the gameEntryView will never ever show regardless of the layoutParams, addView called from whatever thread, or however I call, load, and setContentView on the parent HorizontalDockView. If I list through the horizontalDockView.getChildAt(); all the gameEntryView objects are still there.
Hopeless, I try to debug through GameEntryView's onDraw, onMeasure, dispatchDraw methods and realized none of them actually get called! No.. not even once!
Do I need to iterate through all the child view in the parent (HorizontalDockView's) on* call and call the children's on* explicitly? I was just calling super.on*() on the parent.
I did call setWillNotDraw( false ); on both the parent and the child class.
How do I get the child to show up inside the parent's view? simple sample or existing small open source project is highly appreciated!
Thank you very much!
Did you overwrite onLayout? When Android lays out your ViewGroup, your ViewGroup is responsible for laying out the children.
This code is from a custom ViewGroup that lays out all children on top of each other:
#Override
protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) {
int count = this.getChildCount();
for (int i = 0; i < count; i++) {
View child = this.getChildAt(i);
child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
}
}
For completeness, the onMeasure override:
#Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth, parentHeight);
int count = this.getChildCount();
for (int i = 0; i < count; i++) {
View child = this.getChildAt(i);
this.measureChild(
child,
MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.EXACTLY));
}
}

Android Viewgroup: fade/blend two views on top of each other

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.

changing the position of ImageView dynamically in android

all
I need to change the position of a ImageView dynamically and iam using the following code
int x=100,y=100;
RelativeLayout.LayoutParams mparam = new RelativeLayout.LayoutParams((int)(LayoutParams.FILL_PARENT),(int)(LayoutParams.FILL_PARENT));
mparam.topMargin=x;
mparam.leftMargin=y;
ball.setLayoutParams(mparam);
x+=100;
y+=100;
but i didnt get any change.
Is it possible? and How?
You change margin, but not its position and, it seems, it's not a good solution.
Try to use method View.layout(int, int, int, int)
Documentation says:
public void layout (int l, int t, int r, int b)
Since: API Level 1
Assign a size and position to a view and all of its descendants
This is the second phase of the layout mechanism. (The first is measuring).
In this phase, each parent calls layout on all of its children to position them.
This is typically done using the child measurements that were stored in
the measure pass(). Derived classes should not override this method. Derived
classes with children should override onLayout. In that method, they should call
layout on each of their children.
Parameters
l Left position, relative to parent
t Top position, relative to parent
r Right position, relative to parent
b Bottom position, relative to parent
You can call setPadding on your View. So, in your code (which by the way you should put in a code block!), just add a call to this method:
int x=100,y=100;
LayoutParams mparam = new LayoutParams((int)(LayoutParams.FILL_PARENT),(int) (LayoutParams.FILL_PARENT));
ball.setLayoutParams(mparam);
ball.setPadding(x,y,0,0);
x+=100; y+=100;
ball.setPadding(x,y,0,0);

Categories

Resources