1

Having an issue with the following error after trying to add a slideout menu to an activity:

java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to appname.SlideOutMenu

The specific section of code it is finding fault with is this:

public class MainActivity extends Activity implements View.OnClickListener {

SlideOutMenu root;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.root = (SlideOutMenu) this.getLayoutInflater().inflate(R.layout.activity_main, null);
    this.setContentView(root);
}

Here is the relevant section of my xml file:

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 xmlns:ads="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:paddingLeft="0dp"
 android:paddingRight="0dp"
 android:id="@+id/mainActivityLayout"
 android:paddingTop="0dp"
 android:paddingBottom="0dp"
 tools:context=".MainActivity"
 android:background="#ffffff"
 android:orientation="vertical">

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/mainActivitySlideout"
    android:background="#2a80b9"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tempBtn1"
        android:onClick="toggleMenu"
        android:text="Button 1"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="toggleMenu"
        android:id="@+id/tempBtn2"
        android:text="Button 2"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tempBtn3"
        android:onClick="toggleMenu"
        android:text="Button 3"/>
</LinearLayout>

And this is my SlideOutMenu class, if required:

package rule02.touchpool;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class SlideOutMenu extends LinearLayout {
    private View menu;
    private View content;

    protected static final int menuMargin = 150;

    public enum MenuState {
        CLOSED, OPEN
    };

    protected int currentContentOffset = 0;
    protected MenuState menuCurrentState = MenuState.CLOSED;

    public SlideOutMenu(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public SlideOutMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SlideOutMenu(Context context) {
        super(context);
    }

    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        this.menu = this.getChildAt(0);
        this.content = this.getChildAt(1);
        this.menu.setVisibility(View.GONE);
    }

    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) {
        if (changed) {
            this.calculateChildDimensions();
        }
        this.menu.layout(left, top, right - menuMargin, bottom);
        this.content.layout(left + this.currentContentOffset, top, right
                + this.currentContentOffset, bottom);
    }

    public void toggleMenu() {
        switch (this.menuCurrentState) {
        case CLOSED:
            this.menu.setVisibility(View.VISIBLE);
            this.currentContentOffset = this.getMenuWidth();
            this.content.offsetLeftAndRight(currentContentOffset);
            this.menuCurrentState = MenuState.OPEN;
            break;
        case OPEN:
            this.content.offsetLeftAndRight(-currentContentOffset);
            this.currentContentOffset = 0;
            this.menuCurrentState = MenuState.CLOSED;
            this.menu.setVisibility(View.GONE);
            break;
        }
        this.invalidate();
    }

    private int getMenuWidth() {
        return this.menu.getLayoutParams().width;
    }

    private void calculateChildDimensions() {
        this.content.getLayoutParams().height = this.getHeight();
        this.content.getLayoutParams().width = this.getWidth();
        this.menu.getLayoutParams().width = this.getWidth() - menuMargin;
        this.menu.getLayoutParams().height = this.getHeight();
    }
}

If anyone can help then I will be so very happy!! :)

Edit:

Is it something to do with declaring SlideOutMenu as the root view in the xml document? If so, I am not exactly sure how to do this and cannot find any info on it.

Bisclavret
  • 1,327
  • 9
  • 37
  • 65
  • I think you can use `SlideOutMenu` instead of `LinearLayout` inside your XML layout file. – almightyGOSU Jun 07 '15 at 06:00
  • @Gosu: Thanks for the reply. I got the following error when I tried your method: android.view.InflateException: Binary XML file line #16: Error inflating class SlideOutMenu – Bisclavret Jun 07 '15 at 06:07
  • @Gosu I don't think we can use user defined layout classes as tags in layout xml file. – Aniket Thakur Jun 07 '15 at 06:25

3 Answers3

2

indirect connected post & its indirect explanation, now follows the following code

SlideOutMenu root;
View container;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
container = getLayoutInflater().inflate(R.layout.activity_main, null);
root = (SlideOutMenu) container.findViewById(R.id.mainActivitySlideout);
 this.setContentView(container);
//the following codes can follow

your xml

//the important part
<rule02.touchpool.SlideOutMenu 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainActivitySlideout"
android:background="#2a80b9"
android:orientation="vertical">

the rest is ok, remember to close it with </rule02.touchpool.SlideOutMenu>

Community
  • 1
  • 1
Elltz
  • 10,730
  • 4
  • 31
  • 59
  • 1
    This is brilliant!!! The app no longer crashes and the slideout menu works perfectly. That XML code was exactly what I was looking for! Now I just have to work out why the main activity screen is all messed up. Everything appears to be pushed down or missing. – Bisclavret Jun 07 '15 at 08:51
  • :) yes Sir, you brought the best out of me :), okay, do you want help on that too? so i can see if i can help, messed up how? they are not aligned relatively?@Bisclavret but for starters you need to re-check why you need match_parent on your slideout menu because it will take all the space and leave the rest missing, orphans – Elltz Jun 07 '15 at 09:37
  • Thanks for replying, Elltz. I think the issue is because my activity used to use a relative layout, and now it is converted to a linear layout. I don't know if I need to use linear for my slide out menu to work or not. I am trying to learn how to use linear layouts but they just suck ;) It is using match parent because of this line of code in SlideOutMenu.java: protected final int menuMargin = Math.round(150 * SCALE); The menu size is the size of the screen minus the number specified. This number is also the amount that the activity will slide to the left and to the right. – Bisclavret Jun 07 '15 at 10:30
  • Fixed! Just converted my original section of layout back to relative, within the overall layout and everything is working perfectly. Thanks again mate :) – Bisclavret Jun 07 '15 at 10:36
  • HURRAYY!!!.. okay Sir, but initially i was thinking that you should set the visibility of the menu layout to gone so it does not take screen space unless it is requested for, but since you've solved it there is no need for that@Bisclavret happy codding – Elltz Jun 07 '15 at 13:59
0

I think root is your layout xml file. Therefore code should be, for fixing compile error:

this.root = (LinearLayout) this.getLayoutInflater().inflate(R.layout.activity_main, null);

Standard suggested code is:

setContentView(R.layout.activity_main);

Note: I prefer the standard code.

The Original Android
  • 6,147
  • 3
  • 26
  • 31
  • 2
    @Original Android: Hi mate, thanks for your reply. I normally use the standard code, as you have shown above. This, however, is a bit different. What we are doing is setting a layout underneath the main layout and setting it as the root layout. So basically the slideout menu exists underneath the main activity. When you call for the menu, it moves the activity over to the right, and slides the slideout menu over from the right and makes it visible. When you close the menu, it slides the menu back over to the left and sets it to GONE, and slides the activity back where it came from. – Bisclavret Jun 07 '15 at 06:17
  • @Bisclavret, Thanks for the interesting explanation. Perhaps the answer by Aniket would work. – The Original Android Jun 07 '15 at 06:28
  • @Bisclavret, Your explanation of the slideout menu sounds like Navigation Drawer to me. – The Original Android Jun 07 '15 at 06:36
  • @Original Android: Thanks again for the replies. If you need further explanation, I am following this example almost exactly: https://www.youtube.com/watch?v=YeR7McJIltk I just can't work out what he means when he says he set the root to the SlideOutMenu in his xml file. – Bisclavret Jun 07 '15 at 08:37
0

You can either use an XML or a class to create UI. How are you using both and trying to convert one to another? It will never work. Either instantiate you layout java class and set it in content view or inflate your xml and set it.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(this.getLayoutInflater().inflate(R.layout.activity_main, null));
}

or you can do

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LinearLayout som = new SlideOutMenu(this);
    this.setContentView(som );
}
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • This does not work either. What I end up with is my activity covered by the SlideOutMenu, so you cannot see the activity at all, and then it crashes when you try to slide it back. I followed this guide exactly: https://www.youtube.com/watch?v=YeR7McJIltk and in this clip he is saying you have to set SlideOutMenu to be the root of the activity.... but it isn't working. It HAS to be done this way for it to work, you cannot skip around it by ignoring this part of the code. – Bisclavret Jun 07 '15 at 08:35
  • If you see near the end of the video above, he sets the root as SlideOutMenu in code, but he also does it in the xml document, and I can't work out how he has done that. Maybe this is why it's not working for me? – Bisclavret Jun 07 '15 at 08:35