0

I have a parent RelativeLayout that I want to use as a container to hold a number of item views. Imagine shuffling a pack of cards and seeing a visual stack of cards, slightly skewed from each other, on top of one another like a stack. I have achieved this by iterating over the collection, inflaying a layout XML file which is the template for each "card" and populating it with that items details, before adding that view to the parent RelativeLayout, setting the X, Y, and rotation properties.

This works, however each card is the same width and height as the parent RelativeLayout so that if they are not rotated, they take up the entire parent layout. The ones that are rotated, their corners disappear out of the bounds of the RelativeLayout and you cannot see them.

What I want is for each child View to have a width and height of say 90% of the parent RelativeLayout so that with the rotating of the layered views on the stack, you can see the corners of the ones beneath coming out the sides. I cannot figure out how to do this though.

This is the parent RelativeLayout

<RelativeLayout 
            android:id="@+id/layoutview"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_above="@id/tayle_buttons"
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent"
            android:background="#005500"/>

This is the onCreateView() method of my fragment

View rootView = inflater.inflate(R.layout.fragment_tayleresults, container, false);             
        windowwidth = m_windowManager.getDefaultDisplay().getWidth();       
        screenCenter = windowwidth / 2;     

        parentView = (RelativeLayout) rootView.findViewById(R.id.layoutview);

And this is the code which populates each child view (unnecessary code removed)

final View m_view = inflater.inflate(R.layout.fragment_tayle, null);            
        RelativeLayout m_topLayout = (RelativeLayout) m_view.findViewById(R.id.t_layout);           
                   //Populate the View control values, eg TextViews, ImageViews here

m_view.setX(0);         
        m_view.setY(0);         
        m_view.setTag(i);           

        if (i == 0) { m_view.setRotation(0); } 
        else if (i == 1) { m_view.setRotation(-5); } 
        else if (i == 2) { m_view.setRotation(3); } 
        else if (i == 3) { m_view.setRotation(7); } 
        else if (i == 4) { m_view.setRotation(-2); } 
        else if (i == 5) { m_view.setRotation(5); }         
        parentView.addView(m_view);

Lastly, the child layout that is each "card"

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/t_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="4dip" 
    android:weightSum="2"
    android:background="@drawable/tayle_border"
    >

<ImageView 
        android:id="@+id/genre"
        android:layout_height="60dp"
        android:layout_width="50dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true" />

   ...and so on
NZJames
  • 4,963
  • 15
  • 50
  • 100
  • calculate the width and height of parent and apply those to the child – Illegal Argument Jun 27 '14 at 15:37
  • I considered using weights and LinearLayout but that only lets you set one dimension as percentage. I need each child view to be around 90% both width AND height of the parent control. Even if I need to calculate the width and height of the parent control in code and programmatically set the width and height of the child view, that would be ok - just not sure how to do that – NZJames Jun 27 '14 at 15:40
  • why dont you use switch instead of if else if ladder. Its inefficient to if else if in this case. – Illegal Argument Jun 27 '14 at 15:50
  • Thanks for the tip, will do that – NZJames Jun 27 '14 at 15:50

1 Answers1

0

For knowing the parent's width and height you can implement view tree observer. This code is a modified snippet from here:

ViewTreeObserver viewTreeObserver = relativeLayout.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
 viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
      view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
      viewWidth = relativeLayout.getWidth();
      viewHeight = relativeLayout.getHeight();
    }
  });
}

Now you have the width and height of the view in pixels. You can now scale your imageview accordingly. Here relativeLayout.getWidth() returns the pixels but calling if before or during layout-pass will return 0. Viewtreeobserver is used inorder to mitigate it.

Community
  • 1
  • 1
Illegal Argument
  • 10,090
  • 2
  • 44
  • 61
  • Ok I have the parent width and height now to use, but when I am inflating the child view, I try to get the LayoutParams for that RelativeLayout but they are null. I assume this is because the view hasn't been added to the layout manager yet? At what point can I set the child layout params? – NZJames Jun 27 '14 at 15:54
  • Hmm maybe I don't have the parent width/height. At which point in the code do I put your snipper? in the onCreateView()? does this code block/wait until the layout is rendered as I then need to create all the child views which depend on this value being set first – NZJames Jun 27 '14 at 16:03
  • @NZJames as shown above onGlobalLayout() here you can set the layout params to your child views – Illegal Argument Jun 27 '14 at 16:03
  • @NZJames you can place this code bolck in oncreateview as you can see **@Override** annotation it is called when your layout pass is finished. Its like a interface and can be called anytime. Place your layout params for imageview inside onGlobalLayout() method. – Illegal Argument Jun 27 '14 at 16:06