tags:

views:

93

answers:

2

My issue is that I have a main screen, and I would like to dynamically spawn a view under it with a button click, then slide the main view off the screen revealing the view below it. I've accomplished this, but I feel like there's got to be a better way. The way I've done it is very limited in that you can't just spawn views over and over again under the main.

My main XML file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
  <RelativeLayout
    android:id="@+id/subpage"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  </RelativeLayout>
  <RelativeLayout
    android:id="@+id/homescreen"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/homebg"
        >
    </RelativeLayout>
  </RelativeLayout>
</RelativeLayout>

I've deleted some unnecessary stuff. This is what's important. Notice the first child of the main layout is a relative layout with the id "subpage." As it is I use java to inflate another layout into the subpage layout when a button is clicked then I animate the "homescreen" layout off the screen. It seems like I shouldn't have to have the subpage declared in advance though. I guess my question is, is there a way to dynamically declare a new child layout underneath an existing layout?

=======================================================================

Edit: Part 2 of question

I'm trying to use addView and the app crashes. This is the code I use to try to add a view and inflate my xml into it. In the code below subview is a ViewGroup because as I understand it you can only inflate into ViewGroups, not regular views. Also 'activity' is defined at the top of the class as 'private Activity activity = this'. Any ideas what could be causing the crash?

btnHelp.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            subView = (ViewGroup)new View(getApplicationContext());
            mainScreen.addView(subView,1);
            LayoutInflater inflater = activity.getLayoutInflater();
            inflater.inflate(R.layout.help, subView);
        }
    });

=======================================================================

Edit: Part 3 of question

So one more issue. Everything works great as far as inflating and sliding off. However, the view that is inflated has a button in it. I'm trying to assign a listener to that button, but it doesn't seem to work. I'm doing it by adding the listener to the button after the layout inflater is called in the btnHelp I've been working on. Here's the code:

btnHelp.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            LayoutInflater inflater = activity.getLayoutInflater();
            mainScreen.addView(inflater.inflate(R.layout.help, null),0);
            homeScrn.startAnimation(slideLeftOut);
            btnBackHome = (ImageView)findViewById(R.id.backMenuBtn);
            btnBackHome.setOnClickListener(goHome);

        }
    });

goHome is a handler I've defined below this as such:

private OnClickListener goHome = new OnClickListener(){
    public void onClick(View v) {
        Log.d("ClickEvent: ","btnBackHome Clicked");
        homeScrn.startAnimation(slideRightIn);
    }
};

When I click the button referenced by btnBackHome it doesn't do anything. I'm just not sure if it's because the listener isn't actually being assigned, something is keeping the button from actually being clicked, or something else.

+1  A: 

Call addView() on the RelativeLayout to add children to it, where the children are either inflated (getLayoutInflater().inflate()) or constructed directly in Java.

Also, you might consider using a ViewFlipper, considering that it does what you're seeking (animated transition from child to child, with only one child visible at a time in the steady state), perhaps with less code.

CommonsWare
I'll give that a try. The ViewFlipper isn't quite what I want. It has one view slide off while another slides on simultaneously. I'm looking to have one View slide off from over top of the second view doing a reveal basically.
LoneWolfPR
@LoneWolfPR: Ah, sorry, my mistake on the `ViewFlipper` suggestion.
CommonsWare
I'm trying the add view, but it's giving me problems. Could you check out the edit I made to my original post and see if there's anything you can see wrong with it? Thanks.
LoneWolfPR
@LoneWolfPR: First, do not use `getApplicationContext()`, use `this`. Second, `View` is not a `ViewGroup`, so your cast will fail. Third, you cannot add children to a `View`, so your `inflate()` will fail. Call `inflater.inflate(R.layout.help, null)`, and then add that to your `RelativeLayout`. In your case, if R.layout.help is supposed to appear beneath the current contents, it needs to be your first child, so you would use `addView(inflater.inflate(R.layout.help, null), 0)`.
CommonsWare
Terrific! That worked beautifully. Thanks a lot!
LoneWolfPR
@CommonsWare: I've got one more issue that has cropped up in this. I just left it here has a 3rd edit instead of starting a new question because they're all closely related. Could you check the 3rd edit and offer any advice? Thanks a lot. You've been a tremendous help!
LoneWolfPR
@LoneWolfPR: It is difficult to advise you here. Use `hierarchyviewer` to figure out where your button is to see if it is behind something, or see if the button click animation (orange flash) occurs. Also, always call `findViewById()` on the tightest scope you have handy, so if the `Button` you seek is in the layout you just inflated, call `findViewById()` on the results of the `inflate()` call (you'd need to store this in a local variable so you could also pass it to `addView()`).
CommonsWare
@CommonsWare: Thanks. I checked the hierarchyviewer. It appears that the first screen never actually goes away. When it animates off the screen I set its visibility to View.GONE in the onAnimationEnd of the animation listener, but the wireframe layout in the viewer shows that it's still there sitting on top of the help screen. Is there something I need to do to remove it from on top of my new view?
LoneWolfPR
@LoneWolfPR: call `removeView()`, if needed. But if the button animation occurs (orange flash on click), that's not your problem.
CommonsWare
@CommonsWare: Thanks so much! You have been a tremendous help. removeView() is actually what I needed. I've totally streamlined it now. There is a main layout with the homescreen listed in an include. When you click the help button it inflates the help, slides off the home off the screen and removes it. Then when they click back home it inflates the homescreen (invisible) over the help. Then it animates it onto the screen and removes the help. Then it reactivates all the buttons. That way there's never an unused view active. Thanks again!
LoneWolfPR
A: 

The default animation when starting a new Activity is a sliding animation.. why not just separate your "homescreen" and "subpage" into 2 different XML files and 2 Activities?

Snailer
It's not the right kind of slide, and transitions between activities are difficult to control. Also, it's just a single screen. No real need for an activity for it.
LoneWolfPR